我编写了一个Euler方法代码来查找x(10)的近似值,并将其与separable ODE中给出的精确解给出的x(10)值进行比较。但是,我的代码显示x(10)的混乱数字。你能否找出一个重大错误。
谢谢。
//@(#)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]) );
}
}
}
答案 0 :(得分:2)
您的代码似乎有效。问题在于欧拉方法是一种近似简化的近似积分微分方程的方法。正如您所注意到的,它的准确性在很大程度上取决于您正在使用的步长。
我运行了你的代码并与同一算法的另一个实现进行了比较。结果在近似正在起作用的制度中重叠,并且相当长一段时间。只有在方法强烈破坏时,它们才会有所不同:
需要注意的是,对于您希望达到的点,Euler方法对于此特定微分方程不能很好地工作。步长1/3
太大而不能开始,但即使您选择的步长要小得多,例如1/10000
,该方法也会在到达t=10
之前崩溃。像exp(t)sin(x)
这样的东西很难处理。真正的解决方案变得平坦,接近pi
,因此sin(x)
应该变为零,使得导数也为零。然而,exp(t)
爆炸,因此导数在数值上不稳定。