runge kutta法aoba.cc.saga-u.ac.jp/.../networkanalysis/pdf/rungekutta.pdf補足:runge kutta法...

21
補足:RUNGE KUTTA只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

Upload: others

Post on 28-Dec-2019

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

Page 2: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

RUNGE KUTTA法 一階常微分方程式の数値解法

4次のRunge Kutta法

( ),dy f x ydx

=

( ) ( ) ( )

( )( )

( )

( )

( )( )

1 2 3 4

1

2 1

3 2

4 3

2 2

,

,2 2

6

,2 2,

k k k

f x y x

h hk f x y x k

h hk f x y x k

k f x

hy

h y x h

x h y x

k

k

k + + +

=

= + +

= + +

= +

+ = +

+

Page 3: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

連立微分方程式への拡張

( ),d y f x ydx

=

( ) ( ) ( )( )( )

( )

( )

( )( )

1 2 3 4

1

2 1

3 2

4 3

2 2

,

,2 2

2

6

,2

,

k k k

f x y x

h hk f x y x k

h hk f x y

hy x h y x k

k

x k

k f x h y x hk

+ = +

+ + +

=

= + +

= + +

= + +

Page 4: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

JAVAでの実装 注意点

関数ポインタを引数で渡すことができない 一階微分(微分方程式の右辺)を計算するメソッドを持ったクラスを渡す インターフェイスを定義する

Page 5: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

微分方程式を定義するインターフェイス

package rungeKutta; /** * Runge Kutta法で用いる微分方程式のインターフェイス * @author tadaki */ public interface EvolutionEquation { public double[] derivatives(double x,double y[]); }

( ),d y f x ydx

=

Page 6: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

RUNGE KUTTA法の本体 public static double[] rk4( double x, double y[], double h, EvolutionEquation eq) { int n = y.length; double hh = h / 2.; double h6 = h / 6.; double k1[] = eq.derivatives(x, y); double xh = x + hh; double yt[] = new double[n]; for (int i = 0; i < n; i++) {yt[i] = y[i] + hh * k1[i];} double k2[] = eq.derivatives(xh, yt); for (int i = 0; i < n; i++) {yt[i] = y[i] + hh * k2[i]; } double k3[] = eq.derivatives(xh, yt); for (int i = 0; i < n; i++) {yt[i] = y[i] + h * k3[i]; } double k4[] = eq.derivatives(x + h, yt); double yy[] = new double[n]; for (int i = 0; i < n; i++) { yy[i] = y[i] + h6 * (k1[i] + 2. * k2[i] + 2. * k3[i] + k4[i]); } return yy; }

Page 7: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

サンプル1:単振動 元の微分方程式

連立微分方程式化

22

2

d xdt

xω= −

2

dx ydtdy xdt

ω

=

= −

( ) ( )sint ax tω θ= +

Page 8: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

public class SimpleCircle implements EvolutionEquation { private double x; private double v; private double omega; public SimpleCircle(double x, double v, double omega) { this.x = x; this.v = v; this.omega = omega; } @Override public double[] derivatives(double x, double[] y) { double dy[] = new double[2]; dy[0] = y[1]; dy[1] = -omega * omega * y[0]; return dy; } }

Page 9: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

サンプル2:等加速度運動 元の微分方程式

連立微分方程式化

2

2

d xdt

a=

dx ydtdy adt

=

=

( ) 20 02

at tx v t x+ +=

Page 10: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

public class Parabola implements EvolutionEquation { private double x; private double v; private double accel; public Parabola(double x, double v, double accel) { this.x = x; this.v = v; this.accel = accel; } @Override public double[] derivatives(double x, double[] y) { double dy[] = new double[2]; dy[0] = y[1]; dy[1] = accel; return dy; } }

Page 11: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

おまけ:ファイルへの出力

FileOutputStream OutputStreamの派生クラス

System.out PrintStreamのインスタンス

OutputStreamの派生クラス

BufferedWriter

OutputStreamWriter

OutputStream

FileOutputStream f = new FileOutputStream( new File(“output.txt”));

Page 12: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

public static void printPointsList(List<Point2D.Double> points) throws IOException { printPointsList(points, System.out); } public static void printPointsList(List<Point2D.Double> points, OutputStream oStream) throws IOException { BufferedWriter out = new BufferedWriter( new OutputStreamWriter(oStream)); printPointsList(points, out); } public static void printPointsList(List<Point2D.Double> points, BufferedWriter out) throws IOException { for (int i = 0; i < points.size(); i++) { Point2D.Double p = points.get(i); StringBuilder b = new StringBuilder(); b.append(p.x).append(" ").append(p.y); out.write(b.toString()); out.newLine(); } out.flush(); }

Page 13: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

RungeKutta.java

package rungeKutta;

/** * 4th order Runge-Kutta method * @author tadaki */public class RungeKutta {

/** * One step from x to x + h * @param x initial value of independent valiable * @param y initial values of dependent valiables * @param h step * @param eq class contains differential equations * @return next values of dependent valiables */ public static double[] rk4( double x, double y[], double h, EvolutionEquation eq) { int n = y.length; double hh = h / 2.; double h6 = h / 6.; double k1[] = eq.derivatives(x, y); double xh = x + hh; double yt[] = new double[n]; for (int i = 0; i < n; i++) { yt[i] = y[i] + hh * k1[i]; } double k2[] = eq.derivatives(xh, yt); for (int i = 0; i < n; i++) { yt[i] = y[i] + hh * k2[i]; } double k3[] = eq.derivatives(xh, yt); for (int i = 0; i < n; i++) { yt[i] = y[i] + h * k3[i]; } double k4[] = eq.derivatives(x + h, yt); double yy[] = new double[n]; for (int i = 0; i < n; i++) { yy[i] = y[i] + h6 * (k1[i] + 2. * k2[i] + 2. * k3[i] + k4[i]); } return yy; }

/** * solve by rk4 from x1 to x2 with nstep * @param vstart start values of dependent valiables * @param x1 initial value of independent valiable * @param x2 final value of independent valiable * @param nstep the number of steps between x1 and x3 * @param eq class contains differential equations * @return sequence of values of dependent valiables */ public static double[][] rkdumb( double vstart[], double x1, double x2, int nstep, EvolutionEquation eq) {

1/2 ページ

Page 14: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

RungeKutta.java

int n = vstart.length; double y[][] = new double[n][nstep]; double v[] = new double[n]; for (int i = 0; i < n; i++) { v[i] = vstart[i]; y[i][0] = v[i]; } double xx[] = new double[nstep]; xx[0] = x1; double x = x1; double h = (x2 - x1) / nstep; for (int t = 1; t < nstep; t++) { double vout[] = rk4(x, v, h, eq); if ((double) (x + h) == x) { System.err.println("too small step"); } x += h; xx[t] = x; for (int i = 0; i < n; i++) { v[i] = vout[i]; y[i][t] = v[i]; } } return y; }}

2/2 ページ

Page 15: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

EvolutionEquation.java

package rungeKutta;

/** * * @author tadaki */public interface EvolutionEquation { public double[] derivatives(double x,double y[]);}

1/1 ページ

Page 16: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

Parabola.java

package samples;

import java.awt.geom.Point2D;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.List;import rungeKutta.EvolutionEquation;import rungeKutta.RungeKutta;import utils.FileIO;

/** * * @author tadaki */public class Parabola implements EvolutionEquation {

private double x; private double v; private double accel;

public Parabola(double x, double v, double accel) { this.x = x; this.v = v; this.accel = accel; }

public List<Point2D.Double> evlution(double t, int nstep) { double y[] = new double[2]; y[0] = x; y[1] = v; double yy[][] = RungeKutta.rkdumb(y, 0., t, nstep, this); List<Point2D.Double> points = Collections.synchronizedList( new ArrayList<Point2D.Double>()); double dt = t / nstep; for (int i = 0; i < nstep; i++) { double tt = i * dt; points.add(new Point2D.Double(tt, yy[0][i])); } return points; }

@Override public double[] derivatives(double x, double[] y) { double dy[] = new double[2]; dy[0] = y[1]; dy[1] = accel; return dy; }

/** * @param args the command line arguments */

1/2 ページ

Page 17: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

Parabola.java

public static void main(String[] args) throws IOException { Parabola sys = new Parabola(0., 0., 1.); double t = 10.; int nstep = 10000; try (FileOutputStream fStream1 = new FileOutputStream( new File("output.txt"))) { List<Point2D.Double> points = sys.evlution(t, nstep); FileIO.printPointsList(points, fStream1); }

}}

2/2 ページ

Page 18: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

SimpleCircle.java

package samples;

import java.awt.geom.Point2D;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.List;import rungeKutta.EvolutionEquation;import rungeKutta.RungeKutta;import utils.FileIO;

/** * * @author tadaki */public class SimpleCircle implements EvolutionEquation {

private double x; private double v; private double omega;

public SimpleCircle(double x, double v, double omega) { this.x = x; this.v = v; this.omega = omega; }

public List<Point2D.Double> evlution(double t, int nstep) { double y[] = new double[2]; y[0] = x; y[1] = v; double yy[][] = RungeKutta.rkdumb(y, 0., t, nstep, this); List<Point2D.Double> points = Collections.synchronizedList( new ArrayList<Point2D.Double>()); double dt = t / nstep; for (int i = 0; i < nstep; i++) { double tt = i * dt; points.add(new Point2D.Double(tt, yy[0][i])); } return points; }

@Override public double[] derivatives(double x, double[] y) { double dy[] = new double[2]; dy[0] = y[1]; dy[1] = -omega * omega * y[0]; return dy; }

/** * @param args the command line arguments */

1/2 ページ

Page 19: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

SimpleCircle.java

public static void main(String[] args) throws IOException { SimpleCircle sys = new SimpleCircle(0., 1., 1.); double t = 10.; int nstep = 10000; try (FileOutputStream fStream1 = new FileOutputStream( new File("output.txt"))) { List<Point2D.Double> points = sys.evlution(t, nstep); FileIO.printPointsList(points, fStream1); }

}}

2/2 ページ

Page 20: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

FileIO.java

package utils;

import java.awt.geom.Point2D;import java.io.BufferedWriter;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.util.List;

/** * * @author tadaki */public class FileIO {

public static void printPointsList(List<Point2D.Double> points) throws IOException { printPointsList(points, System.out); }

public static void printPointsList(List<Point2D.Double> points, OutputStream oStream) throws IOException { BufferedWriter out = new BufferedWriter( new OutputStreamWriter(oStream)); printPointsList(points, out); }

public static void printPointsList(List<Point2D.Double> points, BufferedWriter out) throws IOException { for (int i = 0; i < points.size(); i++) { Point2D.Double p = points.get(i); StringBuilder b = new StringBuilder(); b.append(p.x).append(" ").append(p.y); out.write(b.toString()); out.newLine(); } out.flush(); }

public static void printComments(String comments[]) throws IOException { printComments(comments, System.out); }

public static void printComments(String comments[], OutputStream oStream) throws IOException { BufferedWriter out = new BufferedWriter( new OutputStreamWriter(oStream)); printComments(comments, out); }

public static void printComments(String comments[], BufferedWriter out) throws IOException { for (int i = 0; i < comments.length; i++) { StringBuilder b = new StringBuilder(); b.append("#").append(comments[i]);

1/2 ページ

Page 21: RUNGE KUTTA法aoba.cc.saga-u.ac.jp/.../NetworkAnalysis/PDF/RungeKutta.pdf補足:RUNGE KUTTA法 只木進一 佐賀大学総合情報基盤センター 知能情報システム学特別講義

FileIO.java

out.write(b.toString()); out.newLine(); } out.flush(); }}

2/2 ページ