问题
I have written an Euler's Method code to find an approximate value for x(10) and compare it to the value of x(10) given by the exact solution given in separable ODE. However, my code displays a chaotic number for x(10). Can you please identify a major error.
Thank you.
//@(#)euler.java
//This method attempts to find solutions to dx/dt = (e^t)(sin(x)) via
//Euler's iterative method and find an approximate value for x(10)
import java.text.DecimalFormat;
public class euler
{
public static void main(String[] Leonhard)
{
DecimalFormat df = new DecimalFormat("#.0000");
double h = (1.0/3.0); // h is the step-size
double t_0 = 0; // initial condition
double x_0 = .3; // initial condition
double x_f = 10; // I want to find x(10) using this method and compare it to an exact value of x(10)
double[] t_k;
t_k = new double[ (int)( ( x_f - x_0 ) / h ) + 1 ] ; // this two arrays hold the values of x_k and t_k
double[] x_k;
x_k = new double[ (int)( ( x_f - x_0 ) / h ) + 1 ] ;
int i; // the counter
System.out.println( "k\t t_k\t x_k" ); // table header
for ( i = 0; k < (int)( ( x_f - x_0 ) / h ) + 1; i++ )
{
if ( i == 0 ) // this if statement handles the initial conditions
{
t_k[i] = t_0;
x_k[i] = x_0;
}
else if ( i > 0 )
{
t_k[i] += i*h;
x_k[i] = x_k[i-1] + h*( Math.exp(t_k[i-1]))*(Math.sin(x_k[i-1]) );
}
System.out.println( k + " " + df.format(t_k[i]) + " " + df.format( x_k[i]) );
}
}
}
回答1:
Your code seems to work. The problem is that Euler's method is a fairly simplistic way of approximately integrating a differential equation. Its accuracy is strongly dependent upon the step size you're using, as you noticed.
I ran your code and compared with another implementation of the same algorithm. The results overlap in the regime where the approximation is working, and quite a while beyond. They only differ once the method breaks down strongly:
A thing to note is that the Euler method doesn't work very well for this particular differential equation, for the point you wish to reach. A step size of 1/3
is much too big to begin with, but even if you choose a much smaller step size, e.g 1/10000
, the method tends to break down before reaching t=10
. Something like exp(t)sin(x)
is hard to deal with. The real solution becomes flat, approaching pi
, so sin(x)
should go to zero, making the derivative zero as well. However, exp(t)
blows up, so the derivative is numerically unstable.
来源:https://stackoverflow.com/questions/33467167/eulers-method-in-java