Boost.Math和gcc的数学特殊函数ellint_3()
的实现
给出不同的结果。两者都不对,对吗?
即将推出的C ++标准实现应该是正确的,最好是在第一次尝试时。
我的问题是:如何?
特殊功能std::ellint_3(k,nu,phi)
,std::comp_ellint_3(k,nu)
在gcc的实现中
(live example):
const auto pi = std::acos(-1.0);
const auto k = 0.0;
std::cout << "nu\tincomp.\tcompl.\texpect\n";
for (auto nu : {-0.9, -0.5, 0.0, 0.5, 0.9})
{
auto expected = pi/(2*std::sqrt(1-nu));
std::cout
<< nu << '\t'
<< std::ellint_3(k, nu, pi/2) << '\t'
<< std::comp_ellint_3(k, nu) << '\t'
<< expected << '\n';
}
和他们的std::tr1
等价物
(live example)
为参数nu
的非零值提供不正确的结果:
nu incomp. compl. expect
-0.9 4.96729 4.96729 1.13958
-0.5 2.22144 2.22144 1.28255
0 1.5708 1.5708 1.5708
0.5 1.28255 1.28255 2.22144
0.9 1.13958 1.13958 4.96729
结果
Boost.Math
boost::math::ellint_3()
在gcc和clang似乎是正确的
(live example:)
nu incomp. expect
-0.9 1.13958 1.13958
-0.5 1.28255 1.28255
0 1.5708 1.5708
0.5 2.22144 2.22144
0.9 4.96729 4.96729
TR1,Boost库,ISO 29124,C ++ 17草案中的文档,
en.cppreference.org
和gcc实施ellint_3(k,nu,phi)
和comp_ellint_3(k,nu)
的文档评论
一贯地提到的定义
elliptic integral of the 3rd kind
(为方便起见,此处调整了参数顺序/约定)
以拉格朗日形式给出 Abramowitz,Milton&amp; Stegun,Irene:数学函数手册。 (1964)。
对于k=0
和phi=pi/2
,整数简化为pi/(2*sqrt(1-nu))
:
根据 (Bronstein,§1.1.3,no.311,312,german 24th edn,Leipzig 1989) 和 Wolfram Alpha
然而,存在另一个具有相反符号的定义(参数的顺序为了一致性而改变)
参考 Carlsson, Press, W. et al.: Numerical Recipes in C, eq. 6.11.21, p.261。
这些“加号源”也给出了提示, 如何使用Carlson的积分R_F和R_J来实现这些函数。
因此,根据root.cern.ch,一些图书馆选择“加号”进行实施,而其他图书馆则采取额外措施采用“减号”:
Gcc bug report 66689 和testcases 似乎表明,gcc采取(错误的?)决定在GSL上定位。
是否有一种(建设性的)摆脱这种混乱并选择“权利的右侧”? 乍一看,这似乎是一个基于意见的问题, 但是关于真相应该没有基于意见的答案,或者 至少,正确的文档。
顺便说一下,为这种不便而道歉,并感谢所有<*)))<
。