使用 GSL 减少 ODE 系统的编译资源

Reducing compile resources using GSL for an ODE system

我正在使用 C++ 和 GSL(Gnu 科学库)来集成具有 4503 个方程的大型 ODE 系统。由于系统很僵硬,我需要为积分设置雅可比行列式,结果矩阵大约有 2000 万个条目。

要初始化 ODE 系统和 Jacobian,GSL 需要使用具有特定签名的函数,即

int system(double t, const double y[], double dydt[], void *params);
int jac (double t, const double y[], double *dfdy, double dfdt[], void *params);

其中 dydt[]*dfdy 分别是系统和雅可比矩阵的数组。

我在两个单独的 .cpp 文件中声明了这些函数。对于系统,我有类似

的东西
// ODESystem.cpp

int system(double t, const double y[], double dydt[], void *params) {
    (void)(t);
    double l = *(static_cast<double*>(params));

    dydt[0] = 0;

    // lots of assignment statements like the above

    return GSL_SUCCESS;
}

对于雅可比矩阵,我有类似的东西

// ODEJacobian.cpp

int jacobian(double t, const double y[], double *dfdy, double dfdt[], void *params) {
    (void)(t);
    (void)(y);
    double l = *(static_cast<double*>(params));

    dfdy[0] = 0;

    // lots of assignment statements like the above

    return GSL_SUCCESS;
}

到目前为止,GCC 能够很好地处理 ODESystem.cpp,但是编译 ODEJacobian.cpp 需要很长时间(大约 45Gs 的 ram),(我猜,由于这个怪物中赋值操作的表达式树的大小,这是可以理解的)但它最终没有错误或警告。

Clang 似乎无法处理函数的大小,当它正常退出时,它会发出有关 "reaching the end of a non void function and finding no return statement" 的警告,在我看来,好像 clang "gives up" 在雅可比函数结束。然而,对于较小的尺寸(大约 5,745,609 个分配),Clang 可以正常工作并且不会发出警告。

我的问题是:在这种情况下,可以做些什么来减少编译 Jacobian 矩阵所需的资源量(时间和内存),同时遵守 GSL 对 GCC 和 Clang(或两者)施加的约束?

不要为此写作业。而是将数据复制到数组中。

我建议在程序启动时先将文件中的值读取到 std::vector<double> vec; 中。然后您可以继续重复使用其内容。这也使得在不重新编译的情况下修改值变得更容易,并且编译器不必做那么多不必要的工作。

然后

std::copy(vec.begin(), vec.end(), dydt);

std::copy 需要 #include<algorithm>std::vector 需要 #include<vector>