Hello,

I added a library '(sicm symbolic)' for doing some basic symbolic
manipulations. Below I'll work through an example from chapter 1,
section 4 of SICM.

I'm using a low-level symbolic representation that is very
verbose. This is just for illustrative purposes, so that it's clear
what's going on at the low level. Scheme record types are used to
represent the different primitive forms.

Let the games begin:

    (import (sicm numerics-quadrature-defint)
            (sicm symbolic))

Let's setup the path of a free particle:

    (define test-path
      (make-tuple (vector (make-add (make-mul (make-constant 4)
                                              (make-identity))
                                    (make-constant 7))

                          (make-add (make-mul (make-constant 3)
                                              (make-identity))
                                    (make-constant 5))

                          (make-add (make-mul (make-constant 2)
                                              (make-identity))
                                    (make-constant 1)))))

It can be converted to a procedure and applied:

    > ((to-procedure test-path) 10)
    #(47 35 21)

Going off their description of Gamma, here's that procedure:

    (define (Gamma q)
      (make-tuple (vector (make-identity)
                          q
                          (derivative q))))

So we can apply it to a path and we get back a tuple containing the
time, the path, and the velocity. We get back a huge monster when we
call 'Gamma' on 'test-path'. Here it is in all it's unsimplified glory:

    > (Gamma test-path)

#[tuple #(#[identity]

          #[tuple #(#[add #[mul #[constant 4] #[identity]]
                          #[constant 7]]
                    #[add #[mul #[constant 3] #[identity]]
                          #[constant 5]]
                    #[add #[mul #[constant 2] #[identity]]
                          #[constant 1]])]

          #[tuple #(#[add #[add #[mul #[constant 0] #[identity]]
                                #[mul #[constant 4]
                                      #[constant 1]]]
                          #[constant 0]]

                    #[add #[add #[mul #[constant 0] #[identity]]
                                #[mul #[constant 3]
                                      #[constant 1]]]
                          #[constant 0]]

                    #[add #[add #[mul #[constant 0] #[identity]]
                                #[mul #[constant 2] #[constant 1]]]
                          #[constant 0]])])]

Nevertheless, we can extract the third component (the velocity), turn
it into a procedure, and apply it:

    > ((to-procedure
        (vector-ref (tuple-items (Gamma test-path)) 2))
       5)
    #(4 3 2)

Warm fuzzies.

Here's 'L-free-particle':

    (define (L-free-particle mass)
      (lambda (local)
        (let ((v (velocity local)))
          (make-mul (make-mul (make-constant 1/2)
                              (make-constant mass))
                    (tuple-dot-product v v)))))

'local' is what we get back from 'Gamma'. So we need a way to extract
the velocity:

    (define (velocity local)
      (vector-ref (tuple-items local) 2))

The 'tuple-dot-product' procedure can be defined in terms of some
low-level tuple procedures:

    (define (tuple-dot-product a b)
      (make-tuple-sum
       (make-tuple*tuple-elementwise a b)))

Alright, we now come to the function that ties it all together,
'Lagrangian-action':

    (define (Lagrangian-action L q t1 t2)

      (let ((f (to-procedure (L (Gamma q)))))

        (definite-integral f t1 t2 0.001)))

Let's see it in action. The example from the book:

   > (Lagrangian-action (L-free-particle 3.0) test-path 0 10)
   435.0

Easy as pi.

The '(sicm symbolic)' library:

    http://github.com/dharmatech/sicm/raw/master/symbolic.sls

There's something nice about exploring the concepts in SICM using raw Scheme; you can feel the bits between your toes.

Ed

Reply via email to