这是我所做的,它通过使用一步 RK 找到 3 个第一个值,但随后我有一些问题如何在这里使用 Nistrema4th。
在第一部分中,我得到eps
,然后使用一步 Runge Kutta 并将这 3 个值作为具有最佳h
(这是最小步长)的第一、第二和第三个值放入数组中。然后我需要从第 4 个开始并使用 Nistrema 找到其他人。
double fx(double x, double y, double t)
{
return (2*x)-y+(t*t)-2*(sin(t)+1)+cos(t);
}
double fy(double x, double y, double t)
{
return x+(2*y)-sin(t)-(2*(t*t))+(2*t)-1;
}
double precise_x(double t)
{
return sin(t)+1;
}
double precise_y(double t)
{
return (t*t);
}
int main(int argc, char* argv[])
{
double h=0.025,h_opt, x[1000],y[1000],x_pre[10000],y_pre[10000],eps,current_x,current_y,x_prev,y_prev;
double a=0.,b=1.,t=a, x_prev1,y_prev1,current_x1,current_y1, h_temp[3],x1,y1;
int k=20,i;
cout << "Input value of the epsilon, please: ";
cin >> eps;
a = 0; b = 1; t = a; x[0] = 1; y[0] = 0;
current_x = x[0];
current_y = y[0];
int flag = 0;
current_x = x[0];
current_y = y[0];
while(!flag)
{
for(i=0;i<k;i++)
{
x_prev = current_x;
y_prev = current_y;
current_x = x_prev + (h*fx(x_prev,y_prev,t+h));
current_y = y_prev + (h*fy(x_prev,y_prev,t+h));
x[0]=x[1];
x[1]=x[2];
x[2]=x[3];
x[3]=current_x;
y[0]=y[1];
y[1]=y[2];
y[2]=y[3];
y[3]=current_y;
t+=h;
}
if((fabs(x_prev-current_x)+fabs(y_prev-current_y)<eps))
{
flag = 1;
}
else
{
h/=2;
t=0;
current_x=1.;
current_y=0.;
}
h_opt=h;
}
//===============???????????????????????????????????????????===
//use formulas of Nisterm (4th order ) to get the results
double n = 1./h_opt;
for(i=0;i<=n;i++)
{
x[i+4] = x[i+2] + (h_opt/3.0)*(8*fx(x[i+3],y[i+3],(i+3)*h)
-(5*fx(x[i+2],y[i+2],(i+2)*h))
+4*fx(x[i+1],y[i+1],(i+1)*h)
-fx(x[i],y[i],i*h));
y[i+4] = y[i+2] + (h_opt/3.0)*(8*fy(x[i+3],y[i+3],(i+3)*h)
-(5*fy(x[i+2],y[i+2],(i+2)*h))
+4*fy(x[i+1],y[i+1],(i+1)*h)
-fy(x[i],y[i],i*h));
}
t = a;
for(i=0;i<=n;i++)
{
cout<<"n j "<<j;
x_pre[i] = precise_x(t);
y_pre[i] = precise_y(t);
t += h_opt;
}
cout << "xtyttprecise_x precise_y" << endl;
for(int i = 0; i <=k; i++)
{
cout << x[i] << "t" << y[i]<<"t"<< x_pre[i] <<"t"<<y_pre[i]<<endl;
}
system("PAUSE");
return 0;
}
前 3 个隐式欧拉步骤如何以某种同时方式工作
double fx0 = fx(x[0],y[0],t0),
fy0 = fy(x[0],y[0],t0)
while(!flag) {
/* Predictor: initialize the values, could be constant using x[0],y[0],
* or using the explicit Euler method, that is, the line with slopes f0,fy0
*/
for(j=1;j<4;j++) {
x[j] = x[0] + (j*h)*fx0;
y[j] = y[0] + (j*h)*fy0;
}
for(i=0;i<k;i++) {
/* Perform k corrector loops and check the size of the last update.
* Either it is very small or the step size h is outside the
* stability region of method+problem.
*/
x3_prev = x[3]; y3_prev = y[3];
// simultaneous implicit Euler correction for all 3 steps
for(j=1;j<4;j++) {
current_x = x[j-1] + h*fx(x[j],y[j],t0+j*h);
current_y = y[j-1] + h*fy(x[j],y[j],t0+j*h);
x[j] = current_x;
y[j] = current_y;
}
}
/* Check the last change relative to the size of the values
*/
if( (fabs(x3_prev-x[3])+fabs(y3_prev-y[3])) < eps * (fabs(x[3])+fabs(y[3])) )
{
flag = 1;
}
else
{
h/=2;
}
// h_opt=h; no need for extra variable h_opt as the last h retains that same value
}