# [Numpy-discussion] Simple multi-arg wrapper for dot()

Bill Baxter wbaxter@gmail....
Fri Mar 23 23:09:50 CDT 2007

```I mentioned in another thread Travis started on the scipy list that I
would find it useful if there were a function like dot() that could
multiply more than just two things.

Here's a sample implementation called 'mdot'.

mdot(a,b,c,d) ==> dot(dot(dot(a,b),c),d)
mdot(a,(b,c),d) ==> dot(dot(a,dot(b,c),d)
mdot(a,(b,(c,d))) ==> dot(a,dot(b,dot(c,d))

---
def mdot(*args):
"""Multiply all the arguments using matrix product rules.
The output is equivalent to multiplying the arguments one by one
from left to right using dot().
Precedence can be controlled by creating tuples of arguments,
for instance mdot(a,((b,c),d)) multiplies a (a*((b*c)*d)).
Note that this means the output of dot(a,b) and mdot(a,b) will differ if
a or b is a pure tuple of numbers.
"""
if len(args)==1:
return args[0]
elif len(args)==2:
return _mdot_r(args[0],args[1])
else:
return _mdot_r(args[:-1],args[-1])

def _mdot_r(a,b):
"""Recursive helper for mdot"""
if type(a)==types.TupleType:
if len(a)>1:
a = mdot(*a)
else:
a = a[0]
if type(b)==types.TupleType:
if len(b)>1:
b = mdot(*b)
else:
b = b[0]
return numpy.dot(a,b)
---

It does about twice as many function calls as just using dot which I'm
guessing is mostly why its a good bit slower than just doing the
nested dot calls.  Maybe one of you smart folks can figure out a way
to bring it closer to dot's speed.

--bb
```