改进的欧拉格式
梯形格式
首先来看梯形格式
因为显式欧拉格式和隐式欧拉格式的局部截断误差分别为
Ri=h22y′′(ξ) R_i = \frac{h^2}{2}y^{''}(\xi) Ri=2h2y′′(ξ)
Ri=−h22y′′(ξ) R_i =- \frac{h^2}{2}y^{''}(\xi)Ri=−2h2y′′(ξ)
由中点欧拉格式平均的思想,我们设想将显式欧拉格式和隐式欧拉格式平均,则可将误差相抵消,得到下式
yi+1=yi+h2[f(xi,yi)+f(xx+1,yi+1)] y_{i+1} = y_i + \frac{h}{2}[f(x_i,y_i)+f(x_{x+1},y_{i+1})]yi+1=yi+2h[f(xi,yi)+f(xx+1,yi+1)]
即梯形格式, 从几何上看梯形格式是取[xi,xi+1][x_i,x_{i+1}][xi,xi+1]两端点的平均斜率,具有二阶精度O(h2)O(h^2)O(h2)
改进的欧拉格式
- 先用欧拉格式求一个初步近似yi+1y_{i+1}yi+1 为预测值
- 再用梯形格式对它进行一次校正
写成平均化的形式:
{yp=yi+hf(xi,yi)yc=yi+hf(xi+1,yp)yi+1=12(yp+yc)(i=0,1,2,...,n−1) \left\{
\begin{array}{lcl}
y_p &=& y_i + hf(x_i, y_i)\\
y_c&=&y_i + hf(x_{i+1},y_p)\\
y_{i+1}& =& \frac{1}{2}(y_p+y_c)\\
&&(i = 0,1,2,...,n-1)
\end{array}
\right.
⎩⎪⎪⎨⎪⎪⎧ypycyi+1===yi+hf(xi,yi)yi+hf(xi+1,yp)21(yp+yc)(i=0,1,2,...,n−1)
代码如下
#include <iostream>
double f(double x, double y){
return y - (2 * x / y);
}
int main(int argc, const char * argv[]) {
double a, b, n, alpha;
std::cout<<"请依次输入待估区间[a,b],步数n,初值条件y0"<<std::endl;
std::cin>>a>>b>>n>>alpha;
double h = (b - a) / n;
double x0 = a;
double y0 = alpha;
double x1;
double yp;
double yc;
double y1;
for (int i = 0; i < n; ++i) {
x1 = x0 + h;
yp = y0 + h * f(x0, y0);
yc = y0 + h * f(x1, yp);
y1 = (yp + yc) / 2;
std::cout<<x1<<" "<<y1<<std::endl;
x0 = x1;
y0 = y1;
}
return 0;
}