我一直在尝试为学校项目编写隐式的euler方法。 这是关于在重力作用下产生摩擦的钟摆。 因此,该方程分为2
def pend(y, t, b, c):
theta, omega = y
dydt = [omega, -b*omega - c*np.sin(theta)]
return dydt
b
,c
是常量。
这是欧拉方法
def Euler(f,tinit,tfinal, THinit,N,b,c):
h= (tfinal-tinit)/N #step
TH = [THinit] #initialization TH = [theta,omega]
lt = [tinit]
t=tinit
y=THinit
while t<tfinal:
t= t+h
lt.append(t) #list of time
result =scipy.optimize.fsolve(lambda x:x-y-h*f(x,t,b,c), y)
TH.append(r)
y=result
return TH,lt
使用f = pend
的代码,我得到了错误
TypeError:无法将序列乘以'float'类型的非整数
对于具有数组参数和/或返回数组的函数,也许我们不能使用fsolve
。感谢您的帮助。
全码:
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize
g=9.81
L=0.5
def pend(y, t, b, c):
theta, omega = y
dydt = [omega, -b*omega - c*np.sin(theta)]
return dydt
def Euler(f,tinit,tfinal, THinit,N,b,c):
h= (tfinal-tinit)/N
TH = [THinit]
lt = [tinit]
t=tinit
y=THinit
while t<tfinal:
t= t+h
lt.append(t)
result =scipy.optimize.fsolve(lambda x:x-y-h*f(x,t,b,c), y)
TH.append(r)
y=result
return TH,lt
Y,X = Euler(pend,0,10,[np.pi/8,0],100,0.25,5)
plt.plot(X,Y)
plt.show()
答案 0 :(得分:0)
您的pend()
返回一个列表(return [omega, -b*omega - c*np.sin(theta)]
通过变量dydt
)。然后,该列表用在术语h*f(x,t,b,c)
中。 h
是float
,因此您尝试将float
和list
相乘。这是不可能的。将int
与list
相乘是可能的,并导致列表的重复:
5 * [ 42, 23 ]
产生
[ 42, 23, 42, 23, 42, 23, 42, 23, 42, 23 ]
但是对于浮点数,则未定义。请提供有关您期望发生的事情的更多信息。仅给出(这种)代码,很难猜测。
编辑:
从后来添加的内容中,我现在猜测您想将数组的每个元素乘以浮点数,并期望得到一个数组。 numpy
数组就是这样做的,所以我建议立即返回一个numpy
数组:
dydt = np.array([omega, -b*omega - c*np.sin(theta)])
return dydt
答案 1 :(得分:0)
这是您看到的错误:
In [1]: 3.2 * [1,2,3]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-73b36d584f00> in <module>()
----> 1 3.2 * [1,2,3]
TypeError: can't multiply sequence by non-int of type 'float'
其原因是列表上*
运算符的语义。
In [2]: 3 * [1,2,3]
Out[2]: [1, 2, 3, 1, 2, 3, 1, 2, 3]
您可能打算将向量乘以标量
In [3]: 3 * numpy.array([1,2,3])
Out[3]: array([3, 6, 9])
In [4]: 3.2 * numpy.array([1,2,3])
Out[4]: array([ 3.2, 6.4, 9.6])
因此pend应该返回numpy.array(dydt)