- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 GMP 包来实现两个函数的乘积,我表示为两个收敛级数的柯西乘积。
更详细地说:我正在寻找一种方法来计算 f(x)=g(x)*h(x)
其中 g(x)
是指数函数,h(x)
是一个特殊的超几何函数(见下文),均表示为级数。
我的问题是这行得通并且与我自己的近似值和 wolframalpha 对 x<29
的结果一致, 但因 x>29
而失败.在实践中,我需要大约 x=10^6
的值.
我使用的 3 个公式如下图所示:
代码
void invfak(mpf_t invn, unsigned int n) //Calculates inverse factorial, !/n!
{
unsigned int i;
mpf_t k;
mpf_init_set_d(k,1.0);
mpf_init_set_d(invn,0.0);
i=2;
for (i = 2; i <= n; ++i) {
mpf_mul_ui(k, k, i);
}
mpf_ui_div(invn,1.0,k);
mpf_clear(k);
}
void E2F2E(mpf_t result, long double x, unsigned int N)
{
mpf_t Q1,Q2; ///gives Nth term in series expansion of exp(x)
mpf_init_set_d(Q1,x);
mpf_init_set_d(Q2,0.0);
mpf_init_set_d(result,0.0);
mpf_pow_ui(Q1,Q1,N); /// Q1=Q1^N=x^N
invfak(Q2,N); /// Q2=1/N!
mpf_mul(result,Q1,Q2); ///result= Q1*Q2 = x^N/N!
mpf_clear(Q1);
mpf_clear(Q2);
}
void E2F2F(mpf_t result, long double x, unsigned int N)
{
mpf_t Q1,Q2,Q3; ///gives Nth term in series expansion of 2F2
mpf_init_set_d(Q1,(N+x)*(N+x));
mpf_init_set_d(Q2,-x);
mpf_init_set_d(Q3,0.0);
mpf_init_set_d(result,0.0);
mpf_pow_ui(Q2,Q2,N+2); /// Q2=Q2^(N+2)=(-x)^(N+2)
invfak(Q3,N); /// Q3=1/N!
mpf_mul(Q2,Q2,Q3); /// Q2=Q2*Q3
mpf_div(result,Q2,Q1); ///result= Q2/Q1 = .../(N+x)^2
mpf_clear(Q1); mpf_clear(Q3); mpf_clear(Q2)
}
void Exp2F2gmp(mpf_t result, long double x, unsigned int N)
{
mpf_t Q1,Qexp,Q2F2,Qsum;
mpf_init_set_d(Q1,0.0);
mpf_init_set_d(Qexp,0.0);
mpf_init_set_d(Q2F2,0.0);
mpf_init_set_d(Qsum,0.0);
mpf_init_set_d(result,0.0);
for(unsigned i = 0; i <= N; ++i){
mpf_set_d(Qsum,0.0);
mpf_set_d(Qexp,0.0);
mpf_set_d(Q2F2,0.0);
for(unsigned l = 0; l <= i; ++l){ /// a_l und b_i-l
E2F2E(Qexp,x,l);
E2F2F(Q2F2,x,i-l);
mpf_mul(Q1,Qexp,Q2F2);
mpf_add(Qsum,Qsum,Q1);
}
mpf_add(result,result,Qsum);
mpf_abs(Qsum,Qsum);
//if(mpf_cmp_d(Qsum,0.00000001)==-1){ cout << "reached precision at i="<<i; break;}
}
cout << "\n\n Result = " << result << endl;
mpf_clear(Q1);
mpf_clear(Qexp);
mpf_clear(Q2F2);
mpf_clear(Qsum);
}
函数f(x)
应该大约为 f(x)=1.05x+1
还有,f(x)>0
对于 x>0
.
但是实现给出了这个:
Exp2F2gmp(Q,10,1000) = 12.3707
Exp2F2gmp(Q,20,1000) = 23.1739
Exp2F2gmp(Q,30,1000) = -35195.1
Exp2F2gmp(Q,40,1000) = -2.92079e+13
前两个值与 Wolframalpha 一致,后两个显然不一致。
如有任何帮助,我们将不胜感激,谢谢!
最佳答案
这是灾难性取消的教科书示例。
2F2 系列中的项增长到最大大小约为 exp(x),但 2F2 函数的大小约为 exp(-x)。这意味着您至少需要使用 log_2(exp(2x)) ~= 2.886*x 额外的精度位来准确计算 2F2 级数,并且可能略多一些,具体取决于项的计算方式。
例如,如果 x = 29,则需要大约 83 位的精度。您的代码使用 MPF 类型的默认精度,我认为它类似于 64 位。您需要更改代码以将所有 MPF 变量的精度设置为 64 + 2.886*x 位以获得 64 位精确位(有关如何执行此操作,请参阅 GMP 手册)。
在实践中,您实现的系列评估效率不高,并且对于 x = 1e6 可能太慢。
一种可能是使用 Arb库(我开发的)。这支持开箱即用地计算广义超几何函数,并使用更高效的级数评估策略(在本例中,使用二进制拆分)。它还使用区间算法,因此您可以免费获得误差范围,并且可以自动设置精度,而不是提前预测所需的精度(但在这种情况下,预测精度很容易,而且速度更快)。
下面是演示如何使用它的代码:
#include "acb_hypgeom.h"
int main()
{
acb_t z, t;
acb_struct a[2];
acb_struct b[2];
double x;
acb_init(z); acb_init(t);
acb_init(a + 0); acb_init(a + 1);
acb_init(b + 0); acb_init(b + 1);
for (x = 10.0; x <= 1000000; x *= 10)
{
acb_set_d(a + 0, x);
acb_set_d(a + 1, x);
acb_set_d(b + 0, x + 1);
acb_set_d(b + 1, x + 1);
acb_set_d(z, -x);
acb_hypgeom_pfq(t, a, 2, b, 2, z, 0, 64 + 2.886 * x);
acb_neg(z, z);
acb_exp(z, z, 64);
acb_mul(t, t, z, 64);
printf("f(%f) = ", x); acb_printn(t, 20, 0); printf("\n");
}
acb_clear(z); acb_clear(t);
acb_clear(a + 0); acb_clear(a + 1);
acb_clear(b + 0); acb_clear(b + 1);
}
这是输出:
f(10.000000) = [12.37067931727649929 +/- 5.38e-18]
f(100.000000) = [106.6161729468899444 +/- 4.93e-17]
f(1000.000000) = [1020.154983574938368 +/- 3.54e-16]
f(10000.000000) = [10063.00061277849954 +/- 2.57e-15]
f(100000.000000) = [100198.5001942224819 +/- 6.28e-14]
f(1000000.000000) = [1000626.990558714621 +/- 4.59e-13]
在 x = 1e6 时,由于使用了 290 万位,计算大约需要 20 秒(您的代码会花费很长时间)。如果这仍然太慢,您需要找到一个更好的公式来计算 f(x),理想情况下是一个在 x -> 无穷大时有效的渐近展开,或者可能是一个积分表示(如果没有取消问题)。
现在,如果你的 2F2 函数只依赖于最后一个参数中的 x 并且前四个参数是固定的,那么这个渐近展开会有一个标准公式,但是随着涉及的参数越来越多,我不确定如何去做吧。由于上参数和下参数几乎“抵消”,因此将它们视为常量并使用关于参数的标准渐近级数可能会起作用,但我没有检查这一点。在渐近分析方面具有更多专业知识的人必须发表评论。
您也可以使用连续关系将 2F2 函数简化为参数较小的函数,但我不确定这是否会在实践中有所改进。
关于c++ - GMP 给出了一系列扩展的错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43121211/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!