I'm trying to create a function that does the cross product between two lists of the same dimensions, element by element. Each entry of the list is a 3D vector. Something like this:
a = {{a1, a2, a3}, {b1, b2, b3}};
b = {{c1, c2, c3}, {d1, d2, d3}};
listCross[a, b] = {Cross[{a1, a2, a3}, {c1, c2, c3}], Cross[{b1, b2, b3}, {d1, d2, d3}]};
All my lists have 3 dimensions, so something like Dimensions[a] = {32, 32, 32, 3}
would be typical, and I have the following code that works:
listCross[list1_, list2_] := Module[{vec11, vec12, vec13, result},
vec11 = -list1[[All, All, All, 3]]list2[[All, All, All, 2]] + list1[[All, All, All, 2]]list2[[All, All, All, 3]];
vec12 = +list1[[All, All, All, 3]]list2[[All, All, All, 1]] - list1[[All, All, All, 1]]list2[[All, All, All, 3]];
vec13 = -list1[[All, All, All, 2]]list2[[All, All, All, 1]] + list1[[All, All, All, 1]]list2[[All, All, All, 2]];
result = Partition[Partition[MapThread[{#1, #2, #3}&, {Flatten[vec11], Flatten[vec12], Flatten[vec13]}], Dimensions[list1][[3]]], Dimensions[list1][[2]]]
];
It exploits the result of Cross[{a1, a2, a3}, {b1, b2, b3}]
and generalizes to lists with list sums. In the end it uses Partition
and MapThread
to join the x, y and z components into a new list with the same dimensions as the input lists.
However this is not as fast as I would like it to be, and I haven't been able to come up with anything better. I also tried doing the cross product in it's matrix-vector product form, creating a block diagonal sparse matrix from the first list that I would multiply with the Flatten
of the second list, but I couldn't create the matrix fast enough.
Does anyone have any thoughts on this? I also know nothing about Compile
, so no idea if it would be of use here. Any help will be greatly appreciated.
MapThread[Cross, {{{a1, a2, a3}, {b1, b2, b3}}, {{c1, c2, c3}, {d1, d2, d3}}}]
? $\endgroup$MapThread[Cross, {list1, list2}, 3]
. But, hm, it's actually slower! $\endgroup$