英文:
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 asf(x)
inf(x) / (x - c)
. Therefore, work out the expansion and redefine your integrand aroundx0
. Below I multiply byx - x0
instead. - there is a 0/0 at x->0, so ideally redefine your
integrand
function at zero. Below I just step away out ofx=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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论