Python中具有未知常数的数值积分

计算科学 Python scipy 一体化 数字
2021-12-03 21:11:47

我想为未知的求解以下方程:T

0x2exp(xT)1κxdx=C,

其中是一个已知常数,而的值数组,而的不同值 我不想先把它适应一个函数。我希望使用 SciPy 的数值积分函数之一,例如.Cκxxκxintegrate.simps

我对如何解决这个问题感到困惑;由于在具有依赖性的指数内,我不能简单地将其从积分中拉出来。能够将未知常数传递到我的数值积分中并根据常数得到答案,那就太好了。但据我所知,在 Python 中,我无法传递未知数。我怎样才能做到这一点?Tx

编辑:这是我的数组的示例:κx

k_arr = [1.1e-3, 8.8e-2, ..., 3.7e3]

(即,浮点数的范围一般从〜10 ^ -3到10 ^ 3。但我的真实数组的长度约为3000)。

为了提供更多解释,我将其下标为的原因是因为每个值都与某个值相关联(在我的情况下,是能量或频率)。以前我使用各种能量来得出值,这些值是以 cm^2 g^-1 为单位的不透明度。所讨论的积分与星系中尘埃发出的每单位质量的功率有关,其中我省略了常数(温度除外)。它等于某个已知数字,这样我就有希望解出灰尘的温度。κxxxκT

4个回答

你想要的似乎本质上是不可能的,这不是由于 Python 的限制。

我们能够达到只需要应用一个求积的情况的唯一方法是在分析上摆脱 在积分中的所有依赖关系。为此,我们能做的最好的就是将代入积分: 现在,我们去掉了对积分的所有贡献,除了作为的一个参数。我们只能通过应用关于 的特殊知识来进一步改进这一点,但是由于Tx=Ty

I(T)=0x2κxexp(xT)1dx=0T2y2κTyexp(y)1Tdy=T30y2κTyexp(y)1dy.
Tκκκ 是经验性的,你可能不知道任何可以帮助你的东西。

从另一个角度来看,如果您将类似于中点法的方法应用于您实际拥有 ),则结果将是这些值的加权和值: 存在的权重: 其中仅取决于的间距。显然,您不能在这里只考虑 依赖关系。对于其他求积方法,权重可能会变得更复杂,但没有理由期望这可以解决上述问题。κκx1,,κxnI(T)

I(T)i=1nai(T)κxi,
ai(T)=xi2exp(xiT)1bi,
bixiT

在我看来,这个问题是关于你如何处理的。我知道您不想为其拟合函数,但我认为您无法在数组中位置以外的位置对其进行采样。您可能还需要某种渐近近似,如,以便您可以在该范围内进行推断。κx

话虽如此,我对如何处理可能更容易T

我对 SciPy 一无所知,所以你需要做一些代数。

您需要的关键观察结果是:如果是正整数,则:T>0k

0xkex/T1dx=k!Tk+1ζ(k+1)

其中是黎曼 zeta 函数。(练习:证明这一点。)ζ(z)

zeta 函数在正整数处的值是众所周知的这为您提供了一种计算方法:

0p(x)x2ex/T1dx

对于任何多项式因此,如果是多项式,您可以或多或少地直接计算以获得中的多项式,然后求解pκTT

但是,如果在概念上定义在范围内,则很可能没有一个很好的多项式近似,它在整个范围内都表现得很好。κ[0,)

所以我的建议是 Wrzlprmft 的变体,但不是使用中点方法,而是使用Gaussian 正交

如果您在域[,这将为您提供表示为的有限样本集的积分的近似值。TWT(x)=x2ex/T1[0,)κ

可能会给你一个表现良好的方程,你可以求解T

让我们假设给定的表达式有一个你可以实际写下来的非无限积分。

您应该问的问题可能更像是:“我需要计算到什么精度?”。如果作为一个值数组,你可能只能达到一定的精度。1e-16 的错误是否适合您的应用程序?您需要更高的精度吗?

Kx(x)

您可以通过开始在等间距点 x 处评估表达式(例如,您拥有的 K_x 数组的间距),并应用@Wrzlprmft 所写的权重,从这个角度解决问题。如果您在某个点停止求和,您应该能够估计出您的错误有多大。指数函数将很快迫使轮廓趋于零,因此当您的积分点 x_i 处于较高值时,您可能已经达到可存储在双精度中的最小值。根据您要解决的问题,这可能已经足够了。您能否详细说明根本问题是什么?

如果您将积分作为非线性方程的一部分,这可以纯粹以数值方式完成。

首先,我为您的函数创建了一个插值函数。它只是数据点之间的虚拟线性插值,允许端点常数外推(参见interp1d)。我让你根据你的问题和你的口味来修改它(更花哨的插值方案)。κx

的左侧定义所以我需要定义一个只接受作为参数的函数,并将积分封装在这个函数中。在 Python 中,这可能类似于下面的代码。请注意,我从左边界的机器 epsilon 进行积分,以避免处的奇点。f(T)=0

f(T)=0x2exp(xT)1κxdxC.
Tx=0

请务必阅读有关quadfsolve的文档,以便了解它们的选项和限制。根据您的函数,您的被积函数可能会达到峰值。κx

import numpy as np
from scipy.integrate import quad
from scipy.optimize import fsolve
from scipy.interpolate import interp1d

kappa_x = np.linspace(0, 10, 11)
kappa_k = np.array([1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1])

kappa_fun = interp1d(kappa_x, kappa_k, bounds_error = False, fill_value = 1.0)

def RHS(T):
    C = 1000
    def integrand(x):
        return np.power(x, 2) / (np.exp(x / T) - 1.0) * kappa_fun(x)
    res, error = quad(integrand, np.finfo(float).eps, np.inf)
    return res - C

T_sol = fsolve(RHS, 100)