我正在尝试求解这两个积分,我想使用数值方法,因为 C_i 最终会变得更加复杂,我想在所有情况下使用它。目前,C_i 只是一个常量,因此 _quad 无法解决它。我假设是因为它是一个赫维赛德函数,并且很难找到 a、b。如果我的做法有误,请纠正我。
方程 33
In [1]: import numpy as np
...: import scipy as sp
...: import sympy as smp
...: from sympy import DiracDelta
...: from sympy import Heaviside
In [2]: C_i = smp.Function('C_i')
In [3]: t, t0, x, v = smp.symbols('t, t0, x, v', positive=True)
In [4]: tot_l = 10
In [5]: C_fm = (1/tot_l)*v*smp.Integral(C_i(t0), (t0, (-x/v)+t, t))
In [6]: C_fm.doit()
Out[6]:
0.1*v*Integral(C_i(t0), (t0, t - x/v, t))
In [7]: C_fm.doit().simplify()
Out[7]:
0.1*v*Integral(C_i(t0), (t0, t - x/v, t))
In [8]: C_fms = C_fm.doit().simplify()
In [9]: t_arr = np.arange(0,1000,1)
In [10]: f_mean = smp.lambdify((x, v, t), C_fms, ['scipy', {'C_i': lambda e: 0.8}])
In [11]: try2 = f_mean(10, 0.1, t_arr)
Traceback (most recent call last):
File "/var/folders/rd/wzfh_5h110l121rmlxn61v440000gn/T/ipykernel_3164/3786931540.py", line 1, in <module>
try2 = f_mean(10, 0.1, t_arr)
File "<lambdifygenerated-1>", line 2, in _lambdifygenerated
return 0.1*v*quad(lambda t0: C_i(t0), t - x/v, t)[0]
File "/opt/anaconda3/lib/python3.9/site-packages/scipy/integrate/quadpack.py", line 348, in quad
flip, a, b = b < a, min(a, b), max(a, b)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
方程 34
In [12]: C_i = smp.Function('C_i')
In [13]: t, tao, x, v = smp.symbols('t, tao, x, v', positive=True)
In [14]: I2 = v*smp.Integral((C_i(t-tao))**2, (tao, 0, t))
In [15]: I2.doit()
Out[15]:
v*Integral(C_i(t - tao)**2, (tao, 0, t))
In [16]: I2.doit().simplify()
Out[16]:
v*Integral(C_i(t - tao)**2, (tao, 0, t))
In [17]: I2_s = I2.doit().simplify()
In [18]: tao_arr = np.arange(0,1000,1)
In [19]: I2_sf = smp.lambdify((v, tao), I2_s, ['scipy', {'C_i': lambda e: 0.8}])
In [20]: try2 = I2_sf(0.1, tao_arr)
Traceback (most recent call last):
File "/var/folders/rd/wzfh_5h110l121rmlxn61v440000gn/T/ipykernel_3164/4262383171.py", line 1, in <module>
try2 = I2_sf(0.1, tao_arr)
File "<lambdifygenerated-2>", line 2, in _lambdifygenerated
return v*quad(lambda tao: C_i(t - tao)**2, 0, t)[0]
File "/opt/anaconda3/lib/python3.9/site-packages/scipy/integrate/quadpack.py", line 351, in quad
retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
File "/opt/anaconda3/lib/python3.9/site-packages/scipy/integrate/quadpack.py", line 463, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
File "/opt/anaconda3/lib/python3.9/site-packages/sympy/core/expr.py", line 345, in __float__
raise TypeError("Cannot convert expression to float")
TypeError: Cannot convert expression to float
因此,您将未评估的
Integrate
传递给 lambdify
,这又将其调用转换为 scipy.integrate.quad
。
看起来即使使用
doit
和 simplify
调用也无法计算积分。你真的看过C_fms
和I2_s
吗?这是运行此代码时我要做的第一件事!
我从来没有研究过这种方法。我见过人们
lambdify
的客观表达,然后尝试直接在quad
中使用它。
quad
有特定要求(查看文档!)。目标函数必须返回单个数字,并且边界也必须是数字。
在第一个错误中,您将数组
t_arr
作为 t
边界传递,并且在检查它比另一个边界 ambiguity
更大的位置时,它得到了通常的 0
错误。这就是 b < a
测试。 quad
不能使用数组作为边界。
我不知道为什么第二种情况会避免这个问题——边界必须来自其他地方。但是当
quad
调用目标函数并期望浮点返回时,就会出现错误。相反,该函数返回一个 sympy
表达式,而 sympy
无法转换为浮点数。我猜表达式中的某些变量仍然是 sympy.symbol
。
在诊断
lambdify
问题时,最好查看生成的代码。一种方法是在函数 help
上使用 help(I2_sf)
。但你需要能够阅读和理解 python,包括任何 numpy
和 scipy
函数。这并不总是那么容易。
您是否尝试过使用
sympy's
自己的数字积分器?尝试结合 sympy
和 numpy/scipy
通常会遇到问题。