用 C++ (GSL) 解 ODEs
嗯.
记得那是2021年4月6日(周二, 清明节假期), 15:22. 我在吃饭. 有个师妹问我怎么用一个叫 GSL 的 C++ library 来解常微分方程组(ODEs). 我查了一下,
The GNU Scientific Library (GSL) is a numerical library for C and C++ programmers. It is free software under the GNU General Public License.
按 GSL 说明文档, GSL 是一个跟 scipy
类似的, 可用作科学计算的库. 任何科学计算的库的基本功能都是类似的, 所以这对我来说不是一个很大的问题. 奈何我有拖延症, 遇到师妹更是如此. 于是直到三个星期过后, 我才开始细看说明文档, 动笔写这篇文章.
闲话休题.
前置工作
我的操作系统是 windows 7, 前置工作大体有以下四个:
- 把
C++
安装在 windows 系统; - 把
GSL
安装在 windows 系统; - 安装
visual studio code
, 配置 C++ 的编程环境; - 配置
visual studio code
, 使之能正常调用 GSL .
这个过程说复杂其实也不复杂. 有机会出个 windows 版的安装教程.
这过程折腾了我6个小时... 从晚12点到晨6点. 其中编译安装 GSL 大概花了两个小时. 期间师妹多次喊我去睡觉, 我拒绝了.
待解 ODEs
跟 MATLAB
或 mathematica
相比, GSL
的 ODEs 求解过程有自己的风格. GSL
要求 ODEs 要写成如下的形式:
$$\frac{\text{d}y_i}{\text{d}t} = f_i(t, y_1,\cdots,y_n), $$
其中 $i=1,\cdots,n$. 初值条件为
$$y_1(t_0) = a_1, \cdots, y_n(t_0) = a_n.$$
求解过程中某些算法会用到 Jacobi 矩阵
$$J_{ij} = \frac{\partial f_i}{\partial y_j}(t, y_1,\cdots,y_n),$$
但并不是所有算法都需要. 故下文不对 Jacobi 矩阵的相关内容展开说明.
为了行文方便, 设待解的 ODEs 是
$$\frac{\text{d}y_1}{\text{d}t} = -y_2, \frac{\text{d}y_2}{\text{d}t} = y_1.$$
初值条件是
$$y_1(0) = 1, y_1(0) = 0.$$
显然, 该 ODEs 的唯一解是
$$y_1 = \cos t, y_2 = \sin t.$$
限制 $t\in[0, 2\pi]$. 最后可以检验数值解的准确性.
求解 ODEs (复杂版)
定义函数 $f_i$ 和矩阵 $J_{ij}$
GSL 对函数 $f_i$ 和矩阵 $J_{ij}$ 的封装形式有特定的要求.
函数 $f_i$ 的定义:
// 函数自变量是 y, 因变量储存在 f, 函数返回 GSL_SUCCESS (=0) 表示计算成功.
int func (double t, const double y[], double f[], void *params) {
(void)(t); // 假装用过变量 t. 缺少这部可能会在编译时报 warning.
double mu = *(double *)params; // 可通过 params 导入函数所需参数, 非必要.
f[0] = - mu*y[1];
f[1] = mu*y[0];
return GSL_SUCCESS; // GSL规定, 函数运行成功返回 GSL_SUCCESS, 类似返回 0.
}
Jacobi 矩阵 $J_{ij}$ 的定义:
// 某些步进函数需要用到 Jacobi 矩阵, 本文不需要用到.
int jac (double t, const double y[], double *dfdy, double dfdt[], void *params) {
double mu = *(double *)params;
gsl_matrix *m = gsl_matrix_alloc (2, 2);
gsl_matrix_set (m, 0, 0, 0.0);
gsl_matrix_set (m, 0, 1, -1.0*mu);
gsl_matrix_set (m, 1, 0, 1.0*mu);
gsl_matrix_set (m, 1, 1, 0.0);
dfdt[0] = 0.0;
dfdt[1] = 0.0;
return GSL_SUCCESS;
}
定义 ODEs 系统
ODEs 系统 (ODEs system) 是个由函数 $f_i$ , Jacobi 矩阵 $J_{ij}$, 方程维数 (dim
) 及相关参数 (params
) 构成的四元组 (4-tuple). 其中 Jacobi 矩阵和相关参数不是必需的.
// 定义 ODEs 系统
double mu = 1;
size_t dim = 2;
// gsl_odeiv2_system sys = {func, jac, 2, &mu}; // 本文不需要 Jacobi 矩阵
gsl_odeiv2_system sys = {func, NULL, dim, &mu};
定义步进函数
步进函数 (Stepping function) 确定解 ODEs 所涉及的算法. GSL
中所涉及的算法基本都是 Runge-Kutta 法, 不同的算法精度可能差异很大. 步进函数的相关说明如下:
步进函数是最底层的部件, 它能使得解从 $t$ 步进到 $t+h$, 其中 $h$ (相对)固定, 并估计结果的局部误差.
The lowest level components are the stepping functions which advance a solution from time $t$ to $t+h$ for a fixed step-size h and estimate the resulting local error.
步长 $h$ 在计算过程中给定, 这里不需要给定. 相关代码:
const gsl_odeiv2_step_type * T = gsl_odeiv2_step_rk2;
gsl_odeiv2_step * step = gsl_odeiv2_step_alloc (T, dim);
// gsl_odeiv2_step_rk8pd 表示求解 ODEs 所用的算法, 可以换成 gsl_odeiv2_step_type 类中别的算法, 其中有些算法要求 Jacobi 矩阵.
定义控制函数
控制函数 (control function) 是用来调控解的误差的, 使得解的误差落在一定范围内. 不同的控制函数控制不同类型的误差. 其的相关说明如下:
步进函数生成 (ODEs 的) 解, 而 (步长) 控制函数检验这些解(是否符合)给定的范围, 并尝试按用户给定的误差来确定最优的步长.
The control function examines the proposed change to the solution produced by a stepping function and attempts to determine the optimal step-size for a user-specified level of error.
相关代码:
// 定义控制函数, 总误差 = 绝对误差 + 相对误差
double eps_abs = 1e-3; // 绝对误差
double eps_rel = 0; // 相对误差
gsl_odeiv2_control * con = gsl_odeiv2_control_y_new (eps_abs, eps_rel);
定义演进函数
演进函数 (evolution function 进化函数? 这个该怎么翻译...) 是用来控制解的步进. 相关说明如下:
演化函数通过结合步进函数和控制函数, 以及给定的步长, 让解步进一步.
The evolution function combines the results of a stepping function and control function to reliably advance the solution forward one step using an acceptable step-size.
相关代码如下:
gsl_odeiv2_evolve * e = gsl_odeiv2_evolve_alloc (dim);
// dim 表示 ODEs 的维度.
//按说明文档, gsl_odeiv2_evolve 类似乎只有一个对象 gsl_odeiv2_evolve_alloc .
这步是计算前的最后准备, 相当于告诉计算机演进所涉及的 ODEs 是 $2$ 维的.
笔者不明白这一步的意义何在... 仅仅是告诉计算机方程的维数吗?
步进计算
有了上述准备, 便可以开始计算了.
由于 C++
无法直接返回数组, 因此 GSL
不像其他的科学计算库那样, 给定方程和条件就可以直接返回结果. GSL
只能实现用已知 ODEs 在 $t$ 处的值(初值), 来计算 $t+h$ 处的值. 显然 $h$ 的值不能过大或者过小. 要求 ODEs 在特定区间上的数值解, 还需要在外层套个循环.
相关代码
int status = gsl_odeiv2_evolve_apply_fixed_step(e, con, step, &sys, &t, h, y);
// status == 0 表示计算成功
// 计算结果储存在变量 t 和 y
完整代码和返回结果
完整代码如下:
#include <stdio.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
#include <math.h>
int func (double t, const double y[], double f[], void *params) {
(void)(t); // 没有用到 t, 避免某些 warning.
double mu = *(double *)params;
f[0] = - mu*y[1];
f[1] = mu*y[0];
return GSL_SUCCESS;
}
void print_one_step(int n, double t, double y[]){
// 打印计算结果
printf("step %d: t, y1, y2\n", n);
printf ("pred: %1.5f, %1.5f, %1.5f\n", t, y[0], y[1]); // 预测值
printf ("real: %1.5f, %1.5f, %1.5f\n\n", t, cos(t), sin(t)); // 真实值
}
int main(void){
// 定义 ODEs 系统
double mu = 1;
size_t dim = 2;
gsl_odeiv2_system sys = {func, NULL, dim, &mu};
//定义步进函数
const gsl_odeiv2_step_type * T = gsl_odeiv2_step_rk2;
gsl_odeiv2_step * step = gsl_odeiv2_step_alloc (T, dim);
// 定义控制函数, 总误差 = 绝对误差 + 相对误差
double eps_abs = 1e-3; // 绝对误差
double eps_rel = 0; // 相对误差
gsl_odeiv2_control * con = gsl_odeiv2_control_y_new (eps_abs, eps_rel);
// 定义演进函数
gsl_odeiv2_evolve * e = gsl_odeiv2_evolve_alloc (dim);
// 开始计算
double t = 0.0 ; // 初值
double t1 = 2*M_PI; // 终止值
double h = M_PI / 40; // 步长
double y[2] = { 1.0, 0.0 }; // 初值
int n = 0;
print_one_step(n, t, y);
while (t < t1) {
int status = gsl_odeiv2_evolve_apply_fixed_step(e, con, step, &sys, &t, h, y);
if (status != GSL_SUCCESS){
// 异常则退出计算
printf("error, status = %d\n", status);
break;
}
n ++;
print_one_step(n, t, y);
}
// 释放内存
gsl_odeiv2_step_free(step);
gsl_odeiv2_control_free(con);
gsl_odeiv2_evolve_free(e);
return 0;
}
返回结果如下:
step 0: t, y1, y2
pred: 0.00000, 1.00000, 0.00000
real: 0.00000, 1.00000, 0.00000
step 1: t, y1, y2
pred: 0.07854, 0.99692, 0.07846
real: 0.07854, 0.99692, 0.07846
step 2: t, y1, y2
pred: 0.15708, 0.98769, 0.15643
real: 0.15708, 0.98769, 0.15643
step 3: t, y1, y2
pred: 0.23562, 0.97237, 0.23344
real: 0.23562, 0.97237, 0.23345
step 4: t, y1, y2
pred: 0.31416, 0.95105, 0.30902
real: 0.31416, 0.95106, 0.30902
step 5: t, y1, y2
pred: 0.39270, 0.92387, 0.38268
real: 0.39270, 0.92388, 0.38268
step 6: t, y1, y2
pred: 0.47124, 0.89100, 0.45399
real: 0.47124, 0.89101, 0.45399
step 7: t, y1, y2
pred: 0.54978, 0.85263, 0.52249
real: 0.54978, 0.85264, 0.52250
step 8: t, y1, y2
pred: 0.62832, 0.80901, 0.58778
real: 0.62832, 0.80902, 0.58779
step 9: t, y1, y2
pred: 0.70686, 0.76039, 0.64944
real: 0.70686, 0.76041, 0.64945
step 10: t, y1, y2
pred: 0.78540, 0.70709, 0.70710
real: 0.78540, 0.70711, 0.70711
step 11: t, y1, y2
pred: 0.86394, 0.64944, 0.76039
real: 0.86394, 0.64945, 0.76041
step 12: t, y1, y2
pred: 0.94248, 0.58777, 0.80900
real: 0.94248, 0.58779, 0.80902
step 13: t, y1, y2
pred: 1.02102, 0.52249, 0.85262
real: 1.02102, 0.52250, 0.85264
step 14: t, y1, y2
pred: 1.09956, 0.45398, 0.89099
real: 1.09956, 0.45399, 0.89101
step 15: t, y1, y2
pred: 1.17810, 0.38267, 0.92386
real: 1.17810, 0.38268, 0.92388
step 16: t, y1, y2
pred: 1.25664, 0.30901, 0.95103
real: 1.25664, 0.30902, 0.95106
step 17: t, y1, y2
pred: 1.33518, 0.23344, 0.97234
real: 1.33518, 0.23345, 0.97237
step 18: t, y1, y2
pred: 1.41372, 0.15643, 0.98766
real: 1.41372, 0.15643, 0.98769
step 19: t, y1, y2
pred: 1.49226, 0.07845, 0.99689
real: 1.49226, 0.07846, 0.99692
step 20: t, y1, y2
pred: 1.57080, -0.00000, 0.99997
real: 1.57080, 0.00000, 1.00000
step 21: t, y1, y2
pred: 1.64934, -0.07846, 0.99688
real: 1.64934, -0.07846, 0.99692
step 22: t, y1, y2
pred: 1.72788, -0.15643, 0.98765
real: 1.72788, -0.15643, 0.98769
step 23: t, y1, y2
pred: 1.80642, -0.23344, 0.97233
real: 1.80642, -0.23345, 0.97237
step 24: t, y1, y2
pred: 1.88496, -0.30901, 0.95102
real: 1.88496, -0.30902, 0.95106
step 25: t, y1, y2
pred: 1.96350, -0.38267, 0.92384
real: 1.96350, -0.38268, 0.92388
step 26: t, y1, y2
pred: 2.04204, -0.45397, 0.89097
real: 2.04204, -0.45399, 0.89101
step 27: t, y1, y2
pred: 2.12058, -0.52248, 0.85260
real: 2.12058, -0.52250, 0.85264
step 28: t, y1, y2
pred: 2.19911, -0.58776, 0.80898
real: 2.19911, -0.58779, 0.80902
step 29: t, y1, y2
pred: 2.27765, -0.64942, 0.76037
real: 2.27765, -0.64945, 0.76041
step 30: t, y1, y2
pred: 2.35619, -0.70708, 0.70707
real: 2.35619, -0.70711, 0.70711
step 31: t, y1, y2
pred: 2.43473, -0.76037, 0.64941
real: 2.43473, -0.76041, 0.64945
step 32: t, y1, y2
pred: 2.51327, -0.80898, 0.58775
real: 2.51327, -0.80902, 0.58779
step 33: t, y1, y2
pred: 2.59181, -0.85260, 0.52247
real: 2.59181, -0.85264, 0.52250
step 34: t, y1, y2
pred: 2.67035, -0.89096, 0.45396
real: 2.67035, -0.89101, 0.45399
step 35: t, y1, y2
pred: 2.74889, -0.92383, 0.38266
real: 2.74889, -0.92388, 0.38268
step 36: t, y1, y2
pred: 2.82743, -0.95100, 0.30900
real: 2.82743, -0.95106, 0.30902
step 37: t, y1, y2
pred: 2.90597, -0.97231, 0.23343
real: 2.90597, -0.97237, 0.23345
step 38: t, y1, y2
pred: 2.98451, -0.98763, 0.15642
real: 2.98451, -0.98769, 0.15643
step 39: t, y1, y2
pred: 3.06305, -0.99686, 0.07845
real: 3.06305, -0.99692, 0.07846
step 40: t, y1, y2
pred: 3.14159, -0.99994, -0.00000
real: 3.14159, -1.00000, 0.00000
step 41: t, y1, y2
pred: 3.22013, -0.99685, -0.07846
real: 3.22013, -0.99692, -0.07846
step 42: t, y1, y2
pred: 3.29867, -0.98762, -0.15643
real: 3.29867, -0.98769, -0.15643
step 43: t, y1, y2
pred: 3.37721, -0.97230, -0.23343
real: 3.37721, -0.97237, -0.23345
step 44: t, y1, y2
pred: 3.45575, -0.95099, -0.30900
real: 3.45575, -0.95106, -0.30902
step 45: t, y1, y2
pred: 3.53429, -0.92381, -0.38266
real: 3.53429, -0.92388, -0.38268
step 46: t, y1, y2
pred: 3.61283, -0.89094, -0.45396
real: 3.61283, -0.89101, -0.45399
step 47: t, y1, y2
pred: 3.69137, -0.85257, -0.52246
real: 3.69137, -0.85264, -0.52250
step 48: t, y1, y2
pred: 3.76991, -0.80895, -0.58774
real: 3.76991, -0.80902, -0.58779
step 49: t, y1, y2
pred: 3.84845, -0.76034, -0.64940
real: 3.84845, -0.76041, -0.64945
step 50: t, y1, y2
pred: 3.92699, -0.70705, -0.70705
real: 3.92699, -0.70711, -0.70711
step 51: t, y1, y2
pred: 4.00553, -0.64939, -0.76035
real: 4.00553, -0.64945, -0.76041
step 52: t, y1, y2
pred: 4.08407, -0.58773, -0.80895
real: 4.08407, -0.58779, -0.80902
step 53: t, y1, y2
pred: 4.16261, -0.52245, -0.85257
real: 4.16261, -0.52250, -0.85264
step 54: t, y1, y2
pred: 4.24115, -0.45395, -0.89093
real: 4.24115, -0.45399, -0.89101
step 55: t, y1, y2
pred: 4.31969, -0.38265, -0.92380
real: 4.31969, -0.38268, -0.92388
step 56: t, y1, y2
pred: 4.39823, -0.30898, -0.95097
real: 4.39823, -0.30902, -0.95106
step 57: t, y1, y2
pred: 4.47677, -0.23342, -0.97228
real: 4.47677, -0.23345, -0.97237
step 58: t, y1, y2
pred: 4.55531, -0.15641, -0.98760
real: 4.55531, -0.15643, -0.98769
step 59: t, y1, y2
pred: 4.63385, -0.07845, -0.99682
real: 4.63385, -0.07846, -0.99692
step 60: t, y1, y2
pred: 4.71239, 0.00001, -0.99991
real: 4.71239, 0.00000, -1.00000
step 61: t, y1, y2
pred: 4.79093, 0.07846, -0.99682
real: 4.79093, 0.07846, -0.99692
step 62: t, y1, y2
pred: 4.86947, 0.15643, -0.98759
real: 4.86947, 0.15643, -0.98769
step 63: t, y1, y2
pred: 4.94801, 0.23343, -0.97227
real: 4.94801, 0.23345, -0.97237
step 64: t, y1, y2
pred: 5.02655, 0.30899, -0.95096
real: 5.02655, 0.30902, -0.95106
step 65: t, y1, y2
pred: 5.10509, 0.38265, -0.92378
real: 5.10509, 0.38268, -0.92388
step 66: t, y1, y2
pred: 5.18363, 0.45395, -0.89091
real: 5.18363, 0.45399, -0.89101
step 67: t, y1, y2
pred: 5.26217, 0.52245, -0.85255
real: 5.26217, 0.52250, -0.85264
step 68: t, y1, y2
pred: 5.34071, 0.58773, -0.80893
real: 5.34071, 0.58779, -0.80902
step 69: t, y1, y2
pred: 5.41925, 0.64938, -0.76032
real: 5.41925, 0.64945, -0.76041
step 70: t, y1, y2
pred: 5.49779, 0.70703, -0.70702
real: 5.49779, 0.70711, -0.70711
step 71: t, y1, y2
pred: 5.57633, 0.76033, -0.64937
real: 5.57633, 0.76041, -0.64945
step 72: t, y1, y2
pred: 5.65487, 0.80893, -0.58771
real: 5.65487, 0.80902, -0.58779
step 73: t, y1, y2
pred: 5.73341, 0.85255, -0.52243
real: 5.73341, 0.85264, -0.52250
step 74: t, y1, y2
pred: 5.81195, 0.89091, -0.45393
real: 5.81195, 0.89101, -0.45399
step 75: t, y1, y2
pred: 5.89049, 0.92377, -0.38263
real: 5.89049, 0.92388, -0.38268
step 76: t, y1, y2
pred: 5.96903, 0.95094, -0.30897
real: 5.96903, 0.95106, -0.30902
step 77: t, y1, y2
pred: 6.04757, 0.97225, -0.23341
real: 6.04757, 0.97237, -0.23345
step 78: t, y1, y2
pred: 6.12611, 0.98757, -0.15641
real: 6.12611, 0.98769, -0.15643
step 79: t, y1, y2
pred: 6.20465, 0.99679, -0.07844
real: 6.20465, 0.99692, -0.07846
step 80: t, y1, y2
pred: 6.28319, 0.99987, 0.00001
real: 6.28319, 1.00000, 0.00000
求解 ODEs (简化版)
驱动器 (driver) 可以把上述的步进函数, 控制函数, 演进函数打包, 用起来更加方便. 下面利用驱动器的写法, 把上述例子重写一遍.
定义驱动器
相关代码如下:
const gsl_odeiv2_step_type * T = gsl_odeiv2_step_rk2; // 算法
double h = M_PI / 40; // 步长
double eps_abs = 1e-3; // 绝对误差
double eps_rel = 0; // 相对误差
gsl_odeiv2_driver *d = gsl_odeiv2_driver_alloc_y_new (&sys, T, h, eps_abs, eps_rel); // 定义驱动器, sys 是 ODEs 系统.
完整代码和返回结果
完整代码如下:
#include <stdio.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
#include <math.h>
int func (double t, const double y[], double f[], void *params) {
(void)(t);
double mu = *(double *)params;
f[0] = - mu*y[1];
f[1] = mu*y[0];
return GSL_SUCCESS;
}
void print_one_step(int n, double t, double y[]){
// 打印计算结果
printf("step %d: t, y1, y2\n", n);
printf ("pred: %1.5f, %1.5f, %1.5f\n", t, y[0], y[1]); // 预测值
printf ("real: %1.5f, %1.5f, %1.5f\n\n", t, cos(t), sin(t)); // 真实值
}
int main(void){
// 定义 ODEs 系统
double mu = 1;
size_t dim = 2;
gsl_odeiv2_system sys = {func, NULL, dim, &mu};
const gsl_odeiv2_step_type * T = gsl_odeiv2_step_rk2; // 算法
double h = M_PI / 40; // 步长
double eps_abs = 1e-3; // 绝对误差
double eps_rel = 0; // 相对误差
gsl_odeiv2_driver *d = gsl_odeiv2_driver_alloc_y_new (&sys, T, h, eps_abs, eps_rel);
double t = 0;
double t1 = 2*M_PI;
double y[] = {1, 0};
int n = 0;
print_one_step(n, t, y);
while (t < t1) {
int status = gsl_odeiv2_driver_apply(d, &t, t + h, y);
if (status != GSL_SUCCESS){
// 异常则退出计算
printf("error, status = %d\n", status);
break;
}
n++;
print_one_step(n, t, y);
}
gsl_odeiv2_driver_free(d);
return 0;
}
返回结果如下:
step 0: t, y1, y2
pred: 0.00000, 1.00000, 0.00000
real: 0.00000, 1.00000, 0.00000
step 1: t, y1, y2
pred: 0.07854, 0.99692, 0.07846
real: 0.07854, 0.99692, 0.07846
step 2: t, y1, y2
pred: 0.15708, 0.98769, 0.15643
real: 0.15708, 0.98769, 0.15643
step 3: t, y1, y2
pred: 0.23562, 0.97237, 0.23344
real: 0.23562, 0.97237, 0.23345
step 4: t, y1, y2
pred: 0.31416, 0.95105, 0.30902
real: 0.31416, 0.95106, 0.30902
step 5: t, y1, y2
pred: 0.39270, 0.92387, 0.38268
real: 0.39270, 0.92388, 0.38268
step 6: t, y1, y2
pred: 0.47124, 0.89100, 0.45399
real: 0.47124, 0.89101, 0.45399
step 7: t, y1, y2
pred: 0.54978, 0.85263, 0.52249
real: 0.54978, 0.85264, 0.52250
step 8: t, y1, y2
pred: 0.62832, 0.80901, 0.58778
real: 0.62832, 0.80902, 0.58779
step 9: t, y1, y2
pred: 0.70686, 0.76039, 0.64944
real: 0.70686, 0.76041, 0.64945
step 10: t, y1, y2
pred: 0.78540, 0.70709, 0.70710
real: 0.78540, 0.70711, 0.70711
step 11: t, y1, y2
pred: 0.86394, 0.64944, 0.76039
real: 0.86394, 0.64945, 0.76041
step 12: t, y1, y2
pred: 0.94248, 0.58777, 0.80900
real: 0.94248, 0.58779, 0.80902
step 13: t, y1, y2
pred: 1.02102, 0.52249, 0.85262
real: 1.02102, 0.52250, 0.85264
step 14: t, y1, y2
pred: 1.09956, 0.45398, 0.89099
real: 1.09956, 0.45399, 0.89101
step 15: t, y1, y2
pred: 1.17810, 0.38267, 0.92386
real: 1.17810, 0.38268, 0.92388
step 16: t, y1, y2
pred: 1.25664, 0.30901, 0.95103
real: 1.25664, 0.30902, 0.95106
step 17: t, y1, y2
pred: 1.33518, 0.23344, 0.97234
real: 1.33518, 0.23345, 0.97237
step 18: t, y1, y2
pred: 1.41372, 0.15643, 0.98766
real: 1.41372, 0.15643, 0.98769
step 19: t, y1, y2
pred: 1.49226, 0.07845, 0.99689
real: 1.49226, 0.07846, 0.99692
step 20: t, y1, y2
pred: 1.57080, -0.00000, 0.99997
real: 1.57080, 0.00000, 1.00000
step 21: t, y1, y2
pred: 1.64934, -0.07846, 0.99688
real: 1.64934, -0.07846, 0.99692
step 22: t, y1, y2
pred: 1.72788, -0.15643, 0.98765
real: 1.72788, -0.15643, 0.98769
step 23: t, y1, y2
pred: 1.80642, -0.23344, 0.97233
real: 1.80642, -0.23345, 0.97237
step 24: t, y1, y2
pred: 1.88496, -0.30901, 0.95102
real: 1.88496, -0.30902, 0.95106
step 25: t, y1, y2
pred: 1.96350, -0.38267, 0.92384
real: 1.96350, -0.38268, 0.92388
step 26: t, y1, y2
pred: 2.04204, -0.45397, 0.89097
real: 2.04204, -0.45399, 0.89101
step 27: t, y1, y2
pred: 2.12058, -0.52248, 0.85260
real: 2.12058, -0.52250, 0.85264
step 28: t, y1, y2
pred: 2.19911, -0.58776, 0.80898
real: 2.19911, -0.58779, 0.80902
step 29: t, y1, y2
pred: 2.27765, -0.64942, 0.76037
real: 2.27765, -0.64945, 0.76041
step 30: t, y1, y2
pred: 2.35619, -0.70708, 0.70707
real: 2.35619, -0.70711, 0.70711
step 31: t, y1, y2
pred: 2.43473, -0.76037, 0.64941
real: 2.43473, -0.76041, 0.64945
step 32: t, y1, y2
pred: 2.51327, -0.80898, 0.58775
real: 2.51327, -0.80902, 0.58779
step 33: t, y1, y2
pred: 2.59181, -0.85260, 0.52247
real: 2.59181, -0.85264, 0.52250
step 34: t, y1, y2
pred: 2.67035, -0.89096, 0.45396
real: 2.67035, -0.89101, 0.45399
step 35: t, y1, y2
pred: 2.74889, -0.92383, 0.38266
real: 2.74889, -0.92388, 0.38268
step 36: t, y1, y2
pred: 2.82743, -0.95100, 0.30900
real: 2.82743, -0.95106, 0.30902
step 37: t, y1, y2
pred: 2.90597, -0.97231, 0.23343
real: 2.90597, -0.97237, 0.23345
step 38: t, y1, y2
pred: 2.98451, -0.98763, 0.15642
real: 2.98451, -0.98769, 0.15643
step 39: t, y1, y2
pred: 3.06305, -0.99686, 0.07845
real: 3.06305, -0.99692, 0.07846
step 40: t, y1, y2
pred: 3.14159, -0.99994, -0.00000
real: 3.14159, -1.00000, 0.00000
step 41: t, y1, y2
pred: 3.22013, -0.99685, -0.07846
real: 3.22013, -0.99692, -0.07846
step 42: t, y1, y2
pred: 3.29867, -0.98762, -0.15643
real: 3.29867, -0.98769, -0.15643
step 43: t, y1, y2
pred: 3.37721, -0.97230, -0.23343
real: 3.37721, -0.97237, -0.23345
step 44: t, y1, y2
pred: 3.45575, -0.95099, -0.30900
real: 3.45575, -0.95106, -0.30902
step 45: t, y1, y2
pred: 3.53429, -0.92381, -0.38266
real: 3.53429, -0.92388, -0.38268
step 46: t, y1, y2
pred: 3.61283, -0.89094, -0.45396
real: 3.61283, -0.89101, -0.45399
step 47: t, y1, y2
pred: 3.69137, -0.85257, -0.52246
real: 3.69137, -0.85264, -0.52250
step 48: t, y1, y2
pred: 3.76991, -0.80895, -0.58774
real: 3.76991, -0.80902, -0.58779
step 49: t, y1, y2
pred: 3.84845, -0.76034, -0.64940
real: 3.84845, -0.76041, -0.64945
step 50: t, y1, y2
pred: 3.92699, -0.70705, -0.70705
real: 3.92699, -0.70711, -0.70711
step 51: t, y1, y2
pred: 4.00553, -0.64939, -0.76035
real: 4.00553, -0.64945, -0.76041
step 52: t, y1, y2
pred: 4.08407, -0.58773, -0.80895
real: 4.08407, -0.58779, -0.80902
step 53: t, y1, y2
pred: 4.16261, -0.52245, -0.85257
real: 4.16261, -0.52250, -0.85264
step 54: t, y1, y2
pred: 4.24115, -0.45395, -0.89093
real: 4.24115, -0.45399, -0.89101
step 55: t, y1, y2
pred: 4.31969, -0.38265, -0.92380
real: 4.31969, -0.38268, -0.92388
step 56: t, y1, y2
pred: 4.39823, -0.30898, -0.95097
real: 4.39823, -0.30902, -0.95106
step 57: t, y1, y2
pred: 4.47677, -0.23342, -0.97228
real: 4.47677, -0.23345, -0.97237
step 58: t, y1, y2
pred: 4.55531, -0.15641, -0.98760
real: 4.55531, -0.15643, -0.98769
step 59: t, y1, y2
pred: 4.63385, -0.07845, -0.99682
real: 4.63385, -0.07846, -0.99692
step 60: t, y1, y2
pred: 4.71239, 0.00001, -0.99991
real: 4.71239, 0.00000, -1.00000
step 61: t, y1, y2
pred: 4.79093, 0.07846, -0.99682
real: 4.79093, 0.07846, -0.99692
step 62: t, y1, y2
pred: 4.86947, 0.15643, -0.98759
real: 4.86947, 0.15643, -0.98769
step 63: t, y1, y2
pred: 4.94801, 0.23343, -0.97227
real: 4.94801, 0.23345, -0.97237
step 64: t, y1, y2
pred: 5.02655, 0.30899, -0.95096
real: 5.02655, 0.30902, -0.95106
step 65: t, y1, y2
pred: 5.10509, 0.38265, -0.92378
real: 5.10509, 0.38268, -0.92388
step 66: t, y1, y2
pred: 5.18363, 0.45395, -0.89091
real: 5.18363, 0.45399, -0.89101
step 67: t, y1, y2
pred: 5.26217, 0.52245, -0.85255
real: 5.26217, 0.52250, -0.85264
step 68: t, y1, y2
pred: 5.34071, 0.58773, -0.80893
real: 5.34071, 0.58779, -0.80902
step 69: t, y1, y2
pred: 5.41925, 0.64938, -0.76032
real: 5.41925, 0.64945, -0.76041
step 70: t, y1, y2
pred: 5.49779, 0.70703, -0.70702
real: 5.49779, 0.70711, -0.70711
step 71: t, y1, y2
pred: 5.57633, 0.76033, -0.64937
real: 5.57633, 0.76041, -0.64945
step 72: t, y1, y2
pred: 5.65487, 0.80893, -0.58771
real: 5.65487, 0.80902, -0.58779
step 73: t, y1, y2
pred: 5.73341, 0.85255, -0.52243
real: 5.73341, 0.85264, -0.52250
step 74: t, y1, y2
pred: 5.81195, 0.89091, -0.45393
real: 5.81195, 0.89101, -0.45399
step 75: t, y1, y2
pred: 5.89049, 0.92377, -0.38263
real: 5.89049, 0.92388, -0.38268
step 76: t, y1, y2
pred: 5.96903, 0.95094, -0.30897
real: 5.96903, 0.95106, -0.30902
step 77: t, y1, y2
pred: 6.04757, 0.97225, -0.23341
real: 6.04757, 0.97237, -0.23345
step 78: t, y1, y2
pred: 6.12611, 0.98757, -0.15641
real: 6.12611, 0.98769, -0.15643
step 79: t, y1, y2
pred: 6.20465, 0.99679, -0.07844
real: 6.20465, 0.99692, -0.07846
step 80: t, y1, y2
pred: 6.28319, 0.99987, 0.00001
real: 6.28319, 1.00000, 0.00000
提高解的精度
笔者发现, 只要把上述的 gsl_odeiv2_step_rk2
算法换成 gsl_odeiv2_step_rk8pd
, 其余不变, 就能达到很高的精度. 笔者同样不清楚其中的原理.
完整代码
#include <stdio.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
#include <math.h>
int func (double t, const double y[], double f[], void *params) {
(void)(t);
double mu = *(double *)params;
f[0] = - mu*y[1];
f[1] = mu*y[0];
return GSL_SUCCESS;
}
void print_one_step(int n, double t, double y[]){
// 打印计算结果
printf("step %d: t, y1, y2\n", n);
printf ("pred: %1.19f, %1.19f, %1.19f\n", t, y[0], y[1]); // 预测值
printf ("real: %1.19f, %1.19f, %1.19f\n\n", t, cos(t), sin(t)); // 真实值
}
int main(void){
// 定义 ODEs 系统
double mu = 1;
size_t dim = 2;
gsl_odeiv2_system sys = {func, NULL, dim, &mu};
const gsl_odeiv2_step_type * T = gsl_odeiv2_step_rk8pd; // 算法
double h = M_PI / 40; // 步长
double eps_abs = 1e-3; // 绝对误差
double eps_rel = 0; // 相对误差
gsl_odeiv2_driver *d = gsl_odeiv2_driver_alloc_y_new (&sys, T, h, eps_abs, eps_rel);
double t = 0;
double t1 = 2*M_PI;
double y[] = {1, 0};
int n = 0;
print_one_step(n, t, y);
while (t < t1) {
int status = gsl_odeiv2_driver_apply(d, &t, t + h, y);
if (status != GSL_SUCCESS){
// 异常则退出计算
printf("error, status = %d\n", status);
break;
}
n++;
print_one_step(n, t, y);
}
gsl_odeiv2_driver_free(d);
return 0;
}
返回结果
step 0: t, y1, y2
pred: 0.0000000000000000000, 1.0000000000000000000, 0.0000000000000000000
real: 0.0000000000000000000, 1.0000000000000000000, 0.0000000000000000000
step 1: t, y1, y2
pred: 0.0785398163397448280, 0.9969173337331279600, 0.0784590957278449440
real: 0.0785398163397448280, 0.9969173337331279600, 0.0784590957278449440
step 2: t, y1, y2
pred: 0.1570796326794896600, 0.9876883405951376600, 0.1564344650402308400
real: 0.1570796326794896600, 0.9876883405951377700, 0.1564344650402308700
step 3: t, y1, y2
pred: 0.2356194490192344800, 0.9723699203976765600, 0.2334453638559053600
real: 0.2356194490192344800, 0.9723699203976765600, 0.2334453638559053900
step 4: t, y1, y2
pred: 0.3141592653589793100, 0.9510565162951535300, 0.3090169943749473400
real: 0.3141592653589793100, 0.9510565162951535300, 0.3090169943749474000
step 5: t, y1, y2
pred: 0.3926990816987241400, 0.9238795325112867400, 0.3826834323650896700
real: 0.3926990816987241400, 0.9238795325112867400, 0.3826834323650897800
step 6: t, y1, y2
pred: 0.4712388980384689700, 0.8910065241883679000, 0.4539904997395466400
real: 0.4712388980384689700, 0.8910065241883679000, 0.4539904997395467500
step 7: t, y1, y2
pred: 0.5497787143782138000, 0.8526401643540922900, 0.5224985647159486900
real: 0.5497787143782138000, 0.8526401643540921800, 0.5224985647159488000
step 8: t, y1, y2
pred: 0.6283185307179586200, 0.8090169943749474500, 0.5877852522924729200
real: 0.6283185307179586200, 0.8090169943749474500, 0.5877852522924731400
step 9: t, y1, y2
pred: 0.7068583470577034500, 0.7604059656000309300, 0.6494480483301834400
real: 0.7068583470577034500, 0.7604059656000309300, 0.6494480483301836600
step 10: t, y1, y2
pred: 0.7853981633974482800, 0.7071067811865475700, 0.7071067811865473500
real: 0.7853981633974482800, 0.7071067811865475700, 0.7071067811865474600
step 11: t, y1, y2
pred: 0.8639379797371931100, 0.6494480483301837700, 0.7604059656000307100
real: 0.8639379797371931100, 0.6494480483301836600, 0.7604059656000309300
step 12: t, y1, y2
pred: 0.9424777960769379300, 0.5877852522924732500, 0.8090169943749472300
real: 0.9424777960769379300, 0.5877852522924731400, 0.8090169943749474500
step 13: t, y1, y2
pred: 1.0210176124166828000, 0.5224985647159490200, 0.8526401643540920700
real: 1.0210176124166828000, 0.5224985647159489100, 0.8526401643540921800
step 14: t, y1, y2
pred: 1.0995574287564276000, 0.4539904997395469700, 0.8910065241883676800
real: 1.0995574287564276000, 0.4539904997395468000, 0.8910065241883677900
step 15: t, y1, y2
pred: 1.1780972450961724000, 0.3826834323650899500, 0.9238795325112866300
real: 1.1780972450961724000, 0.3826834323650898400, 0.9238795325112867400
step 16: t, y1, y2
pred: 1.2566370614359172000, 0.3090169943749476200, 0.9510565162951534200
real: 1.2566370614359172000, 0.3090169943749474500, 0.9510565162951535300
step 17: t, y1, y2
pred: 1.3351768777756621000, 0.2334453638559056400, 0.9723699203976764500
real: 1.3351768777756621000, 0.2334453638559054700, 0.9723699203976765600
step 18: t, y1, y2
pred: 1.4137166941154069000, 0.1564344650402311200, 0.9876883405951375500
real: 1.4137166941154069000, 0.1564344650402309200, 0.9876883405951377700
step 19: t, y1, y2
pred: 1.4922565104551517000, 0.0784590957278452210, 0.9969173337331278500
real: 1.4922565104551517000, 0.0784590957278449990, 0.9969173337331279600
step 20: t, y1, y2
pred: 1.5707963267948966000, 0.0000000000000002914, 0.9999999999999998900
real: 1.5707963267948966000, 0.0000000000000000612, 1.0000000000000000000
step 21: t, y1, y2
pred: 1.6493361431346414000, -0.0784590957278446380, 0.9969173337331278500
real: 1.6493361431346414000, -0.0784590957278448740, 0.9969173337331279600
step 22: t, y1, y2
pred: 1.7278759594743862000, -0.1564344650402305400, 0.9876883405951376600
real: 1.7278759594743862000, -0.1564344650402308100, 0.9876883405951377700
step 23: t, y1, y2
pred: 1.8064157758141310000, -0.2334453638559050900, 0.9723699203976765600
real: 1.8064157758141310000, -0.2334453638559053400, 0.9723699203976766700
step 24: t, y1, y2
pred: 1.8849555921538759000, -0.3090169943749471200, 0.9510565162951535300
real: 1.8849555921538759000, -0.3090169943749473400, 0.9510565162951536400
step 25: t, y1, y2
pred: 1.9634954084936207000, -0.3826834323650894500, 0.9238795325112867400
real: 1.9634954084936207000, -0.3826834323650897300, 0.9238795325112867400
step 26: t, y1, y2
pred: 2.0420352248333655000, -0.4539904997395464700, 0.8910065241883679000
real: 2.0420352248333655000, -0.4539904997395466900, 0.8910065241883679000
step 27: t, y1, y2
pred: 2.1205750411731104000, -0.5224985647159485800, 0.8526401643540922900
real: 2.1205750411731104000, -0.5224985647159488000, 0.8526401643540922900
step 28: t, y1, y2
pred: 2.1991148575128552000, -0.5877852522924728000, 0.8090169943749475600
real: 2.1991148575128552000, -0.5877852522924730300, 0.8090169943749474500
step 29: t, y1, y2
pred: 2.2776546738526000000, -0.6494480483301833300, 0.7604059656000311500
real: 2.2776546738526000000, -0.6494480483301835500, 0.7604059656000310400
step 30: t, y1, y2
pred: 2.3561944901923448000, -0.7071067811865472400, 0.7071067811865477900
real: 2.3561944901923448000, -0.7071067811865474600, 0.7071067811865475700
step 31: t, y1, y2
pred: 2.4347343065320897000, -0.7604059656000306000, 0.6494480483301839900
real: 2.4347343065320897000, -0.7604059656000309300, 0.6494480483301837700
step 32: t, y1, y2
pred: 2.5132741228718345000, -0.8090169943749471200, 0.5877852522924734700
real: 2.5132741228718345000, -0.8090169943749473400, 0.5877852522924732500
step 33: t, y1, y2
pred: 2.5918139392115793000, -0.8526401643540919600, 0.5224985647159492400
real: 2.5918139392115793000, -0.8526401643540921800, 0.5224985647159489100
step 34: t, y1, y2
pred: 2.6703537555513241000, -0.8910065241883675700, 0.4539904997395471900
real: 2.6703537555513241000, -0.8910065241883677900, 0.4539904997395468600
step 35: t, y1, y2
pred: 2.7488935718910690000, -0.9238795325112865200, 0.3826834323650902300
real: 2.7488935718910690000, -0.9238795325112867400, 0.3826834323650898900
step 36: t, y1, y2
pred: 2.8274333882308138000, -0.9510565162951534200, 0.3090169943749479000
real: 2.8274333882308138000, -0.9510565162951535300, 0.3090169943749475100
step 37: t, y1, y2
pred: 2.9059732045705586000, -0.9723699203976764500, 0.2334453638559058900
real: 2.9059732045705586000, -0.9723699203976765600, 0.2334453638559055300
step 38: t, y1, y2
pred: 2.9845130209103035000, -0.9876883405951375500, 0.1564344650402313700
real: 2.9845130209103035000, -0.9876883405951376600, 0.1564344650402309800
step 39: t, y1, y2
pred: 3.0630528372500483000, -0.9969173337331278500, 0.0784590957278454710
real: 3.0630528372500483000, -0.9969173337331279600, 0.0784590957278450680
step 40: t, y1, y2
pred: 3.1415926535897931000, -0.9999999999999998900, 0.0000000000000005412
real: 3.1415926535897931000, -1.0000000000000000000, 0.0000000000000001225
step 41: t, y1, y2
pred: 3.2201324699295379000, -0.9969173337331278500, -0.0784590957278443880
real: 3.2201324699295379000, -0.9969173337331279600, -0.0784590957278448190
step 42: t, y1, y2
pred: 3.2986722862692828000, -0.9876883405951376600, -0.1564344650402302900
real: 3.2986722862692828000, -0.9876883405951377700, -0.1564344650402307300
step 43: t, y1, y2
pred: 3.3772121026090276000, -0.9723699203976765600, -0.2334453638559048100
real: 3.3772121026090276000, -0.9723699203976766700, -0.2334453638559052800
step 44: t, y1, y2
pred: 3.4557519189487724000, -0.9510565162951535300, -0.3090169943749467900
real: 3.4557519189487724000, -0.9510565162951536400, -0.3090169943749472800
step 45: t, y1, y2
pred: 3.5342917352885173000, -0.9238795325112867400, -0.3826834323650891200
real: 3.5342917352885173000, -0.9238795325112868500, -0.3826834323650896700
step 46: t, y1, y2
pred: 3.6128315516282621000, -0.8910065241883679000, -0.4539904997395461400
real: 3.6128315516282621000, -0.8910065241883679000, -0.4539904997395466900
step 47: t, y1, y2
pred: 3.6913713679680069000, -0.8526401643540922900, -0.5224985647159482400
real: 3.6913713679680069000, -0.8526401643540922900, -0.5224985647159486900
step 48: t, y1, y2
pred: 3.7699111843077517000, -0.8090169943749475600, -0.5877852522924724700
real: 3.7699111843077517000, -0.8090169943749475600, -0.5877852522924730300
step 49: t, y1, y2
pred: 3.8484510006474966000, -0.7604059656000311500, -0.6494480483301829900
real: 3.8484510006474966000, -0.7604059656000310400, -0.6494480483301835500
step 50: t, y1, y2
pred: 3.9269908169872414000, -0.7071067811865477900, -0.7071067811865469100
real: 3.9269908169872414000, -0.7071067811865476800, -0.7071067811865474600
step 51: t, y1, y2
pred: 4.0055306333269858000, -0.6494480483301843200, -0.7604059656000300400
real: 4.0055306333269858000, -0.6494480483301841000, -0.7604059656000306000
step 52: t, y1, y2
pred: 4.0840704496667311000, -0.5877852522924734700, -0.8090169943749467900
real: 4.0840704496667311000, -0.5877852522924732500, -0.8090169943749473400
step 53: t, y1, y2
pred: 4.1626102660064763000, -0.5224985647159489100, -0.8526401643540918500
real: 4.1626102660064763000, -0.5224985647159485800, -0.8526401643540924000
step 54: t, y1, y2
pred: 4.2411500823462216000, -0.4539904997395464700, -0.8910065241883676800
real: 4.2411500823462216000, -0.4539904997395461400, -0.8910065241883682300
step 55: t, y1, y2
pred: 4.3196898986859669000, -0.3826834323650890600, -0.9238795325112867400
real: 4.3196898986859669000, -0.3826834323650886700, -0.9238795325112871800
step 56: t, y1, y2
pred: 4.3982297150257121000, -0.3090169943749462900, -0.9510565162951536400
real: 4.3982297150257121000, -0.3090169943749459000, -0.9510565162951540900
step 57: t, y1, y2
pred: 4.4767695313654574000, -0.2334453638559038600, -0.9723699203976766700
real: 4.4767695313654574000, -0.2334453638559034200, -0.9723699203976771100
step 58: t, y1, y2
pred: 4.5553093477052027000, -0.1564344650402289000, -0.9876883405951377700
real: 4.5553093477052027000, -0.1564344650402284300, -0.9876883405951381000
step 59: t, y1, y2
pred: 4.6338491640449480000, -0.0784590957278425430, -0.9969173337331278500
real: 4.6338491640449480000, -0.0784590957278420290, -0.9969173337331281900
step 60: t, y1, y2
pred: 4.7123889803846932000, 0.0000000000000028311, -0.9999999999999996700
real: 4.7123889803846932000, 0.0000000000000033690, -1.0000000000000000000
step 61: t, y1, y2
pred: 4.7909287967244385000, 0.0784590957278481770, -0.9969173337331274100
real: 4.7909287967244385000, 0.0784590957278487460, -0.9969173337331276300
step 62: t, y1, y2
pred: 4.8694686130641838000, 0.1564344650402344800, -0.9876883405951368800
real: 4.8694686130641838000, 0.1564344650402350600, -0.9876883405951371000
step 63: t, y1, y2
pred: 4.9480084294039290000, 0.2334453638559093600, -0.9723699203976753400
real: 4.9480084294039290000, 0.2334453638559099700, -0.9723699203976755600
step 64: t, y1, y2
pred: 5.0265482457436743000, 0.3090169943749516700, -0.9510565162951518700
real: 5.0265482457436743000, 0.3090169943749522800, -0.9510565162951519800
step 65: t, y1, y2
pred: 5.1050880620834196000, 0.3826834323650942800, -0.9238795325112845200
real: 5.1050880620834196000, 0.3826834323650949400, -0.9238795325112846300
step 66: t, y1, y2
pred: 5.1836278784231649000, 0.4539904997395515200, -0.8910065241883651200
real: 5.1836278784231649000, 0.4539904997395521300, -0.8910065241883651200
step 67: t, y1, y2
pred: 5.2621676947629101000, 0.5224985647159536800, -0.8526401643540888500
real: 5.2621676947629101000, 0.5224985647159543500, -0.8526401643540888500
step 68: t, y1, y2
pred: 5.3407075111026554000, 0.5877852522924780200, -0.8090169943749434500
real: 5.3407075111026554000, 0.5877852522924786900, -0.8090169943749433400
step 69: t, y1, y2
pred: 5.4192473274424007000, 0.6494480483301885400, -0.7604059656000262700
real: 5.4192473274424007000, 0.6494480483301892100, -0.7604059656000261600
step 70: t, y1, y2
pred: 5.4977871437821459000, 0.7071067811865523500, -0.7071067811865421300
real: 5.4977871437821459000, 0.7071067811865530100, -0.7071067811865420200
step 71: t, y1, y2
pred: 5.5763269601218912000, 0.7604059656000355900, -0.6494480483301775500
real: 5.5763269601218912000, 0.7604059656000362600, -0.6494480483301774400
step 72: t, y1, y2
pred: 5.6548667764616365000, 0.8090169943749517800, -0.5877852522924663600
real: 5.6548667764616365000, 0.8090169943749525600, -0.5877852522924661400
step 73: t, y1, y2
pred: 5.7334065928013818000, 0.8526401643540962900, -0.5224985647159413600
real: 5.7334065928013818000, 0.8526401643540969500, -0.5224985647159411400
step 74: t, y1, y2
pred: 5.8119464091411270000, 0.8910065241883715600, -0.4539904997395386400
real: 5.8119464091411270000, 0.8910065241883722300, -0.4539904997395383100
step 75: t, y1, y2
pred: 5.8904862254808723000, 0.9238795325112899600, -0.3826834323650809600
real: 5.8904862254808723000, 0.9238795325112906200, -0.3826834323650805700
step 76: t, y1, y2
pred: 5.9690260418206176000, 0.9510565162951562000, -0.3090169943749380100
real: 5.9690260418206176000, 0.9510565162951567500, -0.3090169943749375100
step 77: t, y1, y2
pred: 6.0475658581603629000, 0.9723699203976785600, -0.2334453638558954000
real: 6.0475658581603629000, 0.9723699203976791100, -0.2334453638558948400
step 78: t, y1, y2
pred: 6.1261056745001081000, 0.9876883405951389900, -0.1564344650402203200
real: 6.1261056745001081000, 0.9876883405951395500, -0.1564344650402197100
step 79: t, y1, y2
pred: 6.2046454908398534000, 0.9969173337331284100, -0.0784590957278338970
real: 6.2046454908398534000, 0.9969173337331288500, -0.0784590957278332310
step 80: t, y1, y2
pred: 6.2831853071795987000, 0.9999999999999995600, 0.0000000000000114908
real: 6.2831853071795987000, 1.0000000000000000000, 0.0000000000000121896
评论已关闭