|
1 | 1 | ^{:kindly/hide-code true |
2 | | - :clay {:title "Emmy, the Algebra System: Differentail Geometry Chapter One" |
| 2 | + :clay {:title "Emmy, the Algebra System: Classical Mechanics Prologue" |
3 | 3 | :quarto {:author :kloimhardt |
4 | 4 | :type :post |
5 | 5 | :date "2025-09-10" |
6 | 6 | :image "sicm_ch01.png" |
7 | 7 | :category :libs |
8 | 8 | :tags [:emmy :physics]}}} |
9 | | - |
10 | 9 | (ns mentat-collective.emmy.fdg-ch01 |
11 | 10 | (:require [scicloj.kindly.v4.api :as kindly] |
12 | 11 | [scicloj.kindly.v4.kind :as kind] |
| 12 | + [emmy.env :as e] |
| 13 | + [emmy.mechanics.lagrange :as lg] |
13 | 14 | [civitas.repl :as repl])) |
14 | 15 |
|
| 16 | +;; Elemetary introduction to Emmy, taken from the first pages of the open-access book |
| 17 | +;; [Functional Differential Geometry (FDG)](https://mitpress.mit.edu/9780262019347/functional-differential-geometry/). |
| 18 | +;; The code snippets are executable, copy-paste them to the sidebar of the page. |
| 19 | + |
| 20 | +;; The Emmy maintainer, Sam Ritchie, wrote the source for this page, namely the |
| 21 | +;; [LaTex version of FDG](https://github.com/mentat-collective/fdg-book/blob/main/scheme/org/prologue.org). |
| 22 | + |
| 23 | +^:kindly/hide-code |
15 | 24 | (kind/hiccup |
16 | 25 | [:div |
17 | 26 | [:script {:src "https://cdn.jsdelivr.net/npm/scittle-kitchen/dist/scittle.js"}] |
|
25 | 34 | (def md |
26 | 35 | (comp kindly/hide-code kind/md)) |
27 | 36 |
|
28 | | -(md "The following examples are taken from the open-access book [Structure and Interpretation of Classical Mechanics (SICM)](https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/9579/sicm_edition_2.zip/chapter001.html).") |
29 | 37 |
|
| 38 | +^:kindly/hide-code |
30 | 39 | (kind/scittle |
31 | 40 | '(defn walk [inner outer form] |
32 | 41 | (cond |
|
35 | 44 | (coll? form) (outer (into (empty form) (map inner form))) |
36 | 45 | :else (outer form)))) |
37 | 46 |
|
| 47 | +^:kindly/hide-code |
38 | 48 | (kind/scittle |
39 | 49 | '(defn postwalk [f form] |
40 | 50 | (walk (partial postwalk f) f form))) |
41 | 51 |
|
| 52 | +^:kindly/hide-code |
42 | 53 | (kind/scittle |
43 | 54 | '(defn postwalk-replace [smap form] |
44 | 55 | (postwalk (fn [x] (if (contains? smap x) (smap x) x)) form))) |
45 | 56 |
|
| 57 | +^:kindly/hide-code |
46 | 58 | (kind/scittle |
47 | 59 | '(defmacro let-scheme [b & e] |
48 | 60 | (concat (list 'let (into [] (apply concat b))) e))) |
49 | 61 |
|
| 62 | +^:kindly/hide-code |
50 | 63 | (kind/scittle |
51 | 64 | '(defmacro define-1 [h & b] |
52 | 65 | (let [body (postwalk-replace {'let 'let-scheme} b)] |
|
58 | 71 | body)) |
59 | 72 | (concat (list 'def h) body))))) |
60 | 73 |
|
| 74 | +^:kindly/hide-code |
61 | 75 | (kind/scittle |
62 | 76 | '(defmacro define [h & b] |
63 | 77 | (if (and (coll? h) (= (first h) 'tex-inspect)) |
|
66 | 80 | h) |
67 | 81 | (concat ['define-1 h] b)))) |
68 | 82 |
|
| 83 | +^:kindly/hide-code |
69 | 84 | (kind/scittle |
70 | 85 | '(defmacro lambda [h b] |
71 | 86 | (list 'fn (into [] h) b))) |
72 | 87 |
|
| 88 | +^:kindly/hide-code |
73 | 89 | (kind/scittle |
74 | 90 | '(require '[emmy.env :refer :all :exclude [Lagrange-equations Gamma]])) |
75 | 91 |
|
| 92 | +^:kindly/hide-code |
76 | 93 | (kind/scittle |
77 | 94 | '(def show-expression (comp ->infix simplify))) |
78 | 95 |
|
| 96 | +^:kindly/hide-code |
79 | 97 | (kind/scittle |
80 | 98 | '(def velocities velocity)) |
81 | 99 |
|
| 100 | +^:kindly/hide-code |
82 | 101 | (kind/scittle |
83 | 102 | '(def coordinates coordinate)) |
84 | 103 |
|
| 104 | +^:kindly/hide-code |
85 | 105 | (kind/scittle |
86 | 106 | '(def vector-length count)) |
87 | 107 |
|
| 108 | +^:kindly/hide-code |
88 | 109 | (kind/scittle |
89 | 110 | '(defn time [state] (first state))) |
90 | 111 |
|
| 112 | +^:kindly/hide-code |
91 | 113 | (defmacro define [& b] |
92 | 114 | (list 'kind/scittle (list 'quote (cons 'define b)))) |
93 | 115 |
|
| 116 | +^:kindly/hide-code |
94 | 117 | (defmacro show-expression [& b] |
95 | | - (list 'kind/reagent [:p (list 'quote (cons 'show-expression b))])) |
| 118 | + (list 'kind/reagent [:h3 (list 'quote (cons 'show-expression b))])) |
96 | 119 |
|
| 120 | +^:kindly/hide-code |
97 | 121 | (kind/scittle '(declare Gamma)) |
98 | 122 |
|
| 123 | +;; ## Programming and Understanding |
| 124 | + |
| 125 | +;; One way to become aware of the precision required to unambiguously communicate a |
| 126 | +;; mathematical idea is to program it for a computer. Rather than using canned |
| 127 | +;; programs purely as an aid to visualization or numerical computation, we use |
| 128 | +;; computer programming in a functional style to encourage clear thinking. |
| 129 | +;; Programming forces us to be precise and unambiguous, without forcing us to be |
| 130 | +;; excessively rigorous. The computer does not tolerate vague descriptions or |
| 131 | +;; incomplete constructions. Thus the act of programming makes us keenly aware of |
| 132 | +;; our errors of reasoning or unsupported conclusions.[fn:1] |
| 133 | + |
| 134 | +;; Although this book is about differential geometry, we can show how thinking |
| 135 | +;; about programming can help in understanding in a more elementary context. The |
| 136 | +;; traditional use of Leibniz’s notation and Newton’s notation is convenient in |
| 137 | +;; simple situations, but in more complicated situations it can be a serious |
| 138 | +;; handicap to clear reasoning. |
| 139 | + |
| 140 | +;; A mechanical system is described by a Lagrangian function of the system state |
| 141 | +;; (time, coordinates, and velocities). A motion of the system is described by a |
| 142 | +;; path that gives the coordinates for each moment of time. A path is allowed if |
| 143 | +;; and only if it satisfies the Lagrange equations. Traditionally, the Lagrange |
| 144 | +;; equations are written |
| 145 | + |
| 146 | +;; $$ |
| 147 | +;;{\frac{d}{dt}\frac{\partial L}{\partial \dot{q}}} - |
| 148 | +;; \frac{\partial L}{\partial q}=0. |
| 149 | +;; $$ |
| 150 | + |
| 151 | +;; What could this expression possibly mean? |
| 152 | + |
| 153 | +;;Let’s try to write a program that implements Lagrange equations. What are |
| 154 | +;;Lagrange equations for? Our program must take a proposed path and give a result |
| 155 | +;;that allows us to decide if the path is allowed. This is already a problem; the |
| 156 | +;;equation shown above does not have a slot for a path to be tested. |
| 157 | + |
| 158 | +;; So we have to figure out how to insert the path to be tested. The partial |
| 159 | +;; derivatives do not depend on the path; they are derivatives of the Lagrangian |
| 160 | +;; function and thus they are functions with the same arguments as the Lagrangian. |
| 161 | +;; But the time derivative $d/dt$ makes sense only for a function of time. Thus we |
| 162 | +;; must be intending to substitute the path (a function of time) and its derivative |
| 163 | +;; (also a function of time) into the coordinate and velocity arguments of the |
| 164 | +;; partial derivative functions. |
| 165 | + |
| 166 | +;; So probably we meant something like the following (assume that $\omega$ is a |
| 167 | +;; path through the coordinate configuration space, and so $w(t)$ specifies the |
| 168 | +;; configuration coordinates at time $t$): |
| 169 | + |
| 170 | +;; $$\frac{d}{d t}\left( \left.\frac{\partial L(t, q, \dot{q})}{\partial \dot{q}} |
| 171 | +;; \right|_{\substack{ {q=w(t)} \\ {\dot{q}=\frac{d w(t)}{d t}} }} |
| 172 | +;; \right)-\left.\frac{\partial L(t, q, \dot{q})}{\partial q}\right|_{ \substack{ |
| 173 | +;; q=w(t) \\ {\dot{q}=\frac{d w(t)}{d t}}} }=0.$$ |
| 174 | + |
| 175 | +;; In this equation we see that the partial derivatives of the Lagrangian function |
| 176 | +;; are taken, then the path and its derivative are substituted for the position and |
| 177 | +;; velocity arguments of the Lagrangian, resulting in an expression in terms of the |
| 178 | +;; time. |
| 179 | + |
| 180 | +;; This equation is complete. It has meaning independent of the context and there |
| 181 | +;; is nothing left to the imagination. The earlier equations require the reader to |
| 182 | +;; fill in lots of detail that is implicit in the context. They do not have a clear |
| 183 | +;; meaning independent of the context. |
| 184 | + |
| 185 | +;; By thinking computationally we have reformulated the Lagrange equations into a |
| 186 | +;; form that is explicit enough to specify a computation. We could convert it into |
| 187 | +;; a program for any symbolic manipulation program because it tells us /how/ to |
| 188 | +;; manipulate expressions to compute the residuals of Lagrange’s equations for a |
| 189 | +;; purported solution path.[fn:2] |
| 190 | + |
| 191 | +;; ## Functional Abstraction |
| 192 | + |
| 193 | +;; But this corrected use of Leibniz notation is ugly. We had to introduce |
| 194 | +;; extraneous symbols ($q$ and $\dot{q}$) in order to indicate the argument |
| 195 | +;; position specifying the partial derivative. Nothing would change here if we |
| 196 | +;; replaced $q$ and $\dot{q}$ by $a$ and $b$.[fn:3] We can simplify the notation by |
| 197 | +;; admitting that the partial derivatives of the Lagrangian are themselves new |
| 198 | +;; functions, and by specifying the particular partial derivative by the position |
| 199 | +;; of the argument that is varied |
| 200 | + |
| 201 | +;; $$\frac{d}{d t}\left(\left(\partial_{2} L\right)\left(t, w(t), \frac{d}{d t} |
| 202 | +;; w(t)\right)\right)-\left(\partial_{1} L\right)\left(t, w(t), \frac{d}{d t} |
| 203 | +;; w(t)\right)=0,$$ |
| 204 | + |
| 205 | +;; where $\partial_{i}L$ is the function which is the partial derivative of the |
| 206 | +;; function $L$ with respect to the ith argument.[fn:4] |
| 207 | + |
| 208 | +;; Two different notions of derivative appear in this expression. The functions |
| 209 | +;; $\partial_2 L$ $\partial_1 L$, constructed from the Lagrangian $L$, have the |
| 210 | +;; same arguments as $L$. |
| 211 | +;; The derivative $d/dt$ is an expression derivative. It applies to an expression |
| 212 | +;; that involves the variable $t$ and it gives the rate of change of the value of |
| 213 | +;; the expression as the value of the variable $t$ is varied. |
| 214 | + |
| 215 | +;; These are both useful interpretations of the idea of a derivative. But functions |
| 216 | +;; give us more power. There are many equivalent ways to write expressions that |
| 217 | +;; compute the same value. For example $1/(1/r_1 + 1/r_2)=(r_1r_2)/(r_1 + r_2)$. |
| 218 | +;; These expressions compute the same function of the two variables $r_1$ and |
| 219 | +;; $r_2$. The first expression fails if $r_1 = 0$ but the second one gives the |
| 220 | +;; right value of the function. If we abstract the function, say as $\Pi(r_1, |
| 221 | +;; r_2)$, we can ignore the details of how it is computed. The ideas become clearer |
| 222 | +;; because they do not depend on the detailed shape of the expressions. |
| 223 | + |
| 224 | +;; So let’s get rid of the expression derivative $d/dt$ and replace it with an |
| 225 | +;; appropriate functional derivative. If $f$ is a function then we will write $Df$ |
| 226 | +;; as the new function that is the derivative of $f$:[fn:5] |
| 227 | + |
| 228 | +;; $$(D f)(t)=\left.\frac{d}{d x} f(x)\right|_{x=t}.$$ |
| 229 | + |
| 230 | +;; To do this for the Lagrange equation we need to construct a function to take the |
| 231 | +;; derivative of. |
| 232 | + |
| 233 | +;; Given a configuration-space path $w$, there is a standard way to make the |
| 234 | +;; state-space path. We can abstract this method as a mathematical function |
| 235 | +;; $\Gamma$: |
| 236 | + |
| 237 | +;; $$\Gamma[w](t)=\left(t, w(t), \frac{d}{d t} w(t)\right).$$ |
| 238 | + |
| 239 | +;; Using $\Gamma$ we can write: |
| 240 | + |
| 241 | +;; $$\frac{d}{dt}\left(\left(\partial_{2} L\right) \left(\Gamma[w](t)\right) |
| 242 | +;; \right) - \left(\partial_{1} L\right) \left(\Gamma[w](t)\right)=0.$$ |
| 243 | + |
| 244 | +;; If we now define composition of functions $(f \circ g)(x) = f(g(x))$, we can |
| 245 | +;; express the Lagrange equations entirely in terms of functions: |
| 246 | + |
| 247 | +;; $$D\left(\left(\partial_{2} L\right) \circ \left(\Gamma[w]\right)\right) |
| 248 | +;; -\left(\partial_{1} L\right) \circ \left(\Gamma[w]\right)=0.$$ |
| 249 | + |
| 250 | +;; The functions $\partial_1 L$ and $\partial_2 L$ are partial derivatives of the |
| 251 | +;; function $L$. Composition with $\Gamma[w]$ evaluates these partials with |
| 252 | +;; coordinates and velocites appropriate for the path $w$, making functions of |
| 253 | +;; time. Applying $D$ takes the time derivative. The Lagrange equation states that |
| 254 | +;; the difference of the resulting functions of time must be zero. This statement |
| 255 | +;; of the Lagrange equation is complete, unambiguous, and functional. It is not |
| 256 | +;; encumbered with the particular choices made in expressing the Lagrangian. For |
| 257 | +;; example, it doesn’t matter if the time is named $t$ or $\tau$, and it has an |
| 258 | +;; explicit place for the path to be tested. |
| 259 | + |
| 260 | +;; This expression is equivalent to a computer program:[fn:6] |
| 261 | + |
99 | 262 | (define ((Lagrange-equations Lagrangian) w) |
100 | 263 | (- (D (compose ((partial 2) Lagrangian) (Gamma w))) |
101 | 264 | (compose ((partial 1) Lagrangian) (Gamma w)))) |
102 | 265 |
|
| 266 | +;; In the Lagrange equations procedure the parameter `Lagrangian` is a procedure |
| 267 | +;; that implements the Lagrangian. The derivatives of the Lagrangian, for example |
| 268 | +;; `((partial 2) Lagrangian)`, are also procedures. The state-space path procedure |
| 269 | +;; `(Gamma w)` is constructed from the configuration-space path procedure `w` by |
| 270 | +;; the procedure `Gamma`: |
| 271 | + |
103 | 272 | (define ((Gamma w) t) |
104 | 273 | (up t (w t) ((D w) t))) |
105 | 274 |
|
| 275 | +;; where `up` is a constructor for a data structure that represents a state of the |
| 276 | +;; dynamical system (time, coordinates, velocities). |
| 277 | + |
| 278 | +;; The result of applying the `Lagrange-equations` procedure to a procedure |
| 279 | +;; `Lagrangian` that implements a Lagrangian function is a procedure that takes a |
| 280 | +;; configuration-space path procedure `w` and returns a procedure that gives the |
| 281 | +;; residual of the Lagrange equations for that path at a time. |
| 282 | + |
| 283 | +;; For example, consider the harmonic oscillator, with Lagrangian |
| 284 | + |
| 285 | +;; $$L(t, q, v) = \frac{1}{2}mv^2 - \frac{1}{2}kq^2,$$ |
| 286 | + |
| 287 | +;; for mass $m$ and spring constant $k$. this lagrangian is implemented by |
| 288 | + |
106 | 289 | (define ((L-harmonic m k) local) |
107 | 290 | (let ((q (coordinate local)) |
108 | 291 | (v (velocity local))) |
109 | 292 | (- (* 1/2 m (square v)) |
110 | 293 | (* 1/2 k (square q))))) |
111 | 294 |
|
| 295 | +;; We know that the motion of a harmonic oscillator is a sinusoid with a given |
| 296 | +;; amplitude $a$, frequency $\omega$, and phase $\varphi$: |
| 297 | + |
| 298 | +;; $$x(t) = a \cos(\omega t + \varphi).$$ |
| 299 | + |
| 300 | +;; Suppose we have forgotten how the constants in the solution relate to the |
| 301 | +;; physical parameters of the oscillator. Let’s plug in the proposed solution and |
| 302 | +;; look at the residual: |
| 303 | + |
112 | 304 | (define (proposed-solution t) |
113 | 305 | (* 'a (cos (+ (* 'omega t) 'phi)))) |
114 | 306 |
|
|
117 | 309 | proposed-solution) |
118 | 310 | 't)) |
119 | 311 |
|
| 312 | +;; [note by MAK: copy-paste the code into the sidebar and verify the above result.] |
| 313 | + |
| 314 | +;; The residual here shows that for nonzero amplitude, the only solutions allowed |
| 315 | +;; are ones where $(k - m\omega^2) = 0$ or $\omega = \sqrt{k/m}$. |
| 316 | + |
| 317 | +;; But, suppose we had no idea what the solution looks like. We could propose a |
| 318 | +;; literal function for the path: |
| 319 | + |
| 320 | +;; [note by MAK: the following does not work in the sidebar because I could not get |
| 321 | +;; `literal-function` to work. |
| 322 | +;; As a remedy, I have an [alternative execution environment](https://kloimhardt.github.io/blog/html/sicmutils-as-js-book-part1.html)] |
| 323 | + |
| 324 | +(->infix |
| 325 | + (simplify |
| 326 | + (((e/Lagrange-equations (lg/L-harmonic 'm 'k)) |
| 327 | + (e/literal-function 'x)) |
| 328 | + 't))) |
| 329 | + |
| 330 | +;; If this residual is zero we have the Lagrange equation for the harmonic |
| 331 | +;; oscillator. |
| 332 | + |
| 333 | +;; Note that we can flexibly manipulate representations of mathematical functions. |
| 334 | +;; (See Appendices A and B.) |
| 335 | + |
| 336 | +;; We started out thinking that the original statement of Lagrange’s equations |
| 337 | +;; accurately captured the idea. But we really don’t know until we try to teach it |
| 338 | +;; to a naive student. If the student is sufficiently ignorant, but is willing to |
| 339 | +;; ask questions, we are led to clarify the equations in the way that we did. There |
| 340 | +;; is no dumber but more insistent student than a computer. A computer will |
| 341 | +;; absolutely refuse to accept a partial statement, with missing parameters or a |
| 342 | +;; type error. In fact, the original statement of Lagrange’s equations contained an |
| 343 | +;; obvious type error: the Lagrangian is a function of multiple variables, but the |
| 344 | +;; $d/dt$ is applicable only to functions of one variable. |
| 345 | + |
| 346 | +;; ## Footnotes |
| 347 | + |
| 348 | +;; [fn:6] The programs in this book are written in Scheme, a dialect of Lisp. The |
| 349 | +;; details of the language are not germane to the points being made. What is |
| 350 | +;; important is that it is mechanically interpretable, and thus unambiguous. In |
| 351 | +;; this book we require that the mathematical expressions be explicit enough that |
| 352 | +;; they can be expressed as computer programs. Scheme is chosen because it is easy |
| 353 | +;; to write programs that manipulate representations of mathematical functions. An |
| 354 | +;; informal description of Scheme can be found in Appendix A. The use of Scheme to |
| 355 | +;; represent mathematical objects can be found in Appendix B. A formal description |
| 356 | +;; of Scheme can be obtained in [10]. You can get the software from [21]. |
| 357 | + |
| 358 | +;; [fn:5] An explanation of functional derivatives is in Appendix B, page 202. |
| 359 | + |
| 360 | +;; [fn:4] The argument positions of the Lagrangian are indicated by indices |
| 361 | +;; starting with zero for the time argument. |
| 362 | + |
| 363 | +;; [fn:3] That the symbols $q$ and $\dot{q}$ can be replaced by other arbitrarily |
| 364 | +;; chosen nonconflicting symbols without changing the meaning of the expression |
| 365 | +;; tells us that the partial derivative symbol is a logical quantifier, like forall |
| 366 | +;; and exists ($\forall$ and $\exists$). |
| 367 | + |
| 368 | +;; [fn:2] The /residuals/ of equations are the expressions whose value must be zero |
| 369 | +;; if the equations are satisfied. For example, if we know that for an unknown $x$, |
| 370 | +;; $x^3-x=0$ then the residual is $x^3 - x$. We can try $x = -1$ and find a |
| 371 | +;; residual of 0, indicating that our purported solution satisfies the equation. A |
| 372 | +;; residual may provide information. For example, if we have the differential |
| 373 | +;; equation $df(x)/dx - af(x) = 0$ and we plug in a test solution $f(x) = Ae^{bx}$ |
| 374 | +;; we obtain the residual $(b - a)Ae^{bx}$, which can be zero only if $b = a$. |
| 375 | + |
| 376 | +;; [fn:1] The idea of using computer programming to develop skills of clear |
| 377 | +;; thinking was originally advocated by Seymour Papert. An extensive discussion of |
| 378 | +;; this idea, applied to the education of young children, can be found in Papert |
| 379 | +;; [13]. |
| 380 | + |
120 | 381 | (repl/scittle-sidebar) |
0 commit comments