Quick Trademark List for PackedArray?

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

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

The fastest method I've 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?

+2
list wolfram-mathematica numeric
source share
2 answers

This is slightly more than twice as fast as your solution, and besides hacking using Rule@@@ to extract the corresponding term, I find it more understandable - it just counts the numeric elements with each character.

 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 
+3
source share

A little late mail: if you are ultimately interested in speed, Compile for the purpose of compiling C seems to be about twice as fast as the fastest solution published so far ( Tally - Sign ):

 fn = Compile[{{l, _Real, 1}}, Module[{sumneg = 0}, Do[If[i < 0, sumneg++], {i, l}]; EvenQ[sumneg]], CompilationTarget -> "C", RuntimeOptions -> "Speed"]; 

The following are the timings on my machine:

 In[85]:= lst = RandomReal[{-2, 2}, 5000000]; s = t = q = {}; Do[AppendTo[s, EvenQ@Total@UnitStep[-lst]], {10}]; // Timing Do[AppendTo[t, EvenQ[-1 /. Rule @@@ Tally@Sign[lst]]], {10}]; // Timing Do[AppendTo[q, fn [lst]], {10}]; // Timing s == t == q Out[87]= {0.813, Null} Out[88]= {0.515, Null} Out[89]= {0.266, Null} Out[90]= True 
+1
source share

All Articles