I've defined a python class in order to compute the solution of system of differential eq. Do ding so I define a classes named Rhs (right and side) that should represent the right and side of the dy/dt(i-th) this class contains a single float value (initial time , initial value , final time ) and a function (array of function) in order to define this array I simply defined 3 lambda function that rapresent equation(i) and create a np.array of this function
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]
and then passed to the rhs class in this way:
func = np.array([func1,func2,func3])
y0 = np.array([1.,0.,0.])
problem3 = rhs.Rhs(func,0.0,100.0,y0,1000)
the Rhs class is this :
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
The problem here is when the euler class call the function 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
the question here is : which is the correct method to pass the vector u that is shape = 1000,3 to the function (in order to work using the 3 function applied to the 3 vector indexing in the lambda function system ..) what I don't understand is why in C++ i didn't got this problem have a look here : all the class hierarchy I don't know in which way compute this thing
this is the error :
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
EDIT thank for reply .. but unfortunately no :( this is the error message :
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])
thanks a lot for your help ! do you have in mind other solution ?
@LutzL I don't need to doing a copy of u0 , self.u0 is shape=3, self.u should be 1000,3 (1000 row) the 3 columns represent respectively the u[0],u[1],u[2] in the equation (array of function) , by the way if I increase the number of step (decreasing the delta)