如何将 std::valarray<double> 与 gsl 集成?
How to integrate std::valarray<double> with gsl?
我对C++相对较新,但我有一些(稀缺的(编码和数值经验。
我知道这个问题时不时地发布,你如何集成一个数组。在 MATLAB 中,您可以强制将数组作为一个函数(我忘记了如何,但我知道我以前做过(并将其发送给内置集成器,所以我的问题是如何在C++中做到这一点。
我有这个积分:
I = integral(A(z)*sin(qz)*dz)
q 只是双常量,z 是积分变量,但 A(z( 是一个数组(从现在开始我称之为 actualfunction(,在我的代码中具有与 z 轴相同的点数。积分边界是 z[0] 和 z[nz-1]。
我使用梯形规则计算了这个积分,对于 5000 点的 z 轴,这需要 0.06 秒。我的问题是这个计算大约发生了 300 * 30 * 20 次(我有 3 个 for 循环(,而这个 0.06 秒非常快地增长到 3 小时的模拟。我的代码的整个瓶颈就是这种集成(我显然可以通过减少 z 来加速,但这不是重点。
我知道库函数通常比用户编写的函数好得多。我也知道我不能用更简单的东西作为辛普森规则,因为积分是高度振荡的,我想避免我自己实现一些复杂的数值算法。
GSL需要一个形式的函数:
F = f(双精度 x,空 *参数(
我可能可以使用 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更好的东西吗?
template<class F>
struct func_ptr_helper {
F f;
void* pvoid(){ return std::addressof(f); }
template<class R, class...Args>
using before_ptr=R(*)(void*,Args...);
template<class R, class...Args>
using after_ptr=R(*)(Args...,void*);
template<class R, class...Args>
static before_ptr<R,Args...> before_func() {
return [](void* p, Args...args)->R{
return (*static_cast<F*>(p))(std::forward<Args>(args)...);
};
}
template<class R, class...Args>
static after_ptr<R,Args...> after_func() {
return [](Args...args, void* p)->R{
return (*static_cast<F*>(p))(std::forward<Args>(args)...);
};
}
};
template<class F>
func_ptr_helper<F> lambda_to_pfunc( F f ){ return {std::move(f)}; }
用:
auto f = lambda_to_pfunc([&actualfunction, &dz](double z){
unsigned int actual_index = z / dz; // crazy assumption (my z[0] was 0)
return actualfunction[actual_index];
});
然后
void* pvoid - f.pvoid();
void(*pfun)(double, void*) = f.after_func();
你可以通过pfun
和pvoid
。
对于任何错别字,我们深表歉意。
这个想法是我们编写一个 lambda 来做我们想做的事。 然后lambda_to_pfunc
将其包装起来,以便我们可以将其作为void*
和函数指针传递给 C 样式的 API。
当然,您必须正确管理所有内容的生命周期。
- 将公共但非静态的成员函数与ALGLIB集成
- 将IBM Rhapsody模型集成到VS 2019中
- 从R调用C++函数并对其进行集成时出错
- EASTL矢量<向量<int>>连续的
- 如何集成 HID USB 控制器?
- 在VS2019项目中集成ImageMagick:x64-windows-static library
- 将Qt集成到现有的VS项目中以取代WinAPI
- 将 Crashpad 与 Windows Qt 应用程序集成
- Python3.6 模板中的 CGAL C++ 集成错误
- 基本 Cuda C++项目集成问题
- 如何使用CMake将QtMultimedia组件集成到项目中?
- 在 Mac OS 中将 QT 与 CMAKE 集成
- 使用 GSL 库制作样条曲线并使用它们进行集成
- 在集成终端上运行vscode lldb调试器时,如何获取程序的输出?
- 将Emscripten集成到Clion中
- VIsual Studio:避免控制台弹出,而是将其集成到IDE中
- 如何在electrolon项目中集成qt原生窗口
- 与 boost odeint 集成期间的析构函数调用
- C++uWebSockets将事件循环集成到一个线程中
- C++ 项目在 Jenkins 中的持续集成