【发布时间】:2011-10-09 16:57:10
【问题描述】:
我正在尝试使用自适应梯形规则来近似积分。
我有一个粗略的积分近似:
//Approximates the integral of f across the interval [a,b]
double coarse_app(double(*f)(double x), double a, double b) {
return (b - a) * (f(a) + f(b)) / 2.0;
}
我有一个很好的积分近似:
//Approximates the integral of f across the interval [a,b]
double fine_app(double(*f)(double x), double a, double b) {
double m = (a + b) / 2.0;
return (b - a) / 4.0 * (f(a) + 2.0 * f(m) + f(b));
}
这是通过对给定间隔的递减部分的近似求和来实现自适应的,直到递归级别太高或粗略和精细近似彼此非常接近:
//Adaptively approximates the integral of f across the interval [a,b] with
// tolerance tol.
double trap(double(*f)(double x), double a, double b, double tol) {
double q = fine_app(f, a, b);
double r = coarse_app(f, a, b);
if ((currentLevel >= minLevel) && (abs(q - r) <= 3.0 * tol)) {
return q;
} else if (currentLevel >= maxLevel) {
return q;
} else {
++currentLevel;
return (trap(f, a, b / 2.0, tol / 2.0) + trap(f, a + (b / 2.0), b, tol / 2.0));
}
}
如果我通过将积分分解为多个部分并在其上使用fine_app 来手动计算积分,我会得到一个非常好的近似值。但是,当我使用应该为我执行此操作的陷阱功能时,我的所有结果都太小了。
例如,trap(square, 0, 2.0, 1.0e-2) 给出输出 0.0424107,其中 square 函数定义为 x^2。但是,输出应该在 2.667 左右。这比在整个时间间隔上执行一次fine_app 差得多,它的值是 3。
从概念上讲,我相信我已经正确实现了它,但是关于 C++ 递归的某些东西并没有达到我的预期。
第一次使用 C++ 编程,因此欢迎所有改进。
【问题讨论】:
-
currentLevel 在哪里定义?我在您的代码中看不到它。如果它是一个全局变量,那么你做错了什么。
-
是的,我将 currentLevel 定义为全局变量。谢谢你的回答,在下面。我会更彻底地看一遍。