【发布时间】:2018-07-25 16:00:37
【问题描述】:
我有这个实现矩形数值积分的 C++ 代码
#include <iostream>
#include <cmath>
using namespace std;
float pdf(float u){
return (1/(pow(1+u, 2)));
}
float cdf(float u){
return (1 - 1/(u+1));
}
// The main function that implements the numerical integration,
//and it is a recursive function
float integ(float h, int k, float du){
float res = 0;
if (k == 1){
res = cdf(h);
}else{
float u = 0;
while (u < h){
res += integ(h - u, k - 1, du)*pdf(u)*du;
u += du;
}
}
return res;
}
int main(){
float du = 0.0001;
int K = 3;
float gamma[4] = {0.31622777, 0.79432823,
1.99526231, 5.01187234};
int G = 50;
int Q = 2;
for (int i = 0; i < 4; i++){
if ((G-Q*(K-1)) > 0){
float gammath = (gamma[i]/Q)*(G-Q*(K-1));
cout<<1-integ(gammath, K, du)<< endl;
}
}
return 0;
}
虽然我从 Python 和 MATLAB 切换到 C++,但我遇到了速度问题,因为 C++ 更快。问题是我需要一个小步长 du 来获得对集成的准确评估。
基本上,我想评估 gammath 定义的 4 个不同点的积分,这是其他定义参数的函数。
无论如何我可以加快这个程序吗?我已经比 Python 中的相同代码获得了 25 倍以上的速度因子,但代码仍然花费了太长时间(我运行了一整夜,早上还没有完成)。这仅适用于 K=3 和 G=50。在其他情况下,我想测试 K = 10,G = 100 或 300。
提前感谢您的任何提示。
【问题讨论】:
-
codereview.stackexchange.com 可能更适合这个问题。
-
我注意到的一件事是
(G-Q*(K-1))在循环中,并且在循环的每次迭代中都有两次。将其排除在循环之外可能会有所帮助,但不确定有多少。 -
将
pow(u, 2)替换为(u*u)。 -
@RSahu 对,(G-Q*(K-1) 必须评估一次,但我认为这不会显着加快我的代码速度。我认为我需要在我的代码中进行一些算法更改可能让我再加速 25 倍。
-
在呈现的代码中仍然看不到它,不知道/关心它实际实现的算法:所有输入都是按值,唯一的返回是累积的,没有全局变量,但也许这就是 k=2 递归级别中特定 h 的优化/值重用范围在哪里?在 k=3 中,随着 u 增加到 h,k=2 要做的工作会减少,在我看来,k=3 的一些输入在某些递归路径上将是相同的。