performance tuning - Optimizing a simple calculus using a list of matrices - Repeated dot product between a vector and a list of matrices
I want to make the following operation :
$$ \begin{bmatrix} \dot q_1\\\dot q_2 \end{bmatrix} + \begin{bmatrix} \begin{bmatrix} q_1 & q_2 \end{bmatrix} \mathbf A_1 \begin{bmatrix} q_1\\ q_2 \end{bmatrix} \\ \begin{bmatrix} q_1 & q_2 \end{bmatrix} \mathbf A_2 \begin{bmatrix} q_1\\ q_2 \end{bmatrix} \end{bmatrix} = \begin{bmatrix} \dot q_1\\\dot q_2 \end{bmatrix} + \begin{bmatrix} \begin{bmatrix} q_1 & q_2 \end{bmatrix} \begin{bmatrix} 0&1\\ 1&1 \end{bmatrix} \begin{bmatrix} q_1\\ q_2 \end{bmatrix} \\ \begin{bmatrix} q_1 & q_2 \end{bmatrix} \begin{bmatrix} -1&0\\ 0&0 \end{bmatrix} \begin{bmatrix} q_1\\ q_2 \end{bmatrix} \end{bmatrix} = \begin{bmatrix} \dot q_1\\\dot q_2 \end{bmatrix} + \begin{bmatrix} {q_1}^2 + q_2(q_1+q_2)\\ -{q_1}^2 \end{bmatrix}$$
I also want to put the two $\mathbf A_1$ and $\mathbf A_2$ matrices inside a list of matrices A
in mathematica.
So I started creating my list of matrices A
and did the following :
A={{{0, 1}, {1, 1}},{{-1, 0}, {0, 0}}};
res={{q1, q2}.A[[1]].{q1, q2},{q1, q2}.A[[2]].{q1, q2}};
final={q1p,q2p}+res;
Now, my question : is there a way to optimize the calculation of res
? The goal is to avoid calling A[[1]]
and A[[2]]
independently each time. The perspective is to extend the A
list to a list of dimension $n \gt 2$ (something like this) :
$$ \begin{bmatrix} \dot q_1\\\dot q_2 \\ \vdots \\ \dot q_n \end{bmatrix} + \begin{bmatrix} \begin{bmatrix} q_1 & q_2 & \cdots & q_n\end{bmatrix} \mathbf A_1 \begin{bmatrix} q_1\\ q_2 \\ \vdots \\ \dot q_n \end{bmatrix} \\ \begin{bmatrix} q_1 & q_2 & \cdots & q_n \end{bmatrix} \mathbf A_2 \begin{bmatrix} q_1\\ q_2 \\ \vdots \\ \dot q_n \end{bmatrix} \\ \vdots \\ \begin{bmatrix} q_1 & q_2 & \cdots & q_n \end{bmatrix} \mathbf A_n \begin{bmatrix} q_1\\ q_2 \\ \vdots \\ q_n \end{bmatrix} \end{bmatrix}$$
Answer
Ok, so, thanks to Spawn1701D's comment here's the simplest way to proceed :
A={{{0, 1}, {1, 1}},{{-1, 0}, {0, 0}}};
res={q1,q2}.#.{q1,q2}&/@A;
final={q1p,q2p}+res;
To state it simple, Spawn1701D prescribes the usage of pure functions to make it extremely terse :
#
function creates a slot between the two versions of the $\mathbf q$ vector/@
is a shorthand of theMap
function
Basically what this code does is : map the Dot
operations to every element on the A
list (which in this particular case is a list of matrices).
UPDATE
Another way to proceed (the simplest one in fact, thanks Michael E2) is to simply use the Dot
product twice between the list A
and vector q
q={q1,q2}
A={{{0, 1}, {1, 1}},{{-1, 0}, {0, 0}}};
res=A.q.q
Comments
Post a Comment