我正在尝试采用有限积分,其中所有参数和限制都具有使用品脱定义的与其关联的单位。当我尝试使用 scipy.integrate.quad 进行积分时,我出错了(下面的代码和错误)。难道品脱这时候就不能进行积分了吗?除了删除我的单位然后在积分后将它们添加回来之外,还有其他方法可以解决这个问题吗?
def f(x,y):
return x
dx=quad(f,0*ureg.nm,1*ureg.nm)
print(dx[0])
DimensionalityError: Cannot convert from 'nanometer' to 'dimensionless'
你绝对可以使用 Pint 来处理
scipy.integrate.quad
函数中的单位,但你必须注意一些事项:
-
scipy.integrate.quad
期望函数以无量纲的方式返回数值。 这意味着你需要在将你的函数传递给quad
之前或在函数内部处理好单位。 -
确保你的积分上下限具有兼容的单位。
以下是两种使用 Pint 处理你的示例的方法:
方法 1:在积分之前处理单位
在这种方法中,我们在将值传递给
quad
之前,使用 Pint 将函数和积分上下限转换为无量纲的量。
from scipy.integrate import quad
import pint
ureg = pint.UnitRegistry()
def f(x, y):
return x
# 定义单位化的积分上下限
lower_limit = 0 * ureg.nm
upper_limit = 1 * ureg.nm
# 将积分上下限转换为无量纲的数值
lower_limit_dimensionless = lower_limit.to_base_units().magnitude
upper_limit_dimensionless = upper_limit.to_base_units().magnitude
# 执行积分
result, error = quad(f, lower_limit_dimensionless, upper_limit_dimensionless)
# 将单位添加回结果
result_with_units = result * lower_limit.units * upper_limit.units
print(result_with_units)
这将输出:
0.5 nanometer ** 2
方法 2:在函数内部处理单位
在这种方法中,我们修改函数以在内部处理单位。
from scipy.integrate import quad
import pint
ureg = pint.UnitRegistry()
def f(x, y):
# 将 x 转换为纳米
x = x * ureg.nm
# 执行计算并返回无量纲的结果
return (x).to_base_units().magnitude
# 定义积分上下限(以无量纲的方式)
lower_limit = 0
upper_limit = 1
# 执行积分
result, error = quad(f, lower_limit, upper_limit)
# 将单位添加回结果
result_with_units = result * ureg.nm ** 2
print(result_with_units)
这将输出与之前相同的结果。
这两种方法都有其优点和缺点。方法 1 更明确,但需要额外的步骤来转换积分上下限。方法 2 更简洁,但可能不太明显发生了什么。选择最适合你的方法。
标签:python,scipy,pint From: 78818410