473,383 Members | 1,919 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

dot products

HI.
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above. (By
the way profiling them i found that the second is faster by about 30%.)
rahul

Jul 18 '05 #1
12 8101
Rahul wrote:
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))


btw, imho the most "Pythonic" would be:

sum(i*j for (i,j) in zip(a,b))
Jul 18 '05 #2
Rahul wrote:
HI.
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above.
Try:

sum(x * y for x, y in zip(a, b))

Between zip() (lockstep iteration over several sequences) and enumerate()
(iteration over a sequence, but also providing an index counter), it is rare
that you will want to use indexing notation in a generator expression.
(By the way profiling them i found that the second is faster by about 30%.)


For short sequences, generator expressions may end up slightly slower than list
comprehensions or for loops, as the latter two do not involve the overhead of
setting up the generator and retrieving values from it. As the sequences
increase in length, generator expressions generally win in the end due to their
reduced memory impact.

Cheers,
Nick.

--
Nick Coghlan | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #3
Rahul wrote:
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above. (By
the way profiling them i found that the second is faster by about 30%.)


You could try

sigma = 0
for ai, bi in itertools.izip(a, b):
sigma += ai * bi

or

sum(itertools.starmap(operator.mul, itertools.izip(a, b)))

but if you are really concerned about number-crunching efficiency, use
Numarray.

Peter

Jul 18 '05 #4
Rahul wrote:
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.


.. >>> import numarray as na
.. >>> a, b = na.arange(5), na.arange(5, 10)
.. >>> na.dot(a, b)
.. 80

Steve
Jul 18 '05 #5
[Rahul].
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above.


Yes:
from itertools import imap
from operator import mul
ans = sum(imap(mul, a, b))

In general:
* reduction functions like sum() do not need their arguments to
take time building a full list; instead, an iterator will do fine
* applying itertools instead of genexps can save the eval-loop overhead
* however, genexps are usually more readable than itertools solutions
* xrange() typically beats range()
* but indexing is rarely the way to go
* izip() typically beats zip()
* imap() can preclude the need for either izip() or zip()
* the timeit module settles these questions quickly

Here are the some timings for vectors of length 10 and 3 respectively

C:\pydev>python timedot.py 3
1.25333310984 sum(a[i]*b[i] for i in xrange(len(a)))
1.16825625639 sum(x*y for x,y in izip(a,b))
1.45373455807 sum(x*y for x,y in zip(a,b))
0.635497577901 sum(imap(mul, a, b))
0.85894416601 sum(map(mul, a, b))

C:\pydev>python timedot.py 10
2.19490353509 sum(a[i]*b[i] for i in xrange(len(a)))
2.01773998894 sum(x*y for x,y in izip(a,b))
2.44932533231 sum(x*y for x,y in zip(a,b))
1.24698871922 sum(imap(mul, a, b))
1.49768685362 sum(map(mul, a, b))

Raymond Hettinger
Jul 18 '05 #6
Raymond Hettinger wrote:
* applying itertools instead of genexps can save the eval-loop overhead
* however, genexps are usually more readable than itertools solutions


I'm still waiting for you to implement itertools as a parse-tree analyzer/code generator,
rather than an "bare" extension module.

</F>

Jul 18 '05 #7

Raymond Hettinger wrote:
[Rahul].
I want to compute dot product of two vectors stored as lists a and b.a and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above.
Yes:
from itertools import imap
from operator import mul
ans = sum(imap(mul, a, b))

In general:
* reduction functions like sum() do not need their arguments to
take time building a full list; instead, an iterator will do fine
* applying itertools instead of genexps can save the eval-loop

overhead * however, genexps are usually more readable than itertools solutions
* xrange() typically beats range()
* but indexing is rarely the way to go
* izip() typically beats zip()
* imap() can preclude the need for either izip() or zip()
* the timeit module settles these questions quickly

Here are the some timings for vectors of length 10 and 3 respectively

C:\pydev>python timedot.py 3
1.25333310984 sum(a[i]*b[i] for i in xrange(len(a)))
1.16825625639 sum(x*y for x,y in izip(a,b))
1.45373455807 sum(x*y for x,y in zip(a,b))
0.635497577901 sum(imap(mul, a, b))
0.85894416601 sum(map(mul, a, b))

C:\pydev>python timedot.py 10
2.19490353509 sum(a[i]*b[i] for i in xrange(len(a)))
2.01773998894 sum(x*y for x,y in izip(a,b))
2.44932533231 sum(x*y for x,y in zip(a,b))
1.24698871922 sum(imap(mul, a, b))
1.49768685362 sum(map(mul, a, b))

Raymond Hettinger

Thanks all of you guys for enlightening me. Python is truly elegant.

Jul 18 '05 #8
On 19 Dec 2004 03:04:15 -0800, "Rahul" <co********@gmail.com> wrote:
HI.
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above. (By
the way profiling them i found that the second is faster by about 30%.)
rahul

Don't know about the timing, but another way:
import operator
a, b = range(5), range(5,10)
sum(map(operator.mul, a, b)) 80

Checking...
class OpShow(object): ... def __init__(self): self.tot = 0
... def __call__(self, x, y):
... prod = x*y
... self.tot += prod
... print '%3s * %-3s => %s (tot %s)' %(x, y, prod, self.tot)
... return prod
... sum(map(OpShow(), a, b))

0 * 5 => 0 (tot 0)
1 * 6 => 6 (tot 6)
2 * 7 => 14 (tot 20)
3 * 8 => 24 (tot 44)
4 * 9 => 36 (tot 80)
80

Regards,
Bengt Richter
Jul 18 '05 #9
On Sun, Dec 19, 2004 at 03:04:15AM -0800, Rahul wrote:
HI.
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above. (By
the way profiling them i found that the second is faster by about 30%.)
rahul


some numbers to confirm my previous reply:

1
zip: 0.00115 (1.00)
range: 0.00108 (0.94)
array: 0.00075 (0.65)
10
zip: 0.00306 (1.00)
range: 0.00288 (0.94)
array: 0.00074 (0.24)
100
zip: 0.02195 (1.00)
range: 0.02035 (0.93)
array: 0.00079 (0.04)
1000
zip: 0.21016 (1.00)
range: 0.19930 (0.95)
array: 0.00130 (0.01)
10000
zip: 4.98902 (1.00)
range: 2.70843 (0.54)
array: 0.01405 (0.00)

(the integers are the number of elements in a random array of floats;
'zip' refers to

sum([x*y for (x,y) in zip(a,b)])

'range', to

sum([a[i]*b[i] for i in range(len(a))])

and 'array' makes a and b Numeric's 'array' objects, with atlas
installed (and hence dotblas loading and assembler version of dot
tuned for the system's processor (in this case a pentium3)). The code
in this case is simply

Numeric.dot(a, b)

The advantage of atlas on systems with sse2 should be even greater.

--
John Lenton (jo**@grulic.org.ar) -- Random fortune:
El deseo nos fuerza a amar lo que nos hará sufrir.
-- Marcel Proust. (1871-1922) Escritor francés.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFBxv1BgPqu395ykGsRAvuKAJkBULU763LN368mVFJf+t rqku8/KQCbB75C
noYAuTFkRh4SJ3VmJCXpwZY=
=F9aS
-----END PGP SIGNATURE-----

Jul 18 '05 #10
[Rahul].
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length.

one simple way is
sum(a[i]*b[i] for i in range(len(a)))

another simple way is
ans=0.0
for i in range(len(a)):
ans=ans+a[i]*b[i]

But is there any other way which is faster than any of the above.


Yes:
from itertools import imap
from operator import mul
ans = sum(imap(mul, a, b))


Doh! We all missed it.

If your vector length is known in advance (and it often is in some apps), the
simplest and fastest approach is:

a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
C:\pydev>python timedot.py 3
0.32 sec: a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
1.38 sec: sum(a[i]*b[i] for i in xrange(len(a)))
1.32 sec: sum(x*y for x,y in izip(a,b))
1.62 sec: sum(x*y for x,y in zip(a,b))
0.75 sec: sum(imap(mul, a, b))
1.04 sec: sum(map(mul, a, b))

Raymond Hettinger
Jul 18 '05 #11
[Rahul].
I want to compute dot product of two vectors stored as lists a and b.a
and b are of the same length


from scipy import dot
ans=dot(a,b)

This times faster than the alternatives I have seen mentioned so far,
given scipy.

Cheers,
Alan Isaac
Jul 18 '05 #12
"Alan G Isaac" <ai****@american.edu> wrote in message
news:10*************@corp.supernews.com...
This times faster than the alternatives I have seen mentioned so far,
given scipy.


Actually, since I am new to 'timeit', I probably should check that
I am not overlooking something. Especially since I see an order
of magnitude difference in performance. Does the code below
give the right comparisons?

Thanks,
Alan Isaac

#-------------------------------------------------------------
import timeit
env1='''
from operator import mul
from itertools import imap
def innerprod(x,y):
return sum(imap(mul,x,y))
from scipy import rand
x=rand(50); y=rand(50)
'''
env2='''
from operator import mul
from itertools import imap
from scipy import rand
x=rand(50); y=rand(50)
'''
env3='''
from scipy import rand,dot
x=rand(50); y=rand(50)
'''
t1=timeit.Timer("innerprod(x,y)",env1)
t2=timeit.Timer("sum(imap(mul,x,y))",env2)
t3=timeit.Timer("dot(x,y)",env3)
trials=1000
print t1.repeat(2,trials) #about 0.1 seconds
print t2.repeat(2,trials) #about 0.1 seconds
print t3.repeat(2,trials) #about 0.01 seconds

Jul 18 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: frizzle | last post by:
Hi there I have a products site with a mysql backend. I have two tables: 1 with series, 1 with products belonging to certain series. Series looks like: - id - kind
0
by: Ralph Guzman | last post by:
TASK: I have to generate a report with all categories, subcategories and products in database. PROBLEM: I want to write one query that will return: 1. category 2. subcategory: determined by...
2
by: Hohn Upshew | last post by:
I need some help to build a report enumerating the products in descending order depending on the sum of liters. In this way i can view the top products sold for a given period.But i fail to do...
1
by: Mark | last post by:
My Category and Product tables look like: TblCategory CategoryID Category TblProduct ProductID CategoryID Product
6
by: Paul T. Rong | last post by:
Dear all, Here is my problem: There is a table "products" in my access database, since some of the products are out of date and stopped manufacture, I would like to delete those PRODUCTS from...
2
by: TD | last post by:
I have this expression in the criteria section of a query: IIf(Forms!frmReports!cboProductID="<ALL PRODUCTS>",. Like "*",Forms!frmReports!cboProductID) (the syntax of the above expression may...
24
by: Rob R. Ainscough | last post by:
I was reading yet another book on .NET - VB 2005 Professional (wrox) and read the statement; "Microsoft has staked their future on .NET and publicly stated that henceforth almost all their...
9
by: Earl | last post by:
I have somewhat of an interesting scenario: The form allows the user to select a service, which populates a a grid of product information related to that service ("service grid"). The user can...
0
by: shapper | last post by:
Hello, I am displaying a list of products. I created a model using Linq To SQL. The List method is as follows: public void List(int? page) { dt.Products = (from p in db.Products orderby...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.