当前位置: 首页 > 知识库问答 >
问题:

如何用java解决ODEs?

姚海
2023-03-14

我正在尝试用Java解决一个ODE,到目前为止,我已经尝试了两个不同的库。我最信任的是Apache Commons Math,然而,即使是简单的问题,我似乎也得不到正确的解。

当我在Mathematica中求解系统时,我得到了这样的结果:

如果我用Apache Commons Math中的Dormand-Prince8(5,3)求解器求解,我会得到以下结果:

import org.apache.commons.math3.ode.*;
import org.apache.commons.math3.ode.nonstiff.DormandPrince853Integrator;
import org.apache.commons.math3.ode.sampling.StepHandler;
import org.apache.commons.math3.ode.sampling.StepInterpolator;

import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;

import static java.lang.Math.*;

public class program {

    public static void main(String[] args) {

        FirstOrderIntegrator dp853 = new DormandPrince853Integrator(1.0E-8, 10E-5, 1.0E-20, 1.0E-20);
        FirstOrderDifferentialEquations ode = new CometSun();

        double G = 1.48808E-34;
        double sunMass = 1.9891E30;

        double a = 1;
        double e = 0.1;
        double rp = a*(1-e);
        double v0 = sqrt(G*sunMass*(2/rp-1/a));
        double t = 2*PI*sqrt(pow(a,3)/(G*sunMass));

        double[] y = new double[6];

        y[0] = -rp;
        y[1] = 0;
        y[2] = 0;

        y[3] = 0;
        y[4] = v0;
        y[5] = 0;

        StepHandler stepHandler = new StepHandler() {

            ArrayList<String> steps = new ArrayList<String>();

            public void init(double t0, double[] y0, double t) {

            }

            public void handleStep(StepInterpolator interpolator, boolean isLast) {
                double   t = interpolator.getCurrentTime();
                double[] y = interpolator.getInterpolatedState();

                if( t > steps.size() )
                    steps.add(t + " " + y[0] + " " + y[1] + " " + y[2]);

                if(isLast) {
                    try{
                        PrintWriter writer = new PrintWriter(new File("results.txt"), "UTF-8");
                        for(String step: steps) {
                            writer.println(step);
                        }
                        writer.close();
                    } catch(Exception e) {};
                }
            }
        };
        dp853.addStepHandler(stepHandler);

        dp853.integrate(ode, 0.0, y, t, y);

        System.out.println(y[0]);
        System.out.println(y[1]);
    }

}
import org.apache.commons.math3.ode.FirstOrderDifferentialEquations;

import static java.lang.Math.*;

public class CometSun implements FirstOrderDifferentialEquations {

    double G = 1.48808E-34;
    double sunMass = 1.9891E30;

    public int getDimension() {
        return 6;
    }

    public void computeDerivatives(double t, double[] y, double[] yp) {
        double coeff = G*sunMass/pow(pow(y[0],2)+pow(y[1],2)+pow(y[2],2),3/2);

        yp[0] = y[3];
        yp[1] = y[4];
        yp[2] = y[5];

        yp[3] = -coeff*y[0];
        yp[4] = -coeff*y[1];
        yp[5] = -coeff*y[2];
    }

}

共有1个答案

邓赤岩
2023-03-14

我既不能预测,也不能保证或证实您会得到与Mathematica完全相同的结果:其中涉及一些非常大的数字和一些非常小的数字,您可能会遇到double精度的限制。

但在这种情况下,错误的主要原因极有可能是一个非常简单、非常微妙的原因:

double coeff = G*sunMass/pow(pow(y[0],2)+pow(y[1],2)+pow(y[2],2),3/2);

最后一个指数是1。你在那里执行一个整数除法,3/2得到1。你可以把它改成

double coeff = G*sunMass/pow(pow(y[0],2)+pow(y[1],2)+pow(y[2],2),3.0/2.0);
double yy0 = y[0]*y[0];
double yy1 = y[1]*y[1];
double yy2 = y[2]*y[2];
double coeff = G*sunMass/pow(yy0+yy1+yy2,3.0/2.0);
 类似资料:
  • 问题内容: 我正在尝试运行Java应用程序,但出现此错误: 冒号到达后,缺少该类的位置。但是,我知道该位置不存在,因为该类位于其他位置。如何更新该课程的路径?它与类路径有关吗? 问题答案: 类路径是要从中加载类的位置的列表。 这些“位置”可以是目录,也可以是jar文件。 对于目录,JVM将遵循预期的模式加载类。如果我的类路径中有目录C:/ myproject / classes,并且尝试加载类co

  • 问题内容: 我有三个方程,如下所示: x + y + z = 100; x + y-z = 50; x-y-z = 10; 如何使用Java查找x,y和z的值? 您有任何可能的解决方案或其他通用框架吗? 问题答案: 您可以使用行列式计算xy和z的值。逻辑可以在这里找到http://www.intmath.com/Matrices- determinants/1_Determinants.php 然

  • 本文向大家介绍JAVA如何解决并发问题,包括了JAVA如何解决并发问题的使用技巧和注意事项,需要的朋友参考一下 并发问题的根源在哪 首先,我们要知道并发要解决的是什么问题?并发要解决的是单进程情况下硬件资源无法充分利用的问题。而造成这一问题的主要原因是CPU-内存-磁盘三者之间速度差异实在太大。如果将CPU的速度比作火箭的速度,那么内存的速度就像火车,而最惨的磁盘,基本上就相当于人双腿走路。 这样

  • 问题内容: 我正在尝试编写简单的Java代码,以在控制台上显示MongoDB集合。我在类路径中添加了mongodb-driver-3.0.0.jar。 但是,当我尝试执行代码时,它在数据库连接行给了我以下错误: 线程“主”中的异常java.lang.NoClassDefFoundError:com.montan.app.MongoDbJdbc.main(MongoDbJdbc.java:12)上的

  • 问题内容: 我试图通过我的Web项目上的applet访问客户端的临时目录。 当我自己运行小程序时,它毫无问题地得到了。 当我尝试使用javascript并调用applet方法在我的项目上获取它时,我在javascript控制台上运行。当我尝试读取temp目录下的文件时,我也遇到同样的异常。 这正是我所看到的: 怎么解决? 问题答案: 最简单的解决方案是对applet进行签名。

  • 问题内容: 我已经尝试了Oracle Java教程中的两个示例。它们都可以正常编译,但是在运行时都出现以下错误: 我想我可能将Main.java文件放在错误的文件夹中。这是目录层次结构: 这里是 我在这里做错了什么? 更新 将Main类放入graphics包中(添加package graphics;到其中)后,将类路径设置为“ _test”(包含图形的文件夹),进行编译,然后使用java grap