metric.scm 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. #| -*-Scheme-*-
  2. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
  3. 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  4. 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
  5. Institute of Technology
  6. This file is part of MIT/GNU Scheme.
  7. MIT/GNU Scheme is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11. MIT/GNU Scheme is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with MIT/GNU Scheme; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
  18. USA.
  19. |#
  20. ;;;; Metrics
  21. ;;; A metric is a function that takes two vector fields and produces a
  22. ;;; function on the manifold.
  23. #|
  24. (set! *divide-out-terms* #f)
  25. (set! *factoring* #t)
  26. ;;; Example: natural metric on a sphere of radius R
  27. (define 2-sphere R2-rect)
  28. (install-coordinates 2-sphere (up 'theta 'phi))
  29. (define ((g-sphere R) u v)
  30. (* (square R)
  31. (+ (* (dtheta u) (dtheta v))
  32. (* (compose (square sin) theta)
  33. (dphi u)
  34. (dphi v)))))
  35. (define u (literal-vector-field 'u 2-sphere))
  36. (define v (literal-vector-field 'v 2-sphere))
  37. (pec (((g-sphere 'R) u v)
  38. ((2-sphere '->point) (up 'theta0 'phi0))))
  39. #| Result:
  40. (* (+ (* (v^0 (up theta0 phi0))
  41. (u^0 (up theta0 phi0)))
  42. (* (expt (sin theta0) 2)
  43. (v^1 (up theta0 phi0))
  44. (u^1 (up theta0 phi0))))
  45. (expt R 2))
  46. |#
  47. ;;; Example: Lorentz metric on R^4
  48. (define SR R4-rect)
  49. (install-coordinates SR (up 't 'x 'y 'z))
  50. (define* ((g-Lorentz c) u v)
  51. (+ (* (dx u) (dx v))
  52. (* (dy u) (dy v))
  53. (* (dz u) (dz v))
  54. (* -1 (square c) (dt u) (dt v))))
  55. ;;; Example: general metric on R^2
  56. (install-coordinates R2-rect (up 'x 'y))
  57. (define R2-basis (coordinate-system->basis R2-rect))
  58. (define ((g-R2 g_00 g_01 g_11) u v)
  59. (+ (* g_00 (dx u) (dx v))
  60. (* g_01 (+ (* (dx u) (dy v)) (* (dy u) (dx v))))
  61. (* g_11 (dy u) (dy v))))
  62. (pec (((g-R2 'a 'b 'c)
  63. (literal-vector-field 'u R2-rect)
  64. (literal-vector-field 'v R2-rect))
  65. ((R2-rect '->point) (up 'x0 'y0))))
  66. #| Result:
  67. (+ (* (u^0 (up x0 y0)) (v^0 (up x0 y0)) a)
  68. (* (+ (* (v^0 (up x0 y0)) (u^1 (up x0 y0)))
  69. (* (u^0 (up x0 y0)) (v^1 (up x0 y0))))
  70. b)
  71. (* (v^1 (up x0 y0)) (u^1 (up x0 y0)) c))
  72. |#
  73. |#
  74. #|
  75. (define ((coordinate-system->metric-components coordsys) xi)
  76. (let ((xi->x ;assumes internal rectangular representation
  77. (lambda (xi)
  78. (manifold-point-representation
  79. ((point coordsys) xi)))))
  80. (define (Qd v)
  81. (* ((D xi->x) xi) v))
  82. (* 1/2
  83. ((D (D (lambda (v)
  84. (dot-product (Qd v) (Qd v)))))
  85. (zero-like xi)))))
  86. (define ((coordinate-system->metric-components coordsys) xi)
  87. (let* ((n (coordsys 'dimension))
  88. (xi->x ;assumes internal rectangular representation
  89. (compose manifold-point-representation
  90. (point coordsys)))
  91. (h ((D xi->x) xi)))
  92. (s:generate n 'down
  93. (lambda (i)
  94. (s:generate n 'down
  95. (lambda (j)
  96. (dot-product (ref h i)
  97. (ref h j))))))))
  98. |#
  99. (define (coordinate-system->metric-components coordsys)
  100. (let* ((n (coordsys 'dimension))
  101. (xi->x ;assumes internal rectangular representation
  102. (compose manifold-point-representation
  103. (point coordsys))))
  104. (embedding-map->metric-components n xi->x)))
  105. (define (embedding-map->metric-components n xi->rectangular)
  106. (let ((h (D xi->rectangular)))
  107. (if (= n 1)
  108. (down (down (dot-product h h)))
  109. (s:generate n 'down
  110. (lambda (i)
  111. (s:generate n 'down
  112. (lambda (j)
  113. (dot-product (ref h i)
  114. (ref h j)))))))))
  115. #|
  116. ((coordinate-system->metric-components R3-spherical) (up 'r 'theta 'phi))
  117. #|
  118. (down (down 1 0 0)
  119. (down 0 (expt r 2) 0)
  120. (down 0 0 (* (expt r 2) (expt (sin theta) 2))))
  121. |#
  122. |#
  123. (define (coordinate-system->metric coordinate-system)
  124. (let* ((basis (coordinate-system->basis coordinate-system))
  125. (1form-basis (basis->1form-basis basis))
  126. (->components
  127. (coordinate-system->metric-components coordinate-system))
  128. (Chi (chart coordinate-system)))
  129. (define* ((the-metric v1 v2) m)
  130. (let ((gcoeffs (->components (Chi m))))
  131. (* (* gcoeffs ((1form-basis v1) m))
  132. ((1form-basis v2) m))))
  133. (declare-argument-types! the-metric
  134. (list vector-field? vector-field?))
  135. the-metric))
  136. #|
  137. (s:map/r (lambda (v1)
  138. (s:map/r (lambda (v2)
  139. (((coordinate-system->metric R3-spherical) v1 v2)
  140. ((point R3-spherical) (up 'r 'theta 'phi))))
  141. (coordinate-system->vector-basis R3-spherical)))
  142. (coordinate-system->vector-basis R3-spherical))
  143. #|
  144. (down (down 1 0 0)
  145. (down 0 (expt r 2) 0)
  146. (down 0 0 (* (expt r 2) (expt (sin theta) 2))))
  147. |#
  148. |#
  149. (define (coordinate-system->inverse-metric coordinate-system)
  150. (let* ((basis (coordinate-system->basis coordinate-system))
  151. (vector-basis (basis->vector-basis basis))
  152. (->components
  153. (/ 1
  154. (coordinate-system->metric-components coordinate-system)))
  155. (Chi (chart coordinate-system)))
  156. (define* ((the-inverse-metric w1 w2) m)
  157. (let ((gcoeffs (->components (Chi m))))
  158. (* (* gcoeffs
  159. (s:map/r (lambda (e) ((w1 e) m))
  160. vector-basis))
  161. (s:map/r (lambda (e) ((w2 e) m))
  162. vector-basis))))
  163. (declare-argument-types! the-inverse-metric
  164. (list 1form-field? 1form-field?))
  165. the-inverse-metric))
  166. #|
  167. (s:map/r (lambda (w1)
  168. (s:map/r (lambda (w2)
  169. (((coordinate-system->inverse-metric R3-spherical) w1 w2)
  170. ((point R3-spherical) (up 'r 'theta 'phi))))
  171. (coordinate-system->1form-basis R3-spherical)))
  172. (coordinate-system->1form-basis R3-spherical))
  173. #|
  174. (up (up 1 0 0)
  175. (up 0 (/ 1 (expt r 2)) 0)
  176. (up 0 0 (/ 1 (* (expt r 2) (expt (sin theta) 2)))))
  177. |#
  178. |#
  179. ;;; Symbolic metrics are often useful for testing.
  180. (define (make-metric name coordinate-system)
  181. (define (gij i j)
  182. (if (<= i j)
  183. (literal-manifold-function
  184. (string->symbol
  185. (string-append (symbol->string name)
  186. "_"
  187. (number->string i)
  188. (number->string j)))
  189. coordinate-system)
  190. (gij j i)))
  191. gij)
  192. (define (literal-metric name coordinate-system)
  193. ;; Flat coordinate systems here only.
  194. (let ((basis (coordinate-system->basis coordinate-system)))
  195. (let ((1form-basis (basis->1form-basis basis))
  196. (gij (make-metric name coordinate-system)))
  197. (let ((n (s:dimension 1form-basis)))
  198. (let ((gcoeffs
  199. (s:generate n 'down
  200. (lambda (i)
  201. (s:generate n 'down
  202. (lambda (j)
  203. (gij i j)))))))
  204. (define (the-metric v1 v2)
  205. (* (* gcoeffs (1form-basis v1))
  206. (1form-basis v2)))
  207. (declare-argument-types! the-metric
  208. (list vector-field? vector-field?))
  209. the-metric)))))
  210. #|
  211. (install-coordinates R3-rect (up 'x 'y 'z))
  212. (set! *factoring* #f)
  213. (pec (((literal-metric 'g R3-rect)
  214. (literal-vector-field 'u R3-rect)
  215. (literal-vector-field 'v R3-rect))
  216. ((R3-rect '->point) (up 'x0 'y0 'z0))))
  217. #| Result:
  218. (+ (* (v^0 (up x0 y0 z0)) (u^0 (up x0 y0 z0)) (g_00 (up x0 y0 z0)))
  219. (* (v^0 (up x0 y0 z0)) (g_01 (up x0 y0 z0)) (u^1 (up x0 y0 z0)))
  220. (* (v^0 (up x0 y0 z0)) (g_02 (up x0 y0 z0)) (u^2 (up x0 y0 z0)))
  221. (* (u^0 (up x0 y0 z0)) (v^1 (up x0 y0 z0)) (g_01 (up x0 y0 z0)))
  222. (* (u^0 (up x0 y0 z0)) (v^2 (up x0 y0 z0)) (g_02 (up x0 y0 z0)))
  223. (* (v^1 (up x0 y0 z0)) (u^1 (up x0 y0 z0)) (g_11 (up x0 y0 z0)))
  224. (* (v^1 (up x0 y0 z0)) (g_12 (up x0 y0 z0)) (u^2 (up x0 y0 z0)))
  225. (* (v^2 (up x0 y0 z0)) (u^1 (up x0 y0 z0)) (g_12 (up x0 y0 z0)))
  226. (* (v^2 (up x0 y0 z0)) (u^2 (up x0 y0 z0)) (g_22 (up x0 y0 z0))))
  227. |#
  228. |#
  229. (define (components->metric components basis)
  230. (let ((1form-basis (basis->1form-basis basis)))
  231. (define (the-metric v1 v2)
  232. (* (1form-basis v1) (* components (1form-basis v2))))
  233. the-metric))
  234. #|
  235. ;;; Code below is OK
  236. (define ((metric->components metric basis) m)
  237. (let ((vector-basis (basis->vector-basis basis)))
  238. (s:map/r (lambda (e_i)
  239. (s:map/r (lambda (e_j)
  240. ((metric e_i e_j) m))
  241. vector-basis))
  242. vector-basis)))
  243. |#
  244. (define (metric->components metric basis)
  245. (let ((vector-basis (basis->vector-basis basis)))
  246. (s:map/r (lambda (e_i)
  247. (s:map/r (lambda (e_j)
  248. (metric e_i e_j))
  249. vector-basis))
  250. vector-basis)))
  251. ;;; Given a metric and a basis, to compute the inverse metric
  252. (define (metric->inverse-components metric basis)
  253. (define (the-coeffs m)
  254. (let ((g_ij ((metric->components metric basis) m))
  255. (1form-basis (basis->1form-basis basis)))
  256. (let ((g^ij
  257. (s:inverse (typical-object 1form-basis)
  258. g_ij
  259. (typical-object 1form-basis))))
  260. g^ij)))
  261. the-coeffs)
  262. #|
  263. ;;; This code seriously degrades performance, use version above.
  264. (define (metric->inverse-components metric basis)
  265. (let ((g_ij (metric->components metric basis))
  266. (1form-basis (basis->1form-basis basis)))
  267. (let ((g^ij
  268. (s:inverse (typical-object 1form-basis)
  269. g_ij
  270. (typical-object 1form-basis))))
  271. g^ij)))
  272. |#
  273. #|
  274. ;;; Code below is OK
  275. (define (metric:invert metric basis)
  276. (define (the-inverse-metric w1 w2)
  277. (lambda (m)
  278. (let ((vector-basis (basis->vector-basis basis))
  279. (g^ij ((metric->inverse-components metric basis) m)))
  280. (* (* g^ij ((s:map/r w1 vector-basis) m))
  281. ((s:map/r w2 vector-basis) m)))))
  282. (declare-argument-types! the-inverse-metric
  283. (list 1form-field? 1form-field?))
  284. the-inverse-metric)
  285. |#
  286. (define (metric:invert metric basis)
  287. (define (the-inverse-metric w1 w2)
  288. (let ((vector-basis (basis->vector-basis basis))
  289. (g^ij (metric->inverse-components metric basis)))
  290. (* (* g^ij (s:map/r w1 vector-basis))
  291. (s:map/r w2 vector-basis))))
  292. (declare-argument-types! the-inverse-metric
  293. (list 1form-field? 1form-field?))
  294. the-inverse-metric)
  295. #|
  296. (install-coordinates R2-rect (up 'x 'y))
  297. (define R2-basis (coordinate-system->basis R2-rect))
  298. (define ((g-R2 g_00 g_01 g_11) u v)
  299. (+ (* g_00 (dx u) (dx v))
  300. (* g_01 (+ (* (dx u) (dy v)) (* (dy u) (dx v))))
  301. (* g_11 (dy u) (dy v))))
  302. (pec (((metric:invert (g-R2 'a 'b 'c) R2-basis)
  303. (literal-1form-field 'omega R2-rect)
  304. (literal-1form-field 'theta R2-rect))
  305. ((R2-rect '->point) (up 'x0 'y0))))
  306. #| Result:
  307. (/ (+ (* a (theta_1 (up x0 y0)) (omega_1 (up x0 y0)))
  308. (* -1 b (theta_1 (up x0 y0)) (omega_0 (up x0 y0)))
  309. (* -1 b (omega_1 (up x0 y0)) (theta_0 (up x0 y0)))
  310. (* c (omega_0 (up x0 y0)) (theta_0 (up x0 y0))))
  311. (+ (* a c) (* -1 (expt b 2))))
  312. |#
  313. ;;; Test of inversion
  314. (pec
  315. (let* ((g (g-R2 'a 'b 'c))
  316. (gi (metric:invert g R2-basis))
  317. (vector-basis (list d/dx d/dy))
  318. (dual-basis (list dx dy))
  319. (m ((R2-rect '->point) (up 'x0 'y0))))
  320. (matrix:generate 2 2
  321. (lambda (i k)
  322. (sigma (lambda (j)
  323. (* ((gi (ref dual-basis i) (ref dual-basis j)) m)
  324. ((g (ref vector-basis j) (ref vector-basis k)) m)))
  325. 0 1)))))
  326. #| Result:
  327. (matrix-by-rows (list 1 0) (list 0 1))
  328. |#
  329. |#
  330. ;;; over a map
  331. (define (metric-over-map mu:N->M g-on-M)
  332. (define (vector-field-over-map->vector-field V-over-mu n)
  333. ;; This helper has no clear meaning.
  334. (procedure->vector-field
  335. (lambda (f)
  336. (lambda (m)
  337. ;;(assert (= m (mu:N->M n)))
  338. ((V-over-mu f) n)))
  339. `(vector-field-over-map->vector-field
  340. ,(diffop-name V-over-mu))))
  341. (define (the-metric v1 v2)
  342. (lambda (n)
  343. ((g-on-M
  344. (vector-field-over-map->vector-field v1 n)
  345. (vector-field-over-map->vector-field v2 n))
  346. (mu:N->M n))))
  347. (declare-argument-types! the-metric
  348. (list vector-field? vector-field?))
  349. the-metric)
  350. ;;; Raising and lowering indices...
  351. ;;; To make a vector field into a one-form field
  352. ;;; ie a (1,0) tensor into a (0,1) tensor
  353. (define* ((lower metric) u)
  354. (define (omega v)
  355. (metric v u))
  356. (procedure->1form-field omega
  357. `(lower ,(diffop-name u)
  358. ,(diffop-name metric))))
  359. (define vector-field->1form-field lower)
  360. (define drop1 lower)
  361. ;;; To make a one-form field into a vector field
  362. ;;; ie a (0,1) tensor into a (1,0) tensor
  363. (define (raise metric basis)
  364. (let ((gi (metric:invert metric basis)))
  365. (lambda (omega)
  366. (define v
  367. (contract (lambda (e_i e~i)
  368. (* (gi omega e~i) e_i))
  369. basis))
  370. (procedure->vector-field v
  371. `(raise ,(diffop-name omega)
  372. ,(diffop-name metric))))))
  373. (define 1form-field->vector-field raise)
  374. (define raise1 raise)
  375. ;;; For making a (2,0) tensor into a (0,2) tensor
  376. (define* ((drop2 metric-tensor basis) tensor)
  377. (define (omega v1 v2)
  378. (contract
  379. (lambda (e1 w1)
  380. (contract
  381. (lambda (e2 w2)
  382. (* (metric-tensor v1 e1)
  383. (tensor w1 w2)
  384. (metric-tensor e2 v2)))
  385. basis))
  386. basis))
  387. (declare-argument-types! omega (list vector-field? vector-field?))
  388. omega)
  389. ;;; For making a (0,2) tensor into a (2,0) tensor
  390. (define (raise2 metric-tensor basis)
  391. (let ((gi (metric:invert metric-tensor basis)))
  392. (lambda (tensor02)
  393. (define (v2 omega1 omega2)
  394. (contract
  395. (lambda (e1 w1)
  396. (contract
  397. (lambda (e2 w2)
  398. (* (gi omega1 w1)
  399. (tensor02 e1 e2)
  400. (gi w2 omega2)))
  401. basis))
  402. basis))
  403. (declare-argument-types! v2 (list 1form-field? 1form-field?))
  404. v2)))
  405. ;;; To compute the trace of a (0,2) tensor
  406. (define (trace2down metric-tensor basis)
  407. (let ((inverse-metric-tensor
  408. (metric:invert metric-tensor basis)))
  409. (lambda (tensor02)
  410. (define f
  411. (contract
  412. (lambda (e1 w1)
  413. (contract
  414. (lambda (e2 w2)
  415. (* (inverse-metric-tensor w1 w2)
  416. (tensor02 e1 e2)))
  417. basis))
  418. basis))
  419. (declare-argument-types! f (list function?))
  420. f)))
  421. ;;; To compute the trace of a (2,0) tensor
  422. (define* ((trace2up metric-tensor basis) tensor20)
  423. (define f
  424. (contract
  425. (lambda (e1 w1)
  426. (contract
  427. (lambda (e2 w2)
  428. (* (metric-tensor e1 e2)
  429. (tensor20 w1 w2)))
  430. basis))
  431. basis))
  432. (declare-argument-types! f (list function?))
  433. f)
  434. ;;; Note: raise needs an extra argument -- the basis -- why?
  435. #|
  436. (pec
  437. ((((lower (g-R2 'a 'b 'c))
  438. (literal-vector-field 'v R2-rect))
  439. (literal-vector-field 'w R2-rect))
  440. ((R2-rect '->point) (up 'x0 'y0))))
  441. #| Result:
  442. (+ (* a (v^0 (up x0 y0)) (w^0 (up x0 y0)))
  443. (* b (v^0 (up x0 y0)) (w^1 (up x0 y0)))
  444. (* b (v^1 (up x0 y0)) (w^0 (up x0 y0)))
  445. (* c (v^1 (up x0 y0)) (w^1 (up x0 y0))))
  446. |#
  447. (pec
  448. ((((raise (g-R2 'a 'b 'c) R2-basis)
  449. ((lower (g-R2 'a 'b 'c)) (literal-vector-field 'v R2-rect)))
  450. (compose (literal-function 'w (-> (UP Real Real) Real))
  451. (R2-rect '->coords)))
  452. ((R2-rect '->point) (up 'x0 'y0))))
  453. #| Result:
  454. (+ (* (v^0 (up x0 y0)) (((partial 0) w) (up x0 y0)))
  455. (* (v^1 (up x0 y0)) (((partial 1) w) (up x0 y0))))
  456. |#
  457. |#
  458. ;;; Unfortunately raise is very expensive because the matrix is
  459. ;;; inverted for each manifold point.
  460. (define (sharpen metric basis m)
  461. (let ((g^ij ((metric->inverse-components metric basis) m))
  462. (vector-basis (basis->vector-basis basis))
  463. (1form-basis (basis->1form-basis basis)))
  464. (define (sharp 1form-field)
  465. (let ((1form-coeffs
  466. (s:map/r (lambda (ei) ((1form-field ei) m))
  467. vector-basis)))
  468. (let ((vector-coeffs (* g^ij 1form-coeffs)))
  469. (s:sigma/r * vector-coeffs vector-basis))))
  470. sharp))
  471. #|
  472. (pec
  473. ((((sharpen (g-R2 'a 'b 'c) R2-basis ((R2-rect '->point) (up 'x0 'y0)))
  474. ((lower (g-R2 'a 'b 'c)) (literal-vector-field 'v R2-rect)))
  475. (compose (literal-function 'w (-> (UP Real Real) Real))
  476. (R2-rect '->coords)))
  477. ((R2-rect '->point) (up 'x0 'y0))))
  478. #| Result:
  479. (up (* (v^0 (up x0 y0)) (((partial 0) w) (up x0 y0)))
  480. (* (v^1 (up x0 y0)) (((partial 1) w) (up x0 y0))))
  481. |#
  482. |#
  483. ;;; Useful metrics
  484. (define S2-metric
  485. (let* ((chart
  486. (S2-spherical 'coordinate-functions))
  487. (theta (ref chart 0))
  488. (phi (ref chart 1))
  489. (1form-basis
  490. (S2-spherical 'coordinate-basis-1form-fields))
  491. (dtheta (ref 1form-basis 0))
  492. (dphi (ref 1form-basis 1)))
  493. (define (the-metric v1 v2)
  494. (+ (* (dtheta v1) (dtheta v2))
  495. (* (expt (sin theta) 2)
  496. (dphi v1) (dphi v2))))
  497. (declare-argument-types! the-metric
  498. (list vector-field? vector-field?))
  499. the-metric))