主值积分与Python

huangapple go评论64阅读模式
英文:

Principal Value Integration with Python

问题

我试图在Python中进行函数积分。它具有奇点,并且使用scipy.integrate,我无法获得令人满意的结果(我还收到IntegrationWarning)。

这是我迄今为止的代码。这是我第一次处理这样的函数,我有点迷失。

from scipy.integrate import quad
import numpy as np

def integrand(x):
    return -(x * np.sin(2*x)) / (x * np.cos(x) + np.sin(x))

def cauchy_principal_value(f, a, b, singular_point):
    integral = quad(f, a, b, points=[a, singular_point, b], limit=1000)
    return integral

result = cauchy_principal_value(integrand, 0, np.pi, 2.0287665755744362)

print("Principal Value: ", result[0])

有人可以帮助我吗?

英文:

I am trying to integrate a function with python. It has a singularity and using scipy.integrate I am not able to get satisfying results (I also get an IntegrationWarning).

This is my code thus far. This is my first time handling such functions and I am a bit lost.

from scipy.integrate import quad
import numpy as np

def integrand(x):
    return -(x * np.sin(2*x)) / (x * np.cos(x) + np.sin(x))

def cauchy_principal_value(f, a, b, singular_point):
    integral = quad(f, a, b, points=[a, singular_point, b],limit=1000)
    return integral

result = cauchy_principal_value(integrand, 0, np.pi, 2.0287665755744362)

print("Principal Value: ", result[0])

Can anyone help me?

答案1

得分: 1

一般来说,积分程序在处理奇点时需要一些帮助。

如果你知道你需要一个主值,通过在quad中使用weight="cauchy"来告诉它(查阅quad的文档)。下面是一个快速而粗糙的演示:

In [32]: x0 = brentq(lambda x: x * np.cos(x) + np.sin(x), 1e-2, np.pi)

In [33]: quad(lambda x: -(x * np.sin(2*x)) / (x * np.cos(x) + np.sin(x) * (x - x0)), 1e-4, np.pi, weight='cauchy', wvar=x0)
Out[33]: (-4.14269240855162, 1.4398780224416236e-08)
  • 积分器需要奇点的位置,所以使用根查找器(brentq)来找到它。
  • 使用weight="cauchy"时,被积函数被解释为f(x)f(x) / (x - c)中。因此,计算出展开式并重新定义你的被积函数在x0周围。下面我乘以x - x0来代替。
  • 在x->0处存在0/0,所以最好重新定义你的integrand函数在零点。下面我只是在x=0处稍微偏离。
英文:

In general, integrator routines need a bit of help when dealing with singularities.

Here if you know you want a principal value, tell it to quad by using the weight="cauchy" (look up the docs for quad). Here's a quick-and-dirty demo:

In [32]: x0 = brentq(lambda x: x * np.cos(x) + np.sin(x), 1e-2, np.pi)

In [33]: quad(lambda x: -(x * np.sin(2*x)) / (x * np.cos(x) + np.sin(x) * (x - x0)), 1e-4, np.pi, weight='cauchy', wvar=x0)
Out[33]: (-4.14269240855162, 1.4398780224416236e-08)
  • The integrator needs a position of the singularity, so find it with a root-finder (brentq below)
  • with weight="cauchy" the integrand it interpreted as f(x) in f(x) / (x - c). Therefore, work out the expansion and redefine your integrand around x0. Below I multiply by x - x0 instead.
  • there is a 0/0 at x->0, so ideally redefine your integrand function at zero. Below I just step away out of x=0 instead.

答案2

得分: -2

scipy.integrate.quad函数是一个通用的积分器,在处理奇点或高度振荡的函数时可能会遇到困难。在您的情况下,您正在尝试对一个具有奇点的函数进行积分,这可能会导致IntegrationWarning或不准确的结果。

为了处理积分中的奇点,您可以使用柯西主值方法。以下是您代码的更新版本:

from scipy.integrate import quad
import numpy as np

def integrand(x):
    return -(x * np.sin(2*x)) / (x * np.cos(x) + np.sin(x))

def cauchy_principal_value(f, a, b, singular_point, **kwargs):
    def wrapped(x):
        if x == singular_point:
            return np.nan
        return f(x)
    
    integral = quad(wrapped, a, b, **kwargs)
    return integral

result = cauchy_principal_value(integrand, 0, np.pi, 2.0287665755744362)

print("Principal Value:", result[0])

在更新的代码中,引入了一个包装函数wrapped来处理奇点。包装函数对于奇点返回np.nan,以指示在该点积分被定义。**kwargs参数允许您传递额外的参数给quad函数(如果需要的话)。

通过使用这种方法,积分应该可以进行而不会引发IntegrationWarning。如果有效,请告诉我。

英文:

The scipy.integrate.quad function is a general-purpose integrator and may encounter difficulties when handling singularities or highly oscillatory functions. In your case, you are trying to integrate a function with a singularity, which can lead to IntegrationWarning or inaccurate results.

To handle the singularity in your integrand, you can use the Cauchy principal value method. Here's an updated version of your code:

from scipy.integrate import quad
import numpy as np

def integrand(x):
    return -(x * np.sin(2*x)) / (x * np.cos(x) + np.sin(x))

def cauchy_principal_value(f, a, b, singular_point, **kwargs):
    def wrapped(x):
        if x == singular_point:
            return np.nan
        return f(x)
    
    integral = quad(wrapped, a, b, **kwargs)
    return integral

result = cauchy_principal_value(integrand, 0, np.pi, 2.0287665755744362)

print("Principal Value:", result[0])

In the updated code, a wrapper function wrapped is introduced to handle the singularity. The wrapper function returns np.nan for the singular point to indicate that the integrand is not defined at that point. The **kwargs parameter allows you to pass additional arguments to the quad function if needed.

By using this approach, the integration should proceed without raising an IntegrationWarning. Let me know, if it works or not.

huangapple
  • 本文由 发表于 2023年6月1日 19:29:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381400.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定