2

さまざまな密度のシェルで構成される球を考えてみましょう。
2つの配列があります。1つは各シェルの外半径用(rad[])、もう1つは各シェルの密度用(den[])です。と呼ばれる、与えられた半径までの質量を計算したいと思いmass[]ます。

次のforループアプローチでは、最初に最も内側のシェルの質量(内側の半径がゼロであるため、球体)を見つけ、次に後続の各シェルの質量を前の(合計された)質量に追加することで、目的の結果を達成します。

mass = numpy.zeros(len(rad))                                   # create array
mass[0] = den[0]**(rad[0]**3)                                  # find inner sphere mass
for i in range(1,len(mass)):
    mass[i] = mass[i-1] + den[i]*(rad[i]**3 - rad[i-1]**3)     # Find mass out to shell i

注:必要なのはスケーリングだけなので、円周率の要因については心配していません。

次のスライス結果が同じ結果を達成しない理由を誰かが説明できますか?

mass = numpy.zeros(len(rad))
mass[0]  = den[0]*(rad[0]**3)
mass[1:] = mass[0:-1] + den[1:]*(rad[1:]**3-rad[0:-1]**3)
4

1 に答える 1

3

その理由は、numpy配列のすべての要素が同時に計算されるためです。2行目の配列は、ゼロのみが続くものmass[0:-1]として評価されます。(線が計算されるとゼロではなくなるden[0]*(rad[0]**3)という事実は関係ありません-それまでには手遅れです)。mass[1]

あなたはその例に注意しました:

test = numpy.linspace(1,10,num=10)
test[1:] += test[0:-1]
# [  1.   3.   6.  10.  15.  21.  28.  36.  45.  55.]

加算が繰り返し行われるかのように、動作が異なります。例の違いは、右側に値を追加することです。この追加により、メモリ内の新しい配列(x + yと同じ配列ではないx)にnumpyなり、それ自体への追加として扱われなくなります。この例を参照してください

test = numpy.linspace(1,10,num=10)
test[1:] += test[0:-1] + 0
# [  1.   3.   5.   7.   9.  11.  13.  15.  17.  19.]

forループのベクトル化バージョンを実行する場合は、次の操作を実行できます。

mass[1:] += den[1:]*(rad[1:]**3-rad[0:-1]**3)
mass[1:] += mass[0:-1]
于 2013-03-10T00:28:27.483 に答える