使用GSL解决大型ODE系统

时间:2018-10-12 15:01:03

标签: c++ ode gsl

我有一个普遍的问题,就是我不能缠住我的头,也不确定这是否是一个合适的地方。目前我一无所知,欢迎任何文献和建议。 我个人讨厌GSL,因为它们的示例完全无济于事,而对不同求解器的解释太笼统且缺少示例。 另一个有点烦人的地方是,每个GSL函数都需要一个指向其参数的指针,这迫使许多用户创建混乱的结构,但是(我认为)最巧妙的方法是创建一个类并简单地发送 this < / strong>指向它并使用reinterpet_cast(params)的指针-我从一位同事那里听说后得知了这一点,在任何GSL示例中都绝对没有,初学者也不自然地想到它。

无论如何,我的问题是如何解决矩阵形式的一阶ODE系统? 我有一个以矩阵形式给出的900个一阶ODE的系统,

y'=M*y

其中M是系统的900x900矩阵。系统由复数组成,我正在使用矩阵M的犰狳库。我认为我的问题中的复数也可能很棘手,但是我认为GSL具有某些功能,或者可以通过分离实部和虚部来完成。

我的整个代码都是C ++,我通常在稳态下解决此问题(有一个标准化技巧,可以简单地将M取反,并避免det(M)= 0),但是我不知道如何使用GSL做到这一点。那里的帮助页面根本没有帮助(因为它是针对二阶ODE的)。我非常了解ODE求解器在Matlab中的工作方式,我看到了GSL版本背后的逻辑,但是我的问题是我需要将整个系统作为矩阵传递,而且我不知道如何获得Jacobian(如果我需要的话)它)。到目前为止,我发现的所有示例都采用非常小的系统,在该系统中写下系统非常简单。 有人可以解释一下GSL的ode函数是如何推广到矩阵方法的吗?我认为它可能像把这样简单:

int odefunc (double t, const double y[], double f[], void *params)
{
    p = reinterpert_cast<Whatever_class *>(params)
    cx_mat M = p->get_matrix_M();
    f=M*y; %Probably does not work since M is armadillo matrix and f needs 
            to be accessed as f[i]
    return GSL_SUCCESS;
}

幸运的是,时间t不在方程中显示,因此可以通过特征值和特征向量更简单地解决此问题,但我真的很想知道如何使用GSL来实现。

对于我的问题,我实际上必须做的是将耦合系统求解为:

y'=M(x)*y
x'=G(y,t);
幸运的是,第一系统M的矩阵取决于另一个变量x,该变量x也取决于时间,仅取决于一个微分方程。 问题是我真的想避免淘汰系统。 G(y,t)非常复杂,需要将向量y整形为矩阵,并使用另一个(恒定)矩阵寻找其踪迹,因此,只有在知道y是什么的情况下,我才能计算G(y,t)。类似地,M(x)是通过非常复杂的矩阵变换(Khatri-Rao和Kronecker张量积)生成的。对我来说很明显,解向量应为[y; x],但我不了解如何以GSL需要的方式填充系统。

是否可以通过GSL执行此操作,或者是否需要为此开发自定义数值方法?

0 个答案:

没有答案