使用lambdify时出现quad问题

问题描述 投票:0回答:1

我正在尝试求解这两个积分,我想使用数值方法,因为 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
sympy lambdify symbolic-integration
1个回答
0
投票

因此,您将未评估的

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
通常会遇到问题。

© www.soinside.com 2019 - 2024. All rights reserved.