So I put together a prototype for an extended dot function that takes
multiple arguments. This allows multiple dots to be computed in a single
call thusly:
dot(dot(dot(a, b), c), d) => dotn(a, b, c, d)
On Bill Baxter's suggestion, dotn attempts to do the dots in an order
that minimizes operations. That appears to work fine, although I wasn't
very careful and I wouldn't be at all surprised if some problems crop up
with that part.
The interesting thing is that, since dot can perform both matrix and dot
products, it's not associative. That is, dot(a, dot(b, c) != dot(dot(a,
b), c) in general. The simplest examples is three vectors.
>>> dot(dot([1,2,3], [3,2,1]), [1,1,1])
array([10, 10, 10])
>>> dot([1,2,3], dot([3,2,1], [1,1,1]))
array([ 6, 12, 18])
That's mind numbingly obvious in retrospect, but means that my simple
minded dot product optimizer is all wrong because it can change the
order of evaluation in such a way that the result changes. That means
two things:
1. I need to pick an effective order of evaluation. So, dotn(a, b, c
...) will be evaluated as if the products were evaluated in left to
right order.
2. The optimizer needs to respect that order when rearranging the order
in which the products are performed. Dot products must remain dot
products and matrix products must remain matrix products under any
transformations that take place.
Anyway, that's that for now. I'll report back when I get it fixed up.
-tim
|