ObviousNistrem4 (основной), неявный Runge Kutta 1 (вспомогательный) при переполнении стека

Вот что я сделал, он находит 3 первых значения с помощью одностадийного RK, но затем у меня есть несколько вопросов, как использовать 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 << "x\ty\t\tprecise_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;
}

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
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]