ひとり勉強会

ひとり楽しく勉強会

[SICM] 1.4 Computing Actions (承前)

最小作用の軌跡を探す

前回は、

ときに、実際にそのpathを使って計算した作用が極小値になってることを確かめました。今回は

ときに、その間に物体が描くpathを探すお話。具体的には、pathが多項式で表せると仮定して、さまざまな多項式のうち一番作用が極小になるものを見つけ出します。近似です。
例として、調和振動子(harmonic oscillator)を考えます。要はバネがびよんびよんする動きですね。昔の偉い人によると、重りの重さとバネ定数を1.0にしたときのラグランジアンはこうだそうです。
L(t,q,v) = \frac{1}{2}v^2 - \frac{1}{2}q^2
Schemeで書くとこう。

(define (L local)
  (let ((q (coordinate local)) 
        (v (velocity   local)))
    (- (* 1/2 (square v)) (* 1/2 (square q)))))

始点 q(0)=1 終点 q(\pi/2)=0 とすると、このバネの動きは
q(t)=cos(t)
となるのですが、ここでは、そんな結論は知らないものとして、多項式近似させてみます。どうやるかというと、まず、途中で通る点のリストqsをパラメータとして与えると、指定した点全部を通る多項式pathを作ってくれる便利関数を定義しておきます。あとは、このqsを色々動かしてみて、一番作用が小さくなるqsを解として返せばOK。多項式pathを計算する関数は組み込みで用意されてますので、それ(make-path)を使います。

(define (parametric-path qs)
  (make-path 0.0 1.0 :pi/2 0.0 qs))
(define (parametric-path-action qs)
  (Lagrangian-action L (parametric-path qs) 0.0 :pi/2))

関数と初期値を与えると、初期値付近でその極小値を探してくれる関数 multidimensional-minimize が組み込みで用意されてますので、あとは、これを使って qs を色々動かしてもらいます。

(define q
  (parametric-path
     (multidimensional-minimize
        parametric-path-action
        (linear-interpolants 1.0 0.0 3))))

linear-interpolants はたぶん指定された個数の分割点を区間からとっていて、上の例だと、(0.75 0.5 0.25) になります。とりあえず直線的に動くという初期値を与えておいて、そこからqsを調整して最小化していくんだと思う。ものすごい時間がかかりますが、しばらくするとこの最小化が終わって、

guile> (list (q 0.0) (cos 0.0))
(1.0 1.0)
guile> (list (q :pi/6) (cos :pi/6))
(0.865860337498234 0.866025403784439)
guile> (list (q :pi/4) (cos :pi/4))
(0.707094767245861 0.707106781186548)
guile> (list (q :pi/3) (cos :pi/3))
(0.500167078050394 0.5)
guile> (list (q :pi/2) (cos :pi/2))
(0.0 6.12303176911189e-17)

だいたいcosに近い関数が計算されました。