10

3

I am trying to implement efficiently a transfer-matrix like algorithm. On each iteration, I have two vectors $x=\{x_1,\dots,x_n\}$, $y=\{y_1,\dots,y_n\}$ with real numbers and I need to compute the vector $\{\min(x_1,y_1),\dots,\min(x_n,y_n)\}$. I tried four approaches for computing it:

- Uncompiled
`MapThread[Min,{listX,listY}]`

call - Compiled
`MapThread[Min,{listX,listY}]`

call - Uncompiled
`Random`Private`MapThreadMin[{listX,ListY}]`

call - Compiled
`Random`Private`MapThreadMin[{listX,ListY}]`

call

(Code see below). The resulting timings were: 4.5s (for 1), 3.5s (for 2), 1.5s (for 3) and 4 reverted to uncompiled evaluation, giving 6.3s.

So my questions are:

- Is the uncompiled
`Random`Private`MapThreadMin[{listX, ListY}]`

call the fastest way to evaluate the element-wise minimum of two lists, or does anybody have a better idea? - Why does the example using
`Random`Private`MapThreadMin[{listX, ListY}]`

fail to compile?

My code examples are:

```
it1[wd_, len_] :=
Module[{pot1, fval},
pot1 = RandomVariate[NormalDistribution[], {len, wd}];
fval = ConstantArray[0., wd];
Do[fval = MapThread[Min, {RotateLeft[fval], fval}] + pot1[[k]];, {k, 1, len}];
Return[fval]];
it2 := Compile[{{wd, _Integer}, {len, _Integer}},
Module[{pot1, fval},
pot1 = RandomVariate[NormalDistribution[], {len, wd}];
fval = ConstantArray[0., wd];
Do[fval = MapThread[Min, {RotateLeft[fval], fval}] + pot1[[k]];, {k, 1, len}];
Return[fval]]];
it3[wd_, len_] :=
Module[{pot1, fval},
pot1 = RandomVariate[NormalDistribution[], {len, wd}];
fval = ConstantArray[0., wd];
Do[fval = Random`Private`MapThreadMin[ {RotateLeft[fval], fval}] + pot1[[k]];, {k, 1, len}];
Return[fval]];
it4 := Compile[{{wd, _Integer}, {len, _Integer}},
Module[{pot1, fval},
pot1 = RandomVariate[NormalDistribution[], {len, wd}];
fval = ConstantArray[0., wd];
Do[fval = Random`Private`MapThreadMin[ {RotateLeft[fval], fval}] + pot1[[k]];, {k, 1, len}];
Return[fval]]];
```

And to obtain the timing values, I used

```
Table[it1[20, 10] // First, {10000}]; // AbsoluteTiming
Table[it2[20, 10] // First, {10000}]; // AbsoluteTiming
Table[it3[20, 10] // First, {10000}]; // AbsoluteTiming
Table[it4[20, 10] // First, {10000}]; // AbsoluteTiming
```

Thank you in advance!

"Why does the example using

– J. M.'s ennui – 2012-09-28T13:14:35.760`Random`Private`MapThreadMin[{listX, ListY}]`

fail to compile?" - it's not in the list here.2For your consideration:

`minNew = Compile[{{x, _Real}, {y, _Real}}, Min[x, y], RuntimeAttributes -> {Listable}]`

. Now, try giving`minNew[]`

two lists as arguments... – J. M.'s ennui – 2012-09-28T13:22:47.857Thanks for the suggestion! I tried your minNew function, it works faster than the pure MapThread call but about 20% slower than

`Random`Private`MapThreadMin`

, unfortunately... – Alex D. – 2012-09-28T13:57:47.953