質問<1562>2004/1/21
from=あっ子
「微分方程式」


「d^2f(x)/dx^2=-f(x)」を「d^2f(x)/dx^2=f(x+2h)-2f(x+h)+f(x)/h^2」
(hは適当な微少な正の実数)のように微分を差分に直して、
f(x+2h)の値をf(x)とf(x+h)の値から求めて、
微分方程式を解く方法を教えてください。
境界条件はf(0)=0,df(0)/dx=1です。
また、hの取り方が、どのように解に影響を与えるかも教えて
くださるとありがたいです。お願いします。


お便り2004/2/5
from=Tetsuya Kobayashi


f(x+2h) = 2f(x+h)-(1+h^2)f(x)
のように変形するとちょっとは漸化式っぽいかな?

せっかくなのでJavaで可視化したプログラムを書いてみました。
コンパイルしてコンソールから
java main (h の値)
とやれば、真の解である y=sin(x) と、上記差分方程式の解をプロットします。
h を小さくすれば小さくするほど真の解に近づきます。h=0.001くらいになると
一周期分くらいでは見た目ではほとんど差が出ません。

以下、プログラムリスト。

// f(x+2h) = 2f(x+h)-(1+h^2)f(x)

import java.awt.*;

class main {
    public static void main(String[] args) {
if (args.length <= 0) return;
double h = java.lang.Double.parseDouble(args[0]);
Frame f = new Frame();
MyCanvas c = new MyCanvas(h);
c.setSize(800,600);
f.add(c, "South");
f.setBackground(Color.white);
f.setForeground(Color.black);
f.pack();
f.show();
    }
}
class MyCanvas extends Canvas {
    double h;

    MyCanvas(double d) {
h = d;
    }

    public void paint(Graphics g) {
for (int i=0; i<8000; i++) {
    double p = i/1000.0;
    double q = Math.sin(p);
    putPixel(g,Color.green,p,q);
}

// Initial Conditions: f(0)=0, f(h)=h
double p2 = 0.0, p1 = h, p0;
// Second-Order Differencial
for (double t=2*h; t<8; t+=h) {
    p0 = 2*p1-(1+h*h)*p2;
    putPixel(g,t,p0);
    p2 = p1;
    p1 = p0;
}
    }

    void putPixel(Graphics g, Color c, double p, double q) {
int x = (int)(p*100);
int y = 300-(int)(q*100);
g.setColor(c);
g.drawLine(x,y,x,y);
    }
    void putPixel(Graphics g, double p, double q) {
putPixel(g,Color.black,p,q);
    }
}

(注)プログラム中の「<」はすべて半角にしてください。(武田談)