Search code examples
wolfram-mathematicamathematica-7

Is there a faster way to find both Min and Max values?


Often I have written: {Min@#, Max@#} &

Yet this seems inefficient, as the expression must be scanned twice, once to find the minimum value, and once to find the maximum value. Is there a faster way to do this? The expression is often a tensor or array.


Solution

  • This beats it by a bit.

    minMax = Compile[{{list, _Integer, 1}},
       Module[{currentMin, currentMax},
        currentMin = currentMax = First[list];
        Do[
         Which[
          x < currentMin, currentMin = x,
          x > currentMax, currentMax = x],
         {x, list}];
        {currentMin, currentMax}],
       CompilationTarget -> "C",
       RuntimeOptions -> "Speed"];
    v = RandomInteger[{0, 1000000000}, {10000000}];
    minMax[v] // Timing
    

    I think it's a little faster than Leonid's version because Do is a bit faster than For, even in compiled code.

    Ultimately, though, this is an example of the kind of performance hit you take when using a high level, functional programming language.

    Addition in response to Leonid:

    I don't think that the algorithm can account for all the time difference. Much more often than not, I think, both tests will be applied anyway. The difference between Do and For is measurable, however.

    cf1 = Compile[{{list, _Real, 1}},
       Module[{sum},
        sum = 0.0;
        Do[sum = sum + list[[i]]^2,
         {i, Length[list]}];
        sum]];
    cf2 = Compile[{{list, _Real, 1}},
       Module[{sum, i},
        sum = 0.0;
        For[i = 1, i <= Length[list],
         i = i + 1, sum = sum + list[[i]]^2];
        sum]];
    v = RandomReal[{0, 1}, {10000000}];
    First /@{Timing[cf1[v]], Timing[cf2[v]]}
    
    {0.685562, 0.898232}