【问题标题】:Mathematica, improve speed for appendto in the loopMathematica,提高循环中追加的速度
【发布时间】:2017-01-28 16:21:31
【问题描述】:

如何改进以下功能?目前它非常缓慢。提前致谢。

    discounts[firstDFF_] :=
        Module[ 
            {len = Length[swapdata], running = firstDF, newdisc, disclist = {firstDFF}, k = 2},

            Do[
                newdisc = (1 - swapdata[[k]]*running)/(1 + swapdata[[k]]);

                running += newdisc;

                AppendTo[disclist, newdisc]
                , 
                {k, 1, len}
            ];

            disclist
        ];

它用于在引导过程中获取折扣因子列表。

【问题讨论】:

  • Join[disclist, Reap[ Do[ ... Sow[newdisc], {k, 1, len}] ][[2, 1]] ] 因此,您使用 Sow 而不是 AppendTo这将快速收集您的 Do 中生成的所有项目,然后您使用 [[2,1]] 获取结果列表,然后您在 Do 之外使用 Join 完成。
  • 把你的Do 变成Table,所以整个事情看起来就像Prepend[Table[newdisc = (1 - swapdata[[k]]*running)/(1 + swapdata[[k]]);running += newdisc;newdisc,{k,len}],firstDFF]
  • 为什么声明k=2,然后只使用k作为循环变量? Do 本地化它的迭代器变量。考虑使用FoldList 而不是Do
  • 谢谢大家!它真的很有帮助!赞赏!

标签: performance loops optimization append wolfram-mathematica


【解决方案1】:

只需使用 disclist = {disclist, newdisc}Flatten 而不是 AppendTo[disclist, newdisc],代码就可以从 14.59 秒加速到 0.34 秒。

下面的演示。首先是OP的原始代码。

swapdata = ConstantArray[0.03, 100000];

firstDF = 1;

discounts[firstDFF_] := Module[{len = Length[swapdata],
    running = firstDF,
    newdisc,
    disclist = {firstDFF}, k = 2},
   Do[newdisc = (1 - swapdata[[k]]*running)/(1 + swapdata[[k]]);
    running += newdisc;
    AppendTo[disclist, newdisc], {k, 1, len}];
   disclist];

First[{time, result1} = Timing[discounts[100]]]

14.594

discounts[firstDFF_] := Module[{
    len = Length[swapdata],
    running = firstDF,
    newdisc,
    disclist = {firstDFF}, k = 2},
   Do[newdisc = (1 - swapdata[[k]]*running)/(1 + swapdata[[k]]);
    running += newdisc;
    disclist = {disclist, newdisc}, {k, 1, len}];
   Flatten@disclist];

First[{time, result2} = Timing[discounts[100]]]

0.343

result1 == result2

是的

【讨论】:

  • 谢谢!它有很大帮助。欣赏!
【解决方案2】:

还有更多方法。这些只是比 ChrisD 的 Do .. disclist = {disclist, newdisc} .. 稍快

discounts[firstDFF_] := 
  Module[{len = Length[swapdata], running = firstDF, newdisc},
   Join[{firstDFF}, Table[
     newdisc = (1 - swapdata[[k]]*(running))/(1 + swapdata[[k]]);
     running += newdisc;
     newdisc, {k, 1, len}]]];
First[{time, result} = Timing[discounts[100]]]

discounts[firstDFF_] := Module[{running = firstDF, newdisc},
   Join[{firstDFF}, (
       newdisc = (1 - #*running)/(1 + #);
       running += newdisc;
       newdisc) & /@ swapdata]];
First[{time, result} = Timing[discounts[100]]]

discounts[firstDFF_] :=
  Reap[Sow[firstDFF];
    Fold[#1 + Sow[(1 - Times@##)/(1 + #2)] &, firstDF  ,
       swapdata]][[2, 1]];
First[{time, result} = Timing[discounts[100]]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多