2016-09-29 70 views
0

我在Mathematica中有點新意,我的代碼中有很多appendto,我認爲它們佔用了一些時間。我知道還有其他一些優化方法,但我無法真正知道如何實現。我認爲getBucketShocks可以提高很多?任何人?Mathematica優化在循環中追加表格

getBucketShocks[BucketPivots_,BucketShock_,parallelOffset_:0]:= 
Module[{shocks,pivotsNb}, 
shocks={}; 
pivotsNb=Length[BucketPivots]; 
If[pivotsNb>1, 
    AppendTo[shocks,LinearFunction[{0,BucketShock},{BucketPivots[[1]],BucketShock},{BucketPivots[[2]],0},BucketPivots[[2]],0},parallelOffset]]; 

    Do[AppendTo[shocks,LinearFunction[{BucketPivots[[i-1]],0},{BucketPivots[[i]],BucketShock},{BucketPivots[[i+1]],0},{BucketPivots[[i+1]],0},parallelOffset]],{i,2,pivotsNb-1}]; 

    AppendTo[shocks,LinearFunction[{BucketPivots[[pivotsNb-1]],0},{BucketPivots[[pivotsNb]],BucketShock},{BucketPivots[[pivotsNb]],BucketShock},{BucketPivots[[pivotsNb]],BucketShock},parallelOffset]],  
    If[pivotsNb==1,AppendTo[shocks,BucketShock+parallelOffset&]]; 
]; 
shocks]; 

LinearInterpolation[x_,{x1_,y1_},{x2_,y2_},parallelOffset_:0]:=parallelOffset+y1+(y2-y1)/(x2-x1)*(x-x1); 

LinearFunction[p1_,p2_,p3_,p4_,parallelOffset_:0]:=Which[ 
#<=p1[[1]],parallelOffset+p1[[2]], 
#<=p2[[1]],LinearInterpolation[#,p1,p2,parallelOffset], 
#<=p3[[1]],LinearInterpolation[#,p2,p3,parallelOffset], 
#<=p4[[1]],LinearInterpolation[#,p3,p4,parallelOffset], 
#>p4[[1]],parallelOffset+p4[[2]]]&; 
+0

這裏有幾個想法http://stackoverflow.com/q/39599232/1004168。 – agentp

回答

1

我想你可以使用某種形式的Map這種或那種方式優化中間Do循環了很多。在每次迭代中,您都試圖訪問BucketPivots的3個相鄰元素。這似乎是MovingMap最容易做到的,但你需要跳過幾圈才能在正確的位置獲得參數。這一個可能是最簡單的解決方案:

shocks = MovingMap[ 
    LinearFunction[ 
    {#[[1]], 0}, 
    {#[[2]], BucketShock}, 
    {#[[3]], 0}, 
    {#[[3]], 0}, 
    parallelOffset 
    ]&, 
    BucketPivots, 
    2 
] 

作爲一般原則:如果你想要做的數學一DoFor循環,運行在另一個列表的Length,試圖找到一種方法可以做到這一點具有Map系列(Map,MapIndexed,MapAt,MapThread等)的功能並熟悉這些功能。它們是迭代的很好替代品!

在此之後,shocks的第一個和最後一個元素可以與AppendTo一起添加。

順便說一句:這是一個免費的提示。我建議在Mathematica中避免給出以大寫字母開頭的變量和函數名稱(就像您使用BucketPivots所做的那樣)。 Mathematica自己的所有符號都以大寫字母開頭,所以如果您自己避免使用它們,您永遠不會與內置函數衝突。