我对 C++ 比较陌生,但我有一些(稀缺的)编码和数字经验。
我知道这个问题时不时地发布,你如何集成一个数组。在 MATLAB 中,你可以强制你的数组成为一个函数(我忘了怎么做,但我知道我以前做过)并将它发送给内置的积分器,所以我的问题是你如何在 C++ 中做到这一点。
我有这个积分:
I = integral(A(z)*sin(qz)*dz)
q 只是 double const,z 是积分变量,但 A(z) 是一个数组(我从现在开始将其称为实际函数),它与我的代码中的 z 轴具有相同数量的点。积分边界是 z[0] 和 z[nz-1]。
我使用梯形规则计算了这个积分,对于 5000 点的 z 轴,这需要 0.06 秒。我的问题是这个计算大约发生了 300 * 30 * 20 次(我有 3 个 for 循环),这个 0.06 秒的时间很快增长到模拟的 3 小时。我的代码的整个瓶颈就是这种集成(我显然可以通过减少 z 来加速,但这不是重点。)
我知道库函数通常比用户编写的函数要好得多。我也知道我不能像辛普森规则那样使用更简单的东西,因为被积函数是高度振荡的,我想避免自己实现一些复杂的数值算法。
GSL 需要一个函数形式:
F = f(double x, void *params)
我可能可以使用 gsl 的 QAWO 自适应集成,但是如何使我的函数以将我的数组转换为函数的形式出现?
我在想一些事情:
F(double z, void *params)
{
std::valarray<double> actualfunction = *(std::valarray<double> *) params;
double dz = *(double *) params; // Pretty sure this is wrong
unsigned int actual_index = z / dz; // crazy assumption (my z[0] was 0)
return actualfunction[actual_index];
}
这样的事情可能吗?我怀疑数值算法会使用与实际函数相同的空间差异,然后我应该以某种方式对实际函数进行插值吗?
有比gsl更好的东西吗?