【问题标题】:Fast list-product sign for PackedArray?PackedArray 的快速列表产品符号?
【发布时间】:2011-03-15 00:33:17
【问题描述】:

作为my previous question 的延续,Simon 查找 PackedArray 的列表积的方法很快,但它不适用于负值。

这可以由Abs 以最少的时间代价“修复”,但标志丢失了,所以我需要单独找到产品标志。

我试过的最快的方法是EvenQ @ Total @ UnitStep[-lst]

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

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

Out[]= {3.062, Null}

有没有更快的方法?

【问题讨论】:

    标签: list wolfram-mathematica numeric packed


    【解决方案1】:

    这比您的解决方案快两倍多一点,除了使用 Rule@@@ 提取相关术语的废话之外,我发现它更清楚 - 它只是计算每个符号的数字元素。

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

    比较时间(和输出)

    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
    

    【讨论】:

    • 再次干得好,西蒙。我试过Count,但速度很慢。在我选择发布这个问题之前,我没有尝试Tally。这个网站及其乐于助人的人可能会让我变得懒惰。
    • @Mr.Wizard:这个网站也让我很懒!有时我花在解决其他人的 Mma 问题上的时间比我发布我的时间要多。 (幸运的是,在这种情况下,Tally 是我尝试的第二件事)。
    • @Mr.Wizard:我想这只是表明 StackExchange 站点的基本模型非常符合人类心理。 (愚蠢、懒惰的人类……)
    【解决方案2】:

    有点迟到的帖子:如果您最终对速度感兴趣,带有 C 编译目标的Compile 似乎比迄今为止发布的最快解决方案快两倍(Tally - @987654323 @基于):

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

    这是我机器上的计时:

    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
    

    【讨论】:

    • Mma 的优点之一是您通常不必编写命令式代码...使用Compile 不可避免地会破坏这一点——但我想这是值得的。无论如何,我今天的票已经用完了,但很快就会给你投票!
    • @Simon 很长一段时间以来,我也发现在 mma 中避免程序构造最有趣,几乎不惜一切代价。但是,随着我开始更多地使用 C 和 Java 进行编码,同时我仍然经常不得不从我的 mma 中获得最大速度,我的看法发生了变化。对我来说,终极优雅是做最少的工作。在 mma 中,它可能看起来是这样,因为很多隐藏在通用函数后面。但是在这个问题中,例如,应用 Tally 和 Sign 显然比在 C 中完成的原始计数更多(CPU)工作,因此加快了速度(这并不是要减少你真正漂亮的解决方案)。
    • @我没有指定,但是这个方法在Mma 7中速度很慢,所以我不能给它打勾。
    猜你喜欢
    • 1970-01-01
    • 2014-10-17
    • 2021-07-17
    • 1970-01-01
    • 2013-04-01
    • 2013-01-30
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多