2

そこの達人:

宇宙船の運動をモデル化するための微分方程式は、加速度項の集まりで記述できます。

d2r/dt2 =  a0 + a1 + a2 + ... + an

通常、a0 は物体による点の質量加速度です (a0 = -mu * r/r^3)。「高次」の用語は、他の惑星、太陽放射圧、推力などに起因する可能性があります。

この種のシステムで動作することを意図したアルゴリズムのコレクションを実装しています。設計とプロトタイピングには Python から始め、次に C++ または Fortran 95 に移行します。

特定のインスタンスに対してさまざまな加速用語を指定できるようにするクラス (またはメタクラス) を設計したいと考えています。

# please notice this is meant as "pseudo-code"
def some_acceleration(t):
    return (1*t, 2*t, 3*t)

def some_other_acceleration(t):
    return (4*t, 5*t, 6*t)

S = Spacecraft()
S.Acceleration += someacceleration + some_other_acceleration

この場合、インスタンス S はデフォルトで、たとえば 2 つの加速項になり、必要な他の 2 つの項を追加しsome accelerationますsome_other_acceleration。それらはベクトルを返します (ここではトリプレットとして表されます)。私の「実装」では、+演算子をオーバーロードしていることに注意してください。

このようにして、アルゴリズムは抽象的な「宇宙船」用に設計され、すべての実際の力場がケースバイケースで提供されるため、単純化されたモデルで作業したり、モデリング方法論を比較したりできます。

これを処理するクラスまたはメタクラスをどのように実装しますか?

かなり冗長で明確に説明されていない質問で申し訳ありませんが、私の頭の中では少しあいまいです。

ありがとう。

4

4 に答える 4

2

PyDSToolを使用すると、空間的または物理的な意味を持ち、それらに関連付けられた数式を持つ "コンポーネント" を構築して、それらを合計する方法などを知っているより大きなコンポーネントにすることができます。その結果、シンボリックを使用してモジュラー方式で微分方程式を指定する方法が得られます。ツールを使用すると、PyDSTool が C コードを自動的に作成し、高速インテグレーターを使用してシステムをシミュレートします。C と Fortran で「重労働」を行う前に、Python を遅いプロトタイピングのステップとしてのみ見る必要はありません。PyDSTool は、問題を完全に特定すると、定義した結果のベクトル フィールドを含むすべてを C レベルに移行します。

二次DEの例は、複数のタイプのイオンチャネルを含む生体細胞膜全体の電位差の「電流バランス」一次方程式に非常に似ています。Kirchoff の現在の法則により、pd の変化率は

dV/dt = 1/memb_capacitance * (電流の合計)

PyDSTool/tests/ModelSpec_tutorial_HH.pyの例は、モジュラー仕様コンポーネントから膜のモデルを構築するパッケージにバンドルされているいくつかの例の 1 つです ( ModelSpecクラスから継承して独自のコンポーネントを作成します。物理学の「point_mass」など)。環境)、マクロのような仕様を使用して、「膜」コンポーネントに追加された「イオンチャネル」コンポーネントに存在する電流の合計として最終的な DE を定義します。合計はmakeSoma関数で定義され、'for(channel,current,+)/C' などのステートメントを使用するだけで、コードで直接使用できます。

お役に立てれば。その場合は、sourceforge のヘルプ フォーラムで私 (PyDSTool の作成者) に気軽に質問してください。

于 2011-07-30T21:25:50.937 に答える
1

宇宙船クラスの任意の数の加速源を格納する方法を尋ねていますか?

関数の配列だけを使用することはできませんか?(c ++に到達したときの関数ポインター)

すなわち:

#pseudo Python
class Spacecraft
    terms = []
    def accelerate(t):
       a = (0,0,0)
       for func in terms:
         a+= func(t)


s = Spacecraft
s.terms.append(some_acceleration)
s.terms.append(some_other_acceleration)
ac = s.accelerate(t)
于 2010-01-21T02:35:56.910 に答える
1

numpy を避けて純粋な python でこれを行いたい人にとって、これはいくつかの良いアイデアを与えるかもしれません。この小さなスキットにも欠点と欠陥があると確信しています。"operator" モジュールは、C 関数で行われるため、数学計算を高速化します。

from operator import sub, add, iadd, mul
import copy

class Acceleration(object):
   def __init__(self, x, y, z):
      super(Acceleration, self).__init__()
      self.accel = [x, y , z]
      self.dimensions = len(self.accel)

   @property
   def x(self):
      return self.accel[0]

   @x.setter
   def x(self, val):
      self.accel[0] = val


   @property
   def y(self):
      return self.accel[1]

   @y.setter
   def y(self, val):
      self.accel[1] = val

   @property
   def z(self):
      return self.accel[2]

   @z.setter
   def z(self, val):
      self.accel[2] = val

   def __iadd__(self, other):
      for x in xrange(self.dimensions):
         self.accel[x] = iadd(self.accel[x], other.accel[x])
      return self

   def __add__(self, other):
      newAccel = copy.deepcopy(self)
      newAccel += other
      return newAccel

   def __str__(self):
      return "Acceleration(%s, %s, %s)" % (self.accel[0], self.accel[1], self.accel[2])

   def getVelocity(self, deltaTime):
      return Velocity(mul(self.accel[0], deltaTime), mul(self.accel[1], deltaTime), mul(self.accel[2], deltaTime))

class Velocity(object):
   def __init__(self, x, y, z):
      super(Velocity, self).__init__()
      self.x = x
      self.y = y
      self.z = z

   def __str__(self):
      return "Velocity(%s, %s, %s)" % (self.x, self.y, self.z)

if __name__ == "__main__":
   accel = Acceleration(1.1234, 2.1234, 3.1234)
   accel += Acceleration(1, 1, 1)
   print accel

   accels = []
   for x in xrange(10):
      accel += Acceleration(1.1234, 2.1234, 3.1234)

   vel = accel.getVelocity(2)
   print "Velocity of object with acceleration %s after one second:" % (accel)
   print vel

以下を出力します。

加速度(2.1234、3.1234、4.1234)

1 秒後の加速度 Acceleration(13.3574, 24.3574, 35.3574) のオブジェクトの速度: Velocity(26.7148, 48.7148, 70.7148)

より高速な計算に夢中になることができます。

def getFancyVelocity(self, deltaTime):
   from itertools import repeat
   x, y, z = map(mul, self.accel, repeat(deltaTime, self.dimensions))
   return Velocity(x, y, z)
于 2010-01-04T18:28:40.380 に答える
0

代わりに、ベクトルで動作し(pythonではnumpyを試してください)、加速度をベクトルとして表すことができるライブラリを使用します。次に、車輪の再発明ではなく、 + 演算子は希望どおりに機能します。私があなたの問題を誤解した場合は、私を修正してください。

于 2010-01-04T17:50:39.237 に答える