Skip to main content
replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
Source Link

Interestingly enough, MapThreading Cross works but is much slower:

Using sample lists:

list1 = Array[c, {20, 20, 20, 3}]; list2 = Array[d, {20, 20, 20, 3}]; 

We can perform this operation in the following two ways, using MapThread:

listCrossMarch1[list1_, list2_] := MapThread[Cross, {list1, list2}, 3] listCrossMarch2[list1_, list2_] := MapThread[{#1[[2]] #2[[3]] - #1[[3]] #2[[2]], #1[[3]] #2[[1]] - #1[[1]] #2[[3]], #1[[1]] #2[[2]] - #1[[2]] #2[[1]]} &, {list1, list2}, 3] 

As we can see below, there is a lot of overhead associated with Cross apparently, since that version is much slower than coding the cross-product explicitly. The MapThread version with the explicit cross-product (rather than Cross) is almost as fast as the OP's version and much cleaner to write down. Simon WoodsSimon Woods' answeranswer is the fastest (and also very clean).

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First l1 === l2 === l3 === l4 (* 1.436369 *) (* 0.190366 *) (* 0.120962 *) (* 0.084740 *) (* True *) 

As suggested by Simon Woods, here are Timings with packed arrays of real numbers. Using

list1 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; list2 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; 

we do

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First (* 0.429275 *) (* 0.094540 *) (* 0.008337 *) (* 0.028592 *) 

The OP's messy version is significantly the fastest here! Simon Woods' answer still does a great job, and Cross still has lots of overhead.

Interestingly enough, MapThreading Cross works but is much slower:

Using sample lists:

list1 = Array[c, {20, 20, 20, 3}]; list2 = Array[d, {20, 20, 20, 3}]; 

We can perform this operation in the following two ways, using MapThread:

listCrossMarch1[list1_, list2_] := MapThread[Cross, {list1, list2}, 3] listCrossMarch2[list1_, list2_] := MapThread[{#1[[2]] #2[[3]] - #1[[3]] #2[[2]], #1[[3]] #2[[1]] - #1[[1]] #2[[3]], #1[[1]] #2[[2]] - #1[[2]] #2[[1]]} &, {list1, list2}, 3] 

As we can see below, there is a lot of overhead associated with Cross apparently, since that version is much slower than coding the cross-product explicitly. The MapThread version with the explicit cross-product (rather than Cross) is almost as fast as the OP's version and much cleaner to write down. Simon Woods' answer is the fastest (and also very clean).

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First l1 === l2 === l3 === l4 (* 1.436369 *) (* 0.190366 *) (* 0.120962 *) (* 0.084740 *) (* True *) 

As suggested by Simon Woods, here are Timings with packed arrays of real numbers. Using

list1 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; list2 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; 

we do

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First (* 0.429275 *) (* 0.094540 *) (* 0.008337 *) (* 0.028592 *) 

The OP's messy version is significantly the fastest here! Simon Woods' answer still does a great job, and Cross still has lots of overhead.

Interestingly enough, MapThreading Cross works but is much slower:

Using sample lists:

list1 = Array[c, {20, 20, 20, 3}]; list2 = Array[d, {20, 20, 20, 3}]; 

We can perform this operation in the following two ways, using MapThread:

listCrossMarch1[list1_, list2_] := MapThread[Cross, {list1, list2}, 3] listCrossMarch2[list1_, list2_] := MapThread[{#1[[2]] #2[[3]] - #1[[3]] #2[[2]], #1[[3]] #2[[1]] - #1[[1]] #2[[3]], #1[[1]] #2[[2]] - #1[[2]] #2[[1]]} &, {list1, list2}, 3] 

As we can see below, there is a lot of overhead associated with Cross apparently, since that version is much slower than coding the cross-product explicitly. The MapThread version with the explicit cross-product (rather than Cross) is almost as fast as the OP's version and much cleaner to write down. Simon Woods' answer is the fastest (and also very clean).

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First l1 === l2 === l3 === l4 (* 1.436369 *) (* 0.190366 *) (* 0.120962 *) (* 0.084740 *) (* True *) 

As suggested by Simon Woods, here are Timings with packed arrays of real numbers. Using

list1 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; list2 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; 

we do

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First (* 0.429275 *) (* 0.094540 *) (* 0.008337 *) (* 0.028592 *) 

The OP's messy version is significantly the fastest here! Simon Woods' answer still does a great job, and Cross still has lots of overhead.

added 696 characters in body
Source Link
march
  • 24.9k
  • 2
  • 48
  • 108

Interestingly enough, MapThreading Cross works but is much slower:

Using sample lists:

list1 = Array[c, {20, 20, 20, 3}]; list2 = Array[d, {20, 20, 20, 3}]; 

We can perform this operation in the following two ways, using MapThread:

listCrossMarch1[list1_, list2_] := MapThread[Cross, {list1, list2}, 3] listCrossMarch2[list1_, list2_] := MapThread[{#1[[2]] #2[[3]] - #1[[3]] #2[[2]], #1[[3]] #2[[1]] - #1[[1]] #2[[3]], #1[[1]] #2[[2]] - #1[[2]] #2[[1]]} &, {list1, list2}, 3] 

As we can see below, there is a lot of overhead associated with Cross apparently, since that version is much slower than coding the cross-product explicitly. The MapThread version with the explicit cross-product (rather than Cross) is almost as fast as the OP's version and much cleaner to write down. Simon Woods' answer is the fastest (and also very clean).

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First l1 === l2 === l3 === l4 (* 1.436369 *) (* 0.190366 *) (* 0.120962 *) (* 0.084740 *) (* True *) 

As suggested by Simon Woods, here are Timings with packed arrays of real numbers. Using

list1 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; list2 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; 

we do

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First (* 0.429275 *) (* 0.094540 *) (* 0.008337 *) (* 0.028592 *) 

The OP's messy version is significantly the fastest here! Simon Woods' answer still does a great job, and Cross still has lots of overhead.

Interestingly enough, MapThreading Cross works but is much slower:

Using sample lists:

list1 = Array[c, {20, 20, 20, 3}]; list2 = Array[d, {20, 20, 20, 3}]; 

We can perform this operation in the following two ways, using MapThread:

listCrossMarch1[list1_, list2_] := MapThread[Cross, {list1, list2}, 3] listCrossMarch2[list1_, list2_] := MapThread[{#1[[2]] #2[[3]] - #1[[3]] #2[[2]], #1[[3]] #2[[1]] - #1[[1]] #2[[3]], #1[[1]] #2[[2]] - #1[[2]] #2[[1]]} &, {list1, list2}, 3] 

As we can see below, there is a lot of overhead associated with Cross apparently, since that version is much slower than coding the cross-product explicitly. The MapThread version with the explicit cross-product (rather than Cross) is almost as fast as the OP's version and much cleaner to write down. Simon Woods' answer is the fastest (and also very clean).

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First l1 === l2 === l3 === l4 (* 1.436369 *) (* 0.190366 *) (* 0.120962 *) (* 0.084740 *) (* True *) 

Interestingly enough, MapThreading Cross works but is much slower:

Using sample lists:

list1 = Array[c, {20, 20, 20, 3}]; list2 = Array[d, {20, 20, 20, 3}]; 

We can perform this operation in the following two ways, using MapThread:

listCrossMarch1[list1_, list2_] := MapThread[Cross, {list1, list2}, 3] listCrossMarch2[list1_, list2_] := MapThread[{#1[[2]] #2[[3]] - #1[[3]] #2[[2]], #1[[3]] #2[[1]] - #1[[1]] #2[[3]], #1[[1]] #2[[2]] - #1[[2]] #2[[1]]} &, {list1, list2}, 3] 

As we can see below, there is a lot of overhead associated with Cross apparently, since that version is much slower than coding the cross-product explicitly. The MapThread version with the explicit cross-product (rather than Cross) is almost as fast as the OP's version and much cleaner to write down. Simon Woods' answer is the fastest (and also very clean).

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First l1 === l2 === l3 === l4 (* 1.436369 *) (* 0.190366 *) (* 0.120962 *) (* 0.084740 *) (* True *) 

As suggested by Simon Woods, here are Timings with packed arrays of real numbers. Using

list1 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; list2 = RandomReal[{-1, 1}, {20, 20, 20, 3}]; 

we do

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First (* 0.429275 *) (* 0.094540 *) (* 0.008337 *) (* 0.028592 *) 

The OP's messy version is significantly the fastest here! Simon Woods' answer still does a great job, and Cross still has lots of overhead.

Source Link
march
  • 24.9k
  • 2
  • 48
  • 108

Interestingly enough, MapThreading Cross works but is much slower:

Using sample lists:

list1 = Array[c, {20, 20, 20, 3}]; list2 = Array[d, {20, 20, 20, 3}]; 

We can perform this operation in the following two ways, using MapThread:

listCrossMarch1[list1_, list2_] := MapThread[Cross, {list1, list2}, 3] listCrossMarch2[list1_, list2_] := MapThread[{#1[[2]] #2[[3]] - #1[[3]] #2[[2]], #1[[3]] #2[[1]] - #1[[1]] #2[[3]], #1[[1]] #2[[2]] - #1[[2]] #2[[1]]} &, {list1, list2}, 3] 

As we can see below, there is a lot of overhead associated with Cross apparently, since that version is much slower than coding the cross-product explicitly. The MapThread version with the explicit cross-product (rather than Cross) is almost as fast as the OP's version and much cleaner to write down. Simon Woods' answer is the fastest (and also very clean).

l1 = listCrossMarch1[list1, list2]; // AbsoluteTiming // First l2 = listCrossMarch2[list1, list2]; // AbsoluteTiming // First l3 = listCross[list1, list2]; // AbsoluteTiming // First l4 = furious[list1, list2]; // AbsoluteTiming // First l1 === l2 === l3 === l4 (* 1.436369 *) (* 0.190366 *) (* 0.120962 *) (* 0.084740 *) (* True *)