Search code examples
listwolfram-mathematicanumericpacked

Fast list-product sign for PackedArray?


As a continuation of my previous question, Simon's method to find the list product of a PackedArray is fast, but it does not work with negative values.

This can be "fixed" by Abs with minimal time penalty, but the sign is lost, so I will need to find the product sign separately.

The fastest method that I tried is EvenQ @ Total @ UnitStep[-lst]

lst = RandomReal[{-2, 2}, 5000000];

Do[
  EvenQ@Total@UnitStep[-lst],
  {30}
] // Timing

Out[]= {3.062, Null}

Is there a faster way?


Solution

  • This is a little over two times faster than your solution and apart from the nonsense of using Rule@@@ to extract the relevant term, I find it more clear - it simply counts the number elements with each sign.

    EvenQ[-1 /. Rule@@@Tally@Sign[lst]]
    

    To compare timings (and outputs)

    In[1]:= lst=RandomReal[{-2,2},5000000];
            s=t={};
            Do[AppendTo[s,EvenQ@Total@UnitStep[-lst]],{10}];//Timing
            Do[AppendTo[t,EvenQ[-1/.Rule@@@Tally@Sign[lst]]],{10}];//Timing
            s==t
    Out[3]= {2.11,Null}
    Out[4]= {0.96,Null}
    Out[5]= True