代码之家  ›  专栏  ›  技术社区  ›  Drudox lebowsky

python numpy`函数数组(lambda函数)

  •  3
  • Drudox lebowsky  · 技术社区  · 7 年前

    为了计算微分方程组的解,我定义了一个python类。 所以我定义了一个名为Rhs(right and side)的类,它应该表示dy/dt(I-th)的右边和右边。这个类包含一个浮点值(initial time,initial value,最后一次)和一个函数(函数数组)为了定义这个数组,我简单地定义了3个lambda函数,表示方程(I)并创建一个np.数组此函数的

    func1 = lambda t,u : 10   * (u[1] - u[0])
    func2 = lambda t,u : 28   * u[0] - u[1] - u[0] * u[2]  
    func3 = lambda t,u : -8/3 * u[2] + u[0]*u[1]
    

    然后以这种方式传递给rhs类:

    func = np.array([func1,func2,func3])
    y0 = np.array([1.,0.,0.])
    problem3 = rhs.Rhs(func,0.0,100.0,y0,1000) 
    

    Rhs等级如下:

        class Rhs:
        def __init__(self, fnum : np.ndarray , t0: np.float, tf: np.float, y0 : np.array, n: int , fanal = None ):
              self.func = fnum
              Rhs.solution  = fanal
              self.t0   = t0
              self.tf   = tf
              self.n    = n
              self.u0   = y0
       def createArray(self):
          '''   
             Create the Array time and f(time) 
             - the time array can be create now 
             - the solution array can be just initialize with the IV
          ''' 
          self.t = np.linspace(self.t0, self.tf, self.n )
          self.u = np.array([self.u0  for i in range(self.n) ])
    
    
          return self.t,self.u   
    
       def f(self,ti,ui):
          return self.func(ti,ui)     
    
       def Df(self,ti,ui):
          eps = 10e-6
          return ((self.func(ti,ui)+eps) - self.f(ti,ui))/eps
    

    f

    class Explicit:
         def __init__(self, dydt: rhs.Rhs, save : bool=True, _print: bool=False,  filename : str=None):
              self.dydt   = dydt
              self.dt     = (dydt.tf-dydt.t0)/dydt.n
              self._print = _print 
    
       def solve(self):
          self.time, self.u = self.dydt.createArray() 
          for i in range(len(self.time)-1): 
             self.u[i+1] = self.u[i] + self.dt*self.dydt.f(self.time[i],self.u[i])
    
    
          Explicit.solved = True 
    
          print('here')
    
          if self._print:
              with open(filename) as f:
                  print('here')
                  for i in range(len(self.u)):      
                    f.write('%.4f %4f %4f %4f' %(self.time ,self.u[0,i], self.u[1], self.u[2]))
    
    
          if self.save:
             return self.time,self.u
    

    这里的问题是:正确的方法是将向量u(形状=1000,3)传递给函数(为了使用3函数来应用于lambda函数系统中的3矢量索引……)我不理解为什么C++中没有这个问题。 请看这里: all the class hierarchy 我不知道用哪种方法计算这个东西

    Traceback (most recent call last):
      File "drive.py", line 94, in <module>
        main()
      File "drive.py", line 63, in main
        fet,feu = fwdeuler_p1.solve()
      File "/home/marco/Programming/Python/Numeric/OdeSystem/euler.py", line 77, in solve
        self.u[i+1] = self.u[i] + self.dt*self.dydt.f(self.time[i],self.u[i])
      File "/home/marco/Programming/Python/Numeric/OdeSystem/rhs.py", line 44, in f
        return self.func(ti,ui)     
    TypeError: 'numpy.ndarray' object is not callable
    

    编辑 谢谢你的回复。。但不幸的是没有:( 这是错误消息:

    drive.py:31: RuntimeWarning: overflow encountered in double_scalars
      func2 = lambda t,u : 28   * u[0] - u[1] - u[0] * u[2]
    drive.py:32: RuntimeWarning: overflow encountered in double_scalars
      func3 = lambda t,u : -8/3 * u[2] + u[0]*u[1]
    drive.py:31: RuntimeWarning: invalid value encountered in double_scalars
      func2 = lambda t,u : 28   * u[0] - u[1] - u[0] * u[2]
    /home/marco/Programming/Python/Numeric/OdeSystem/euler.py:77: RuntimeWarning: invalid value encountered in add
      self.u[i+1] = self.u[i] + self.dt*self.dydt.f(self.time[i],self.u[i])
    

    非常感谢你的帮助!你有别的解决办法吗?

    u[0],u[1],u[2] 在方程(函数数组)中,顺便说一下,如果我增加步长(减少增量)

    2 回复  |  直到 7 年前
        1
  •  1
  •   bobrobbob    7 年前

    这应该管用

    def f(self,ti,ui):
        return  np.array([function(ti,ui) for function in self.func])
    
        2
  •  0
  •   Lutz Lehmann    7 年前
      self.u = np.array([self.u0  for i in range(self.n) ])
    

    u0 作为行,而不是预期的副本。你可能想要

      self.u = np.array([self.u0[i]  for i in range(self.n) ])
    

    或者更简单

      self.u = self.u0.copy()