Exercise 1.14: Coordinate-independence of Lagrange equations

(require '[sicmutils.env :refer :all])

Look carefully at what this exercise is asking us to do:

Check that the Lagrange equations for central force motion in polar coordinates and in rectangular coordinates are equivalent. Determine the relationship among the second derivatives by substituting paths into the transformation equations and computing derivatives, then substitute these relations into the equations of motion.

The punchline that we'll encounter soon is that a coordinate transformation of applied to some path function inline_formula not implemented can commute with inline_formula not implemented. You can always write some function inline_formula not implemented of the local tuple that handles the coordinate transformation after inline_formula not implemented instead of transforming the path directly. In other words, you can always find some inline_formula not implemented such that

formula not implemented

Because function composition is associative, instead of ever transforming the path, you can push the coordinate transformation into the Lagrangian to generate a new Lagrangian: inline_formula not implemented.

The section of textbook just before the exercise has given us two Lagrangians in different coordinates – L-central-polar and L-rectangular – and generated Lagrange equations from each.

Our task is to directly transform the Lagrange equations by substituting the first and second derivatives of the coordinate transformation expression into one of the sets of equations, and looking to see that it's equivalent to the other.

Fair warning: this is much more painful than transforming the Lagrangian before generating the Lagrange equations. This exercise continues the theme of devastating you with algebra as a way to show you the horror that the later techniques were developed to avoid. Let us proceed.

Here are the two Lagrangians from the book:

(defn L-central-rectangular [m U]
  (fn [[_ q v]]
    (- (* (/ 1 2) m (square v))
       (U (sqrt (square q))))))
(defn L-central-polar [m U]
  (fn [[_ [r phi] [rdot phidot]]]
    (- (* (/ 1 2) m
          (+ (square rdot)
             (square (* r phidot))) )
       (U r))))

Here are the rectangular equations of motion:

(((Lagrange-equations
   (L-central-rectangular 'm (literal-function 'U)))
  (up (literal-function 'x)
      (literal-function 'y)))
 't)

And the polar Lagrange equations:

(((Lagrange-equations
   (L-central-polar 'm (literal-function 'U)))
  (up (literal-function 'r)
      (literal-function 'phi)))
 't)

Once again, our goal is to show that, if you can write down coordinate transformations for the coordinates, velocities and accelerations and substitute them in to one set of Lagrange equations, the other will appear.

To do this by hand, take the coordinate transformation described in 1.64 in the book:

formula not implemented

Note that inline_formula not implemented, inline_formula not implemented, inline_formula not implemented and inline_formula not implemented are functions of inline_formula not implemented. Take the derivative of each equation (Use the product and chain rules) to obtain expressions for the rectangular velocities in terms of the polar coordinates, just like equation 1.66 in the book:

formula not implemented

The rectangular equations of motion have second derivatives, so we need to keep going. This is too devastating to imagine doing by hand. Let's move to Scheme.

Write the coordinate transformation for polar coordinates to rectangular in Scheme:

(ns-unmap *ns* 'p->r)
(defn p->r [[_ [r phi]]]
  (let [x (* r (cos phi))
        y (* r (sin phi))]
    (up x y)))

Now use F->C, first described on page 46. This is a function that takes a coordinate transformation like p->r and returns a new function that can convert an entire local tuple from one coordinate system to another; the inline_formula not implemented discussed above.

The version that the book presents on page 46 can only generate a velocity transformation given a coordinate transformation, but scmutils contains a more general version that will convert as many path elements as you pass to it.

Here are the rectangular positions, velocities and accelerations, written in polar coordinates:

(let [convert-path (F->C p->r)
      polar-path (up 't
                     (up 'r 'phi)
                     (up 'rdot 'phidot)
                     (up 'rdotdot 'phidotdot))]
  (convert-path polar-path))

Ordinarily, it would be too heartbreaking to substitute these in to the rectangular equations of motion. The fact that we have Scheme on our side gives me the strength to proceed.

Write the rectangular Lagrange equations as a function of the local tuple, so we can call it directly:

(defn rect-equations [[_ [x y] [xdot ydot] [xdotdot ydotdot]]]
  (let [U (literal-function 'U)]
    (up (/ (+ (* 'm xdotdot (sqrt (+ (square x) (square y))))
              (* x ((D U) (sqrt (+ (square x) (square y))))))
           (sqrt (+ (square x) (square y))))
        (/ (+ (* 'm ydotdot (sqrt (+ (square x) (square y))))
              (* y ((D U) (sqrt (+ (square x) (square y))))))
           (sqrt (+ (square x) (square y)))))))

Verify that these are, in fact, the rectangular equations of motion by passing in a symbolic rectangular local tuple:

(let [rect-path (up 't
                    (up 'x 'y)
                    (up 'xdot 'ydot)
                    (up 'xdotdot 'ydotdot))]
  (rect-equations rect-path))

Now use the p->r conversion to substitute each of the rectangular values above with their associated polar values:

(let [convert-path (F->C p->r)
      polar-path (up 't
                     (up 'r 'phi)
                     (up 'rdot 'phidot)
                     (up 'rdotdot 'phidotdot))
      local (convert-path polar-path)]
  (rect-equations local))

Oh no. This looks quite different from the polar Lagrange equations above. What is the problem?

I had to stare at this for a long time before I saw what to do. Notice that the terms we want from the polar Lagrange equations all seem to appear in the first equation with a inline_formula not implemented, and in the second equation with a inline_formula not implemented. Using the trigonometric identity:

formula not implemented

I realized that I could recover the first equation through a linear combination of both terms. Multiply the first by inline_formula not implemented and the second by inline_formula not implemented, add them together and the unwanted terms all drop away.

A similar trick recovers the second equation,given an extra factor of inline_formula not implemented:

(let [convert-path (F->C p->r)
      polar-path (up 't
                     (up 'r 'phi)
                     (up 'rdot 'phidot)
                     (up 'rdotdot 'phidotdot))
      local (convert-path polar-path)
      eq (rect-equations local)]
  (up (+ (* (cos 'phi) (ref eq 0))
         (* (sin 'phi) (ref eq 1)))
      (- (* 'r (cos 'phi) (ref eq 1))
         (* 'r (sin 'phi) (ref eq 0)))))

This was a powerful lesson. We're allowed to take a linear combination here because each equation is a residual, equal to zero. inline_formula not implemented for any inline_formula not implemented and inline_formula not implemented, so any combination we generate is still a valid residual.

There is something important going on here, with the way we were able to remove inline_formula not implemented completely from the Lagrange equations. It seemed like inline_formula not implemented was quite important, until we managed to kill it. Is this related to the discussions of symmetries that we'll encounter later in the book? Let me know if you know the answer here.

Runtimes (1)