2011-07-20 20 views
3

私はNumPyを使用して、大きなボックスと小さなボックスの間のApertureでY切片を見つける計算をしています。大きな箱には100,000個以上の粒子があり、小さな箱には1000個以上の粒子があります。そしてそれはそうするために多くの時間がかかります。すべてのself.YD、self.XDは、私が乗算している非常に大きな配列です。計算 - numpy pythonのバグ

PS:indは、乗算する必要がある値のインデックスです。私は自分のコードでその行の前に非ゼロの条件を持っていました。

私はこの計算を簡単な方法でどのように行うのですか?

YD_zero = self.oldYD[ind] - ((self.oldYD[ind]-self.YD[ind]) * self.oldXD[ind])/(self.oldXD[ind]-self.XD[ind]) 

ありがとうございます!乗算、除算、減算し、numpyののすべてのものを使用して

UPDATE

でしょう。早くする? もしかすると私は計算を分割します。例えば。最初にこれを行うには

YD_zero = self.oldYD[ind] - ((self.oldYD[ind]-self.YD[ind])*self.oldXD[ind]) 

し、次の行は次のようになります。

YD_zero /= (self.oldXD[ind]-self.XD[ind]) 

任意の提案!私は今しばらく、これを理解しようとしている2

UPDATEではなく、多くの進歩。私の懸念は、分母が次のように分母であるということです。

self.oldXL[ind]-self.XL[ind] == 0 

そして私は奇妙な結果を得ています。

もう1つは非ゼロ関数です。私はしばらくそれをテストしています。 Matlabで見つけたものとほとんど同じだと誰にでも教えてもらえますか?

+0

は、重大な精度の損失ですか? – Wok

+0

本当に正確なデータが必要です。 –

+0

シンプルにすると、CPUのサイクル数は少なくなりますか? –

答えて

2

すべての計算は要素単位で行われるので、式をCythonに書き直すのは簡単です。これにより、oldYD-YDなどを実行したときに作成される、非常に大きな一時的配列がすべて回避されます。

もう一つの可能​​性はnumexprです。

+0

NumexprまたはCythonで2つの配列をどのように乗算すればよいですか? CythonやNumexprをお勧めしますか? –

+0

@theSun:特に混乱の原因となる乗算については何ですか? 'Cython'と' numexpr'については、後者は簡単に正しいものにすべきです。しかし私は個人的には前者しか使っていないので、私が気づいていない 'numexpr'の周りに微妙なことがあるかもしれません。 – NPE

3

おそらく私は棒の間違った終わりを持っていますが、Numpyではベクトル化された計算を実行できます。

YD_zero = self.oldYD - ((self.oldYD - self.YD) * self.oldXD)/(self.oldXD - self.XD)

それははるかに高速でなければなりません...囲むwhileループを削除し、ちょうどこれを実行します。

更新:ニュートン・ラプソン法を使用して反復ルート発見...

unconverged_mask = np.abs(f(y_vals)) > CONVERGENCE_VALUE: 
while np.any(unconverged_mask): 
    y_vals[unconverged_mask] = y_vals[unconverged_mask] - f(y_vals[unconverged_mask])/f_prime(y_vals[unconverged_mask]) 
    unconverged_mask = np.abs(f(y_vals)) > CONVERGENCE_VALUE: 

このコードは一例ですが、それはあなたが任意の関数fにベクトル化コードを使用して反復プロセスを適用する方法を示していますあなたはf_primeの微分を見つけることができます。unconverged_maskは、現在の反復の結果が、まだ収束していない値にのみ適用されることを意味します。

この場合、反復する必要はありません.Newton-Raphsonは直線を扱っているため、最初の繰り返しで正しい答えを得られます。あなたが持っているものは正確な解決策です。

セカンド更新

[OK]をので、あなたは、ニュートン・ラプソンを使用していません。一度にYD_zero(y切片)を計算するには、使用することができ、dYdXはあなたのケースでは、あるように思わ勾配、ある

YD_zero = YD + (XD - X0) * dYdX

dYdX = (YD - oldYD)/(XD - oldXD)

I XDおよびYDを粒子の現在のx、y値とすると、oldXDおよびoldYDは、粒子の以前のx、y値であり、X0は、開口のx値であるure。

なぜすべての粒子を繰り返し処理する必要があるのか​​まだ完全にはっきりしていないため、Numpyはすべての粒子の計算を一度に行うことができます。

+0

ベクトル化すると、実際に速度が必要な場合は、後でGPUに移動することもできます。 –

+0

私はそれをベクトル化しましたが、私はループの中にたくさんのものがあります。私はこれが他のすべてより長くかかると思う。私はこれを使わずに走ったので、ずっと速かったから。 –

+1

私はループがインデックス上ではなく、反復ニュートンアルゴリズムであると信じています。 – Wok

0

私は間違いなくnumexprに行きます。私はnumexprは、インデックスを扱うことができるかわからないんだけど、私は、次の(または類似したもの)が働くだろうと賭け:あなたがポイントのセットをトリミングしようとした場合

import numexpr as ne 

yold = self.oldYD[ind] 
y = self.YD[ind] 
xold = self.oldXD[ind] 
x = self.XD[ind] 
YD_zero = ne.evaluate("yold - ((yold - y) * xold)/(xold - x)")