谁能确认我(欧拉法)对这些常微分方程的实现?

Can anyone confirm my (eulers method) implementation of these ordinary differential equations?

我正在尝试使用 Euler 方法在 C 中实现这些方程(Matsuoka 的振荡器 - 此处有详细信息 http://www.ecila.org/ecila_files/content/papers/ACEICMC05.pdf)。我意识到 Euler 不是最准确的方法,但它在我开发时消除了一些复杂性,一旦我完成了这项工作,我计划切换到 Runge Kutta。 这是我的实现,但我无法复制论文中的结果,所以我确定我有问题。但是代码翻了多少遍都找不到。

是否有人能够查看此代码并确认我的工作,或发现任何错误?

#define POSPART(X)  X > 0.0 ? X : 0.0

double matsuoka_calc_nextVal(double in, double t1, double t2,
                          double c, double b, double g,
                          double *x1, double *x2,
                          double *v1, double *v2, double step)
{
    double posX1 = POSPART(*x1); 
    double posX2 = POSPART(*x2);
    double posIn = POSPART(in);


    // calculate derivatives
    double dx1 = (c - *x1 - (b*(*v1)) - (g*posX2) - posIn) / t1;
    double dx2 = (c - *x2 - (b*(*v2)) - (g*posX1) - posIn) / t1;
    double dv1 = (posX1 - *v1) / t2;
    double dv2 = (posX2 - *v2) / t2;

    // increment value by 1 euler step (using eulerStep =0.2 in testing)
    *x1 += dx1 * eulerStep;         
    *x2 += dx2 * eulerStep;
    *v1 += dv1 * eulerStep;         
    *v2 += dv2 * eulerStep;
    return POSPART(*x1) - POSPART(*x2);

}

宏的定义

#define POSPART(X)  X > 0.0 ? X : 0.0

错了。

例如,如果您写

POSPART(1.0) - POSPART(1.0)

这扩展为

1.0 > 0.0 ? 1.0 : 0.0 - 1.0 > 0.0 ? 1.0 : 0.0

这相当于

(1.0 > 0.0) ? 1.0 : (((0.0 - 1.0) > 0.0) ? 1.0 : 0.0)

因此,POSPART(1.0) - POSPART(1.0) 被计算为 1.0,因为 1.0 > 0.0 为真。

为了避免这样的麻烦,你应该像这样包含参数和函数式宏的整个表达式:

#define POSPART(X)  ((X) > 0.0 ? (X) : 0.0)

在这种情况下应该可以,但是像 POSPART(x += 1.0) 这样的东西不会很好地工作,因为 x += 1.0 可能会被计算两次。 在这种情况下应该使用函数。