- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑以下函数:
import numpy as np
from scipy.special import erf
def my_func(x):
return np.exp(x ** 2) * (1 + erf(x))
当我使用 scipy
的 quad
评估此函数从 -14
到 -4
的积分时函数,我得到以下结果:
In [3]: from scipy import integrate
In [4]: integrate.quad(my_func, -14, -4)
/usr/local/lib/python2.7/dist-packages/scipy/integrate/quadpack.py:289: UserWarning: The maximum number of subdivisions (50) has been achieved.
If increasing the limit yields no improvement it is advised to analyze
the integrand in order to determine the difficulties. If the position of a
local difficulty can be determined (singularity, discontinuity) one will
probably gain from splitting up the interval and calling the integrator
on the subranges. Perhaps a special-purpose integrator should be used.
warnings.warn(msg)
Out[4]: (0.21896647054443383, 0.00014334175850538866)
也就是说,大约 0.22
。
但是,当我将这个积分提交给 Wolfram Alpha 时,我得到了一个非常不同的结果:
-5.29326 X 10 ^ 69.
这是怎么回事?我猜这与 scipy
给我的警告有关。在 python
中评估此积分的最佳方法是什么?
注意:增加limit
会更改警告但保留scipy
结果不变:
In [5]: integrate.quad(my_func, -14, -4, limit=10000)
/usr/local/lib/python2.7/dist-packages/scipy/integrate/quadpack.py:289: UserWarning: The occurrence of roundoff error is detected, which prevents
the requested tolerance from being achieved. The error may be
underestimated.
warnings.warn(msg)
Out[5]: (0.21894780966717864, 1.989164129832358e-05)
最佳答案
TL;DR:被积函数等价于erfcx(-x)
,erfcx
的实现在scipy.special.erfcx
处理数值问题:
In [10]: from scipy.integrate import quad
In [11]: from scipy.special import erfcx
In [12]: quad(lambda x: erfcx(-x), -14, -4)
Out[12]: (0.6990732491815446, 1.4463494884581349e-13)
In [13]: quad(lambda x: erfcx(-x), -150, -50)
Out[13]: (0.6197754761443759, 4.165648376274775e-14)
您可以通过更改积分参数和限制的符号来避免 lambda
表达式:
In [14]: quad(erfcx, 4, 14)
Out[14]: (0.6990732491815446, 1.4463494884581349e-13)
问题是 1 + erf(x)
的负值 x
的数值计算。随着 x
减小,erf(x)
接近 -1。然后加 1,得到 catastrophic loss of precision ,并且对于足够负的 x
(特别是 x
< -5.87),1 + erf(x)
在数值上为 0。
请注意,Wolfram Alpha 的默认行为也存在同样的问题。我不得不点击“更多数字”两次才能得到合理的答案。
解决方法是重新表述您的函数。您可以将 1+erf(x)
表示为 2*ndtr(x*sqrt(2))
,其中 ndtr
是正态累积分布函数,可从 scipy.special.ndtr
获得(参见,例如,https://en.wikipedia.org/wiki/Error_function)。这是您的函数的替代版本,以及将其与 scipy.integrate.quad
集成的结果:
In [133]: def func2(x):
.....: return np.exp(x**2) * 2 * ndtr(x * np.sqrt(2))
.....:
In [134]: my_func(-5)
Out[134]: 0.1107029852258767
In [135]: func2(-5)
Out[135]: 0.11070463773306743
In [136]: integrate.quad(func2, -14, -4)
Out[136]: (0.6990732491815298, 1.4469372263470424e-13)
点击“更多数字”两次后 Wolfram Alpha 的答案是 0.6990732491815446...
这是使用数值稳定版本时函数图的样子:
为了避免具有非常大数量级的参数的溢出或下溢,您可以在对数空间中进行部分计算:
from scipy.special import log_ndtr
def func3(x):
t = x**2 + np.log(2) + log_ndtr(x * np.sqrt(2))
y = np.exp(t)
return y
例如
In [20]: quad(func3, -150, -50)
Out[20]: (0.6197754761435517, 4.6850379059597266e-14)
(看起来@ali_m 在新问题中打败了我:Tricking numpy/python into representing very large and very small numbers。)
最后,正如 Simon Byrne 在 Tricking numpy/python into representing very large and very small numbers 的回答中指出的那样,被积分的函数可以表示为erfcx(-x)
,其中erfcx
是缩放后的互补误差函数。可用形式为 scipy.special.erfcx
.
例如,
In [10]: from scipy.integrate import quad
In [11]: from scipy.special import erfcx
In [12]: quad(lambda x: erfcx(-x), -14, -4)
Out[12]: (0.6990732491815446, 1.4463494884581349e-13)
In [13]: quad(lambda x: erfcx(-x), -150, -50)
Out[13]: (0.6197754761443759, 4.165648376274775e-14)
关于python - Wolfram Alpha 和 scipy.integrate.quad 对同一个积分给出了不同的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32302231/
(function() { main(); function main() { jQuery(document).ready(function($) {
所以我必须为我们的类(class)软件设计制作一个 GUI,我们正在为 children 制作一个游戏来练习乘法表。到目前为止,当您执行一次测试或练习时它工作正常,但是当您进行第二次运行时,它会出错。
我刚开始学习 python,想做一些琐事。基本上,我想从列表中随机询问一个问题,然后使用“输入”运算符来判断用户输入的 Y/N 是否正确。我坚持确定如何检查它是否正确。也许我的(不正确的)代码可以更好
我目前正在做一个暑期实习项目,我必须制作一个不经意的 DNS 翻译服务器。我不会在这里详细讨论被忽视的部分,但我会解释我的程序的架构。 有一个服务器端接收混淆的请求并发回一个它自己无法理解的答案。 在
我想用ajax请求翻译单词到谷歌翻译 如果我使用 curl,它会像: curl_init("http://translate.google.com/translate_a/t?client=t&tex
这是我运行dig www.google.com时的答案部分: ;; ANSWER SECTION: www.google.com. 108 IN A 74
我在ES上有以下简单数据: curl -XPUT localhost:9200/dt/art/1 -d '{ "age": 77 }' curl -XPUT localhost:9200/dt/art
我从编码开始,我有一个多维数组的示例。但它没有给出预期的答案。 我只得到“C”,我期待“JohnnyCash:Live at Folsom Prison”。出了什么问题? var music = []
我们有一个应用程序与 Crashlytic 和 Answers 配合得很好。我们需要为这个应用程序做一个不同的风格。因此,我们的 Gradle 编译工作正常,并为两个不同的品牌制作了两个不同的 APK
我正在尝试从数据库获取歌曲列表。 我在查询行中发送一个 ID 数组(永久链接),并且我希望返回值的顺序与我在数组中给出的顺序相同。有没有办法做到这一点? function getByPermalink
我有一个表单可以输入这样的值 test 有没有办法用jquery改变输入类型 我基本上想把这个添加到输入类型中 data-slider="true" data-sl
好吧,我距离数学高手还很远。哎呀,我记住了足够多的高中代数,可以拼凑出任何有效的公式,这对我来说是一个胜利。因此,如果您注意到这里有一个不必要的长或令人困惑的公式,那就可以解释了。 但是,正如人们可以
所以我的问题有点令人困惑,但仍然如此。我从外部源获取一个由 8 个字符串组成的数组,其中所有字符串都包含 double 值。这些值通常为小数点后 4 位: 12345.5678 我想做的是将其转换为小
我成功地构建了一个函数来提示用户提出问题,然后是随机排列的答案选项。但是,由于答案选择现在是随机的,python 如何识别用户输入(数字:1、2、3 或 4)以获得“正确”答案? import ran
我正在尝试使用蛮力来回答这个问题,这样我就可以理解发生了什么: https://www.interviewcake.com/question/java/product-of-other-numbers
尝试使用刚刚宣布的 Answers OSX平台框架: pod 'Fabric' pod 'Answers' pod 'Crashlytics' #import #import #import [
在我添加的页面上检索忘记的用户名 步骤 1) 输入电子邮件地址(通过电子邮件获取帐户) 第 2 步)验证安全问题(他们提供答案,我对其进行验证) 第 3 步)向他们发送带有用户名的电子邮件 第 2 步
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
在我的测试中,我需要模拟一种情况,当使用实体管理器(em)将新对象保存到数据库中时,在此过程中,该对象的id属性设置为数据库中该行的自动递增ID。我想将该id属性设置为我自己的值,以便稍后在测试中进行
我有这个代码。调用askToContinue() 方法来询问用户是否要继续,但我的问题是它只是忽略选择并重新启动程序,无论我输入什么。我在代码中遗漏了什么导致它忽略我的选择? public class
我是一名优秀的程序员,十分优秀!