Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 天体动力学引擎的类或元类设计_Python_Math_Oop_Simulation_Physics - Fatal编程技术网

Python 天体动力学引擎的类或元类设计

Python 天体动力学引擎的类或元类设计,python,math,oop,simulation,physics,Python,Math,Oop,Simulation,Physics,大师们: 航天器运动建模的微分方程可以用一系列加速度项来描述: d2r/dt2 = a0 + a1 + a2 + ... + an 通常a0是由于物体引起的点质量加速度(a0=-mu*r/r^3);“高阶”术语可能是由其他行星、太阳辐射压力、推力等引起的 我正在实现一组算法,用于这种系统。我将从Python开始设计和原型,然后我将继续使用C++或FORTRAN 95。 我想设计一个类(或元类),它允许我为给定实例指定不同的加速条件,大致如下: # please notice this is

大师们:

航天器运动建模的微分方程可以用一系列加速度项来描述:

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将默认为,比方说,两个加速项,我将为另外两个我想要的项添加一个参数:
some acceleration
some_other_acceleration
;它们返回一个向量(这里表示为三元组)。注意,在我的“实现”中,我重载了
+
操作符

通过这种方式,算法将被设计为一个抽象的“航天器”,所有实际力场将在个案基础上提供,使我能够使用简化模型,比较建模方法等

您将如何实现一个类或元类来处理这个问题

我为这个相当冗长且没有解释清楚的问题道歉,但我的脑子里有点模糊


谢谢。

我会使用一些可以处理向量的库(在python中,试试numpy),并将加速度表示为向量。然后,您不是在重新发明轮子,+操作符按照您想要的方式工作。如果我误解了您的问题,请纠正我。

对于那些希望避免使用numpy并使用纯python执行此操作的人,这可能会给您一些好主意。我相信这个小短剧也有缺点和缺点。“运算符”模块可加快您的数学计算速度,因为它们是使用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)

带加速度物体的速度 一秒钟后的加速度(13.3574,24.3574,35.3574): 速度(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)

你是在问如何为航天器级存储任意数量的加速度源吗

你不能只使用一组函数吗?(使用c++时的函数指针)

i、 e:

让您将具有空间或物理意义的“组件”,以及与之相关的数学表达式,构建成更大的组件,这些组件知道如何进行总结等。结果是一种使用符号工具以模块化方式指定微分方程的方法,然后PydTool将自动创建C代码,以使用快速积分器模拟系统。在使用C和Fortran进行“繁重的工作”之前,不需要将python看作是一个缓慢的原型制作步骤。一旦您完全指定了问题,PydTool已经将所有内容(包括您定义的结果向量场)向下移动到C级别

你的二阶DEs的例子非常类似于包含多种离子通道的生物细胞膜电位差的“电流平衡”一阶方程。根据基尔霍夫定律,p.d.的变化率是

dV/dt=1/memb_电容*(电流之和)

中的示例是包中捆绑的几个示例之一,该包使用模块化规范组件(您继承以创建自己的类,如物理环境中的“点质量”)为膜构建模型,并使用类似宏的规范将最终DE定义为膜中存在的任何电流的总和“离子通道”组件添加到“膜”组件中。求和在函数中定义,只需使用“for(channel,current,+)/C”等语句,您可以直接在代码中使用


希望这有帮助。如果有,请随时问我(PydTool的作者)如果您需要更多帮助,请访问sourceforge上的帮助论坛开始使用。

不要抨击Python,但是有一些环境专门针对这样的计算繁重的任务。我想到了Matlab。您想做的一些事情可能会更自然或更容易。@Carl:Python用于解决方案b的原型设计首先,我要研究一种更强大的编译语言。如果在Python中逻辑和设计工作良好,我已经完成了在C++中部署一个很棒的应用程序所需的80%的工作。至于裁剪解决重任务的解决方案,那就是我的工作:)根据任务,我执行的几个基准在MATLAB中显示了类似的性能。&Python和这两种语言具有相似的功能(当您在Python中包含numpy/scipy/matplotlib时)。我建议您从一种语言切换到另一种语言的唯一原因是特定于您所在领域的MATLAB工具箱(到MATLAB)或price(到Python)-否则,我认为在优化之前使用MATLAB/Python进行原型设计是完美的…顺便说一句,我假设您找到了一个解决方案,因为它已经很旧了?是的。我选择了一个工作良好的设计。我对速度不太感兴趣(即二次设计优先)因为最终所有的东西都将在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)