manifold.scm 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651
  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. ;;;; Manifolds are built here.
  21. (define-record-type manifold-point
  22. (%make-manifold-point spec manifold)
  23. manifold-point?
  24. (spec manifold-point-representation)
  25. (manifold point->manifold)
  26. (coordinate-representations coordinate-reps set-coordinate-reps!))
  27. (define (make-manifold-point spec manifold coordinate-system coordinate-rep)
  28. (let ((m (%make-manifold-point spec manifold)))
  29. (set-coordinate-reps! m (list (list coordinate-system coordinate-rep)))
  30. m))
  31. (define (transfer-point embedded embedding)
  32. (lambda (point)
  33. (assert (eq? (embedded 'manifold) (point->manifold point)))
  34. (assert (= ((embedded 'manifold) 'embedding-dimension)
  35. ((embedding 'manifold) 'embedding-dimension)))
  36. (let ((m (%make-manifold-point
  37. (manifold-point-representation point)
  38. (embedding 'manifold))))
  39. (set-coordinate-reps! m '())
  40. m)))
  41. ;;; A Kludge.
  42. (define (get-coordinate-rep point)
  43. ;(assert (eq? ((point->manifold point) 'name) manifold-name))
  44. (let ((rep
  45. (find (lambda (rep)
  46. ;(eq? ((car rep) 'name) chart-name)
  47. #t)
  48. (coordinate-reps point))))
  49. (assert rep)
  50. (cadr rep)))
  51. (define (get-coordinates point coordinate-system thunk)
  52. (let ((entry (assq coordinate-system (coordinate-reps point))))
  53. (if entry
  54. (cadr entry)
  55. (let ((val (s:map/r simplify-numerical-expression (thunk))))
  56. (set-coordinate-reps! point
  57. (cons (list coordinate-system val)
  58. (coordinate-reps point)))
  59. val))))
  60. (define (my-manifold-point? point manifold)
  61. (and (manifold-point? point)
  62. (eq? (point->manifold point) manifold)))
  63. ;;; There is a kludge in this system... A single coordinate is just
  64. ;;; the number:
  65. (define (c:generate n type proc)
  66. (if (fix:= n 1)
  67. (proc 0)
  68. (s:generate n type proc)))
  69. (define (c:lookup m struct)
  70. (if (structure? struct)
  71. (assq m
  72. (vector->list
  73. (if (up? struct)
  74. (up->vector struct)
  75. (down->vector struct))))
  76. struct))
  77. (define* (specify-manifold manifold-name #:optional type)
  78. (if (default-object? type) (set! type Real))
  79. (let ((patches '()) (counter 0) (distinguished-points '()))
  80. (define* (generator dimension #:optional embedding-dimension)
  81. (assert (exact-integer? dimension))
  82. (if (default-object? embedding-dimension)
  83. (set! embedding-dimension dimension)
  84. (assert (and (exact-integer? embedding-dimension)
  85. (fix:>= embedding-dimension dimension))))
  86. (set! counter (+ counter 1))
  87. (let ((name
  88. (symbol (let* ((namestring (symbol->string manifold-name))
  89. (i (string-search-forward "^n" namestring)))
  90. (if i
  91. (string->symbol
  92. (string-append (string-head namestring i)
  93. "^"
  94. (number->string dimension)))
  95. manifold-name))
  96. '-
  97. counter)))
  98. (define (the-manifold m)
  99. (case m
  100. ((name manifold-name) name)
  101. ((manifold) the-manifold)
  102. ((type manifold-type) type)
  103. ((dimension manifold-dimension) dimension)
  104. ((embedding-dimension) embedding-dimension)
  105. ((get-patch)
  106. (lambda (patch-name)
  107. (let ((patch-entry (assq patch-name patches)))
  108. (if patch-entry
  109. ((cadr patch-entry) the-manifold)
  110. (error "Unknown patch" patch-name name)))))
  111. ((distinguished-points) distinguished-points)
  112. ((add-distinguished-point!)
  113. (lambda (sspec m)
  114. (set! distinguished-points
  115. (cons (list sspec m) distinguished-points))))
  116. ((patch-names)
  117. (map car patches))
  118. (else
  119. (error "Unknown message: manifold generator" m))))
  120. the-manifold))
  121. (define (setup m)
  122. (case m
  123. ((new-patch)
  124. (lambda (new-patch-name patch-generator patch-setup)
  125. (set! patches
  126. (cons (list new-patch-name
  127. patch-generator
  128. patch-setup)
  129. patches))))
  130. ((patch-setup)
  131. (lambda (patch-name)
  132. (let ((patch-entry (assq patch-name patches)))
  133. (if patch-entry
  134. (caddr patch-entry)
  135. (error "Unknown patch" patch-name)))))
  136. ((generator) generator)
  137. (else (error "Unknown message: manifold setup" m))))
  138. setup))
  139. ;;; Coordinate patches are added to manifolds.
  140. (define (patch patch-name manifold)
  141. ((manifold 'get-patch) patch-name))
  142. (define (attach-patch patch-name manifold-spec)
  143. (let ((coordinate-systems '()))
  144. (define (patch-generator manifold)
  145. (define (the-patch m)
  146. (case m
  147. ((name patch-name) patch-name)
  148. ((patch) the-patch)
  149. ((get-coordinate-system)
  150. (lambda (coordinate-system-name)
  151. (let ((coordinate-system-entry
  152. (assq coordinate-system-name
  153. coordinate-systems)))
  154. (if coordinate-system-entry
  155. ((cdr coordinate-system-entry) the-patch)
  156. (error "Unknown coordinate-system"
  157. coordinate-system-name patch-name)))))
  158. ((coordinate-system-names)
  159. (map car coordinate-systems))
  160. (else (manifold m) ; pass the buck.
  161. ;; (error "unknown message: patch" m)
  162. )))
  163. the-patch)
  164. (define (patch-setup m)
  165. (case m
  166. ((new-coordinate-system)
  167. (lambda (new-coordinate-system-name new-coordinate-system)
  168. (set! coordinate-systems
  169. (cons (cons new-coordinate-system-name
  170. new-coordinate-system)
  171. coordinate-systems))))
  172. ((generator) patch-generator)
  173. (else (error "Unknown message patch-setup" m))))
  174. ((manifold-spec 'new-patch)
  175. patch-name patch-generator patch-setup)
  176. patch-name))
  177. (define (coordinate-system coordinate-system-name patch)
  178. ((patch 'get-coordinate-system) coordinate-system-name))
  179. (define (coordinate-system-at coordinate-system-name patch-name manifold)
  180. (coordinate-system coordinate-system-name
  181. (patch patch-name manifold)))
  182. (define (make-manifold manifold-type . args)
  183. (apply (manifold-type 'generator) args))
  184. ;;; Coordinate systems are added to coordinate patches.
  185. ;;; A coordinate system is an invertible map from the space to R^n.
  186. (define* (attach-coordinate-system coordinate-system-name
  187. patch-name
  188. manifold-type
  189. transformations
  190. #:optional coordinate-prototype)
  191. (define (the-coordinate-system-generator the-patch)
  192. (let* ((manifold (the-patch 'manifold))
  193. (transform-delivery (transformations manifold))
  194. (coordinate-prototype
  195. (if (default-object? coordinate-prototype)
  196. (c:generate (manifold 'dimension) 'up
  197. (lambda (i) (symbol 'x i)))
  198. (begin
  199. (assert
  200. (fix:= (manifold 'dimension)
  201. (s:dimension coordinate-prototype)))
  202. coordinate-prototype)))
  203. (access-chains
  204. (s:map-chain (lambda (element chain) chain)
  205. coordinate-prototype))
  206. (dual-chains (flip-indices access-chains)))
  207. (let ((coordinate-function-specs #f)
  208. (coordinate-basis-vector-field-specs #f)
  209. (coordinate-basis-1form-field-specs #f)
  210. (coordinate-basis #f))
  211. (define (the-coordinate-system m)
  212. (case m
  213. ((name coordinate-system-name)
  214. coordinate-system-name)
  215. ((patch) the-patch)
  216. ((->point) (transform-delivery 'coords->point))
  217. ((->coords) (transform-delivery 'point->coords))
  218. ((check-point) (transform-delivery 'check-point))
  219. ((check-coords) (transform-delivery 'check-coords))
  220. ((typical-coords)
  221. (typical-object coordinate-prototype))
  222. ((coordinate-prototype) coordinate-prototype)
  223. ((set-coordinate-prototype!)
  224. (lambda (new)
  225. (assert (fix:= (manifold 'dimension) (s:dimension new)))
  226. (set! coordinate-prototype new)
  227. (set! access-chains
  228. (s:map-chain (lambda (element chain) chain)
  229. coordinate-prototype))
  230. (set! coordinate-function-specs #f)
  231. (set! coordinate-basis-vector-field-specs #f)
  232. (set! coordinate-basis-1form-field-specs #f)
  233. (set! coordinate-basis #f)))
  234. ((access-chains) access-chains)
  235. ((dual-chains) dual-chains)
  236. ((coordinate-function-specs)
  237. (if (not coordinate-function-specs)
  238. (set! coordinate-function-specs
  239. (s:map/r
  240. (lambda (coordinate-name access-chain)
  241. (list coordinate-name
  242. (compose
  243. (apply component access-chain)
  244. (transform-delivery 'point->coords))))
  245. coordinate-prototype
  246. access-chains)))
  247. coordinate-function-specs)
  248. ((coordinate-basis-vector-field-specs)
  249. (if (not coordinate-basis-vector-field-specs)
  250. (set! coordinate-basis-vector-field-specs
  251. (flip-indices
  252. (s:map/r
  253. (lambda (coordinate-name access-chain)
  254. (let* ((oname (symbol 'd/d coordinate-name))
  255. (vf
  256. (apply coordinate-basis-vector-field
  257. the-coordinate-system
  258. oname
  259. access-chain)))
  260. (set-operator-optionals! vf
  261. (cons `(manifold ,manifold)
  262. (operator-optionals vf)))
  263. (list oname vf)))
  264. coordinate-prototype
  265. access-chains))))
  266. coordinate-basis-vector-field-specs)
  267. ((coordinate-basis-1form-field-specs)
  268. (if (not coordinate-basis-1form-field-specs)
  269. (set! coordinate-basis-1form-field-specs
  270. (s:map/r
  271. (lambda (coordinate-name access-chain)
  272. (let* ((oname (symbol 'd coordinate-name))
  273. (ff
  274. (apply coordinate-basis-1form-field
  275. the-coordinate-system
  276. oname
  277. access-chain)))
  278. (set-operator-optionals! ff
  279. (cons `(manifold ,manifold)
  280. (operator-optionals ff)))
  281. (list oname ff)))
  282. coordinate-prototype
  283. access-chains)))
  284. coordinate-basis-1form-field-specs)
  285. ((coordinate-basis)
  286. (if (not coordinate-basis)
  287. (set! coordinate-basis
  288. (coordinate-system->basis the-coordinate-system)))
  289. coordinate-basis)
  290. ((coordinate-functions)
  291. (s:map/r cadr
  292. (the-coordinate-system
  293. 'coordinate-function-specs)))
  294. ((coordinate-basis-vector-fields)
  295. (s:map/r cadr
  296. (the-coordinate-system
  297. 'coordinate-basis-vector-field-specs)))
  298. ((coordinate-basis-1form-fields)
  299. (s:map/r cadr
  300. (the-coordinate-system
  301. 'coordinate-basis-1form-field-specs)))
  302. (else
  303. (cond ((symbol? m) (manifold m)) ;pass the buck.
  304. ((c:lookup m
  305. (the-coordinate-system
  306. 'coordinate-function-specs))
  307. => cadr)
  308. ((c:lookup m
  309. (the-coordinate-system
  310. 'coordinate-basis-vector-field-specs))
  311. => cadr)
  312. ((c:lookup m
  313. (the-coordinate-system
  314. 'coordinate-basis-1form-field-specs))
  315. => cadr)
  316. (else (error "bad message" m))))))
  317. the-coordinate-system)))
  318. ((((manifold-type 'patch-setup) patch-name)
  319. 'new-coordinate-system)
  320. coordinate-system-name the-coordinate-system-generator)
  321. coordinate-system-name)
  322. (define (coordinate-system-dimension coordinate-system)
  323. (coordinate-system 'dimension))
  324. ;;; FBE: we define this function in '(scmutils base).
  325. ;; ;;; So that the generic operation can get this.
  326. ;; (environment-define scmutils-base-environment
  327. ;; 'coordinate-system-dimension
  328. ;; coordinate-system-dimension)
  329. (define (frame? x)
  330. (and (procedure? x)
  331. ;; Kludge. See frame-maker.scm
  332. (not (x 'manifold))))
  333. (define (chart coordinate-system)
  334. (if (frame? coordinate-system)
  335. (event->coords coordinate-system)
  336. (coordinate-system '->coords)))
  337. (define (point coordinate-system)
  338. (if (frame? coordinate-system)
  339. (coords->event coordinate-system)
  340. (coordinate-system '->point)))
  341. (define (typical-point coordinate-system)
  342. ((point coordinate-system)
  343. (typical-coords coordinate-system)))
  344. (define (typical-coords coordinate-system)
  345. (s:map/r generate-uninterned-symbol
  346. (coordinate-system 'coordinate-prototype)))
  347. (define (corresponding-velocities coords)
  348. (s:map/r (lambda (x)
  349. (string->uninterned-symbol
  350. (string-append "v:"
  351. (symbol->string x))))
  352. coords))
  353. ;;; This adds names to the generic environment for the coordinate
  354. ;;; functions, the coordinate-basis vector fields and 1form fields.
  355. ;;; The names are generated from the coordinate prototype.
  356. ;;; E.g. if the coordinate prototype is (up 'r 'theta)
  357. ;;; r and theta become coordinate functions
  358. ;;; d/dr and d/dtheta are coordinate basis vector fields
  359. ;;; dr and dtheta are coordinate 1form fields.
  360. (define* (install-coordinates coordinate-system
  361. #:optional coordinate-prototype)
  362. (define (install-symbol name value)
  363. (if (environment-bound? user-generic-environment name)
  364. (begin
  365. (write-line `(clobbering ,name))
  366. (*saved-environment-values*
  367. (cons (cons name
  368. (environment-lookup user-generic-environment
  369. name))
  370. (*saved-environment-values*)))))
  371. (environment-define user-generic-environment name value))
  372. (define (install-symbols s)
  373. (s:foreach (lambda (symval)
  374. (install-symbol (car symval) (cadr symval)))
  375. s))
  376. (if (not (default-object? coordinate-prototype))
  377. ((coordinate-system 'set-coordinate-prototype!) coordinate-prototype))
  378. (install-symbols (coordinate-system 'coordinate-function-specs))
  379. (install-symbols (coordinate-system 'coordinate-basis-vector-field-specs))
  380. (install-symbols (coordinate-system 'coordinate-basis-1form-field-specs))
  381. (list (coordinate-system 'name) ((coordinate-system 'manifold) 'name)))
  382. ;;; FBE: make parameter
  383. (define *saved-environment-values* (make-parameter '()))
  384. (define (uninstall-coordinates)
  385. (for-each (lambda (saved-values)
  386. (environment-assign! user-generic-environment
  387. (car saved-values)
  388. (cdr saved-values)))
  389. (*saved-environment-values*))
  390. (*saved-environment-values* '())
  391. 'done)
  392. ;;;; Common manifolds
  393. (define R^n (specify-manifold 'R^n))
  394. (define R^n-type R^n)
  395. (define %calculus-manifold-dummy-1
  396. (begin
  397. (attach-patch 'origin R^n)
  398. (attach-coordinate-system 'rectangular 'origin R^n
  399. (lambda (manifold)
  400. (define (me m)
  401. (case m
  402. ((check-coordinates)
  403. (lambda (coords)
  404. (fix:= (s:dimension coords) (manifold 'dimension))))
  405. ((coords->point)
  406. (lambda (coords)
  407. (if ((me 'check-coordinates) coords)
  408. (make-manifold-point coords manifold me coords)
  409. (error "Bad coordinates: rectangular" coords me))))
  410. ((check-point)
  411. (lambda (point)
  412. (my-manifold-point? point manifold)))
  413. ((point->coords)
  414. (lambda (point)
  415. (if (not ((me 'check-point) point))
  416. (error "Bad point: rectangular" point me))
  417. (get-coordinates point me
  418. (lambda ()
  419. (let ((prep (manifold-point-representation point)))
  420. (if (fix:= (s:dimension prep)
  421. (manifold 'embedding-dimension))
  422. prep
  423. (error "Bad point: rectangular" point me)))))))
  424. ((manifold) manifold)
  425. (else (error "Bad message: rectangular" m me))))
  426. me))
  427. (attach-coordinate-system 'polar/cylindrical 'origin R^n
  428. (lambda (manifold)
  429. (define (me m)
  430. (case m
  431. ((check-coordinates)
  432. (lambda (coords)
  433. (and (up? coords)
  434. (fix:= (s:dimension coords) (manifold 'dimension))
  435. (not (fix:< (s:dimension coords) 2))
  436. (or (not (number? (ref coords 0)))
  437. (not (< (ref coords 0) 0))))))
  438. ((coords->point)
  439. (lambda (coords)
  440. (if ((me 'check-coordinates) coords)
  441. (let ((r (ref coords 0)) (theta (ref coords 1)))
  442. (make-manifold-point
  443. (s:generate (s:dimension coords) 'up
  444. (lambda (i)
  445. (cond ((= i 0) (* r (cos theta)))
  446. ((= i 1) (* r (sin theta)))
  447. (else (ref coords i)))))
  448. manifold
  449. me
  450. coords))
  451. (error "Bad coordinates: polar/cylindrical"
  452. coords me))))
  453. ((check-point)
  454. (lambda (point)
  455. (my-manifold-point? point manifold)))
  456. ((point->coords)
  457. (lambda (point)
  458. (if (not ((me 'check-point) point))
  459. (error "Bad point: polar/cylindrial" point me))
  460. (get-coordinates point me
  461. (lambda ()
  462. (let ((prep (manifold-point-representation point)))
  463. (if (and (up? prep)
  464. (fix:= (s:dimension prep)
  465. (manifold 'embedding-dimension)))
  466. (let ((x (ref prep 0)) (y (ref prep 1)))
  467. (let ((rsq (+ (square x) (square y))))
  468. (if (and (number? rsq) (= rsq 0))
  469. (error "polar/cylindrical singular"
  470. point me))
  471. (s:generate (s:dimension prep) 'up
  472. (lambda (i)
  473. (cond ((= i 0) (sqrt rsq))
  474. ((= i 1) (atan y x))
  475. (else (ref prep i)))))))
  476. (error "Bad point: polar/cylindrial"
  477. point me)))))))
  478. ((manifold) manifold)
  479. (else
  480. (error "Bad message: polar/cylindrical" m me))))
  481. me))
  482. (attach-coordinate-system 'spherical/cylindrical 'origin R^n
  483. (lambda (manifold)
  484. (define (me m)
  485. (case m
  486. ((check-coordinates)
  487. (lambda (coords)
  488. (and (up? coords)
  489. (fix:= (s:dimension coords) (manifold 'dimension))
  490. (not (fix:< (s:dimension coords) 3))
  491. (or (not (number? (ref coords 0)))
  492. (not (< (ref coords 0) 0))))))
  493. ((coords->point)
  494. (lambda (coords)
  495. (if ((me 'check-coordinates) coords)
  496. (let ((r (ref coords 0))
  497. (theta (ref coords 1))
  498. (phi (ref coords 2)))
  499. (make-manifold-point
  500. (s:generate (s:dimension coords) 'up
  501. (lambda (i)
  502. (cond ((= i 0) (* r (sin theta) (cos phi)))
  503. ((= i 1) (* r (sin theta) (sin phi)))
  504. ((= i 2) (* r (cos theta)))
  505. (else (ref coords i)))))
  506. manifold
  507. me
  508. coords))
  509. (error "Bad coordinates: spherical/cylindrical"
  510. coords me))))
  511. ((check-point)
  512. (lambda (point) (my-manifold-point? point manifold)))
  513. ((point->coords)
  514. (lambda (point)
  515. (if (not ((me 'check-point) point))
  516. (error "Bad point: spherical/cylindrial" point me))
  517. (get-coordinates point me
  518. (lambda ()
  519. (let ((prep (manifold-point-representation point)))
  520. (if (and (up? prep)
  521. (fix:= (s:dimension prep)
  522. (manifold 'embedding-dimension)))
  523. (let ((x (ref prep 0))
  524. (y (ref prep 1))
  525. (z (ref prep 2)))
  526. (let ((r (sqrt
  527. (+ (square x) (square y) (square z)))))
  528. (if (and (number? r) (= r 0))
  529. (error "spherical/cylindrical singular"
  530. point me))
  531. (s:generate (s:dimension prep) 'up
  532. (lambda (i)
  533. (cond ((= i 0) r)
  534. ((= i 1) (acos (/ z r)))
  535. ((= i 2) (atan y x))
  536. (else (ref prep i)))))))
  537. (error "Bad point: spherical/cylindrial"
  538. point me)))))))
  539. ((manifold) manifold)
  540. (else
  541. (error "Bad message: spherical/cylindrical" m me))))
  542. me))
  543. ;;; For R4 only
  544. (attach-coordinate-system 'spacetime-spherical 'origin R^n
  545. (lambda (manifold)
  546. (define (me m)
  547. (case m
  548. ((check-coordinates)
  549. (lambda (coords)
  550. (and (up? coords) (fix:= (s:dimension coords) 4))))
  551. ((coords->point)
  552. (lambda (coords)
  553. (if ((me 'check-coordinates) coords)
  554. (let ((t (ref coords 0))
  555. (r (ref coords 1))
  556. (theta (ref coords 2))
  557. (phi (ref coords 3)))
  558. (make-manifold-point
  559. (up t
  560. (* r (sin theta) (cos phi))
  561. (* r (sin theta) (sin phi))
  562. (* r (cos theta)))
  563. manifold
  564. me
  565. coords))
  566. (error "Bad coordinates: spacetime-spherical"
  567. coords me))))
  568. ((check-point)
  569. (lambda (point)
  570. (my-manifold-point? point manifold)))
  571. ((point->coords)
  572. (lambda (point)
  573. (if (not ((me 'check-point) point))
  574. (error "Bad point: spacetime-spherical" point me))
  575. (get-coordinates point me
  576. (lambda ()
  577. (let ((prep (manifold-point-representation point)))
  578. (if (and (up? prep) (fix:= (s:dimension prep) 4))
  579. (let ((t (ref prep 0))
  580. (x (ref prep 1))
  581. (y (ref prep 2))
  582. (z (ref prep 3)))
  583. (let ((r (sqrt (+ (square x) (square y) (square z)))))
  584. (if (and (number? r) (= r 0))
  585. (error "spacetime-spherical singular" point me))
  586. (up t
  587. r
  588. (acos (/ z r))
  589. (atan y x))))
  590. (error "Bad point: spacetime-spherical" point me)))))))
  591. ((manifold) manifold)
  592. (else (error "Bad message: spacetime-spherical" m me))))
  593. me))))
  594. (define R1 (make-manifold R^n 1))
  595. (define R1-rect (coordinate-system-at 'rectangular 'origin R1))
  596. (define the-real-line R1-rect)
  597. (define R2 (make-manifold R^n 2))
  598. (define R2-rect (coordinate-system-at 'rectangular 'origin R2))
  599. (define R2-polar (coordinate-system-at 'polar/cylindrical 'origin R2))
  600. (define R3 (make-manifold R^n 3))
  601. (define R3-rect (coordinate-system-at 'rectangular 'origin R3))
  602. (define R3-cyl (coordinate-system-at 'polar/cylindrical 'origin R3))
  603. (define R3-spherical
  604. (coordinate-system-at 'spherical/cylindrical 'origin R3))
  605. (define R4 (make-manifold R^n 4))
  606. (define R4-rect (coordinate-system-at 'rectangular 'origin R4))
  607. (define R4-cyl (coordinate-system-at 'polar/cylindrical 'origin R4))
  608. (define spacetime (make-manifold R^n 4))
  609. (define spacetime-rect
  610. (coordinate-system-at 'rectangular 'origin spacetime))
  611. (define spacetime-sphere
  612. (coordinate-system-at 'spacetime-spherical 'origin spacetime))
  613. #|
  614. (define m ((R2-rect '->point) (up 3 4)))
  615. ((R2-polar '->coords) m)
  616. ;Value: #(5 .9272952180016122)
  617. (install-coordinates R2-rect (up 'x 'y))
  618. (install-coordinates R2-polar (up 'r 'theta))
  619. (define mr ((R2-rect '->point) (up 'x0 'y0)))
  620. (define mp ((R2-polar '->point) (up 'r0 'theta0)))
  621. (define circular (- (* x d/dy) (* y d/dx)))
  622. (pec ((circular (+ (* 2 x) (* 3 y))) mr))
  623. #| Result:
  624. (+ (* 3 x0) (* -2 y0))
  625. |#
  626. (pec ((circular theta) mr))
  627. #| Result:
  628. 1
  629. |#
  630. (pec ((dr circular) mr))
  631. #| Result:
  632. 0
  633. |#
  634. (pec (((d r) d/dr) mr))
  635. #| Result:
  636. 1
  637. |#
  638. (pec ((dr d/dr) mr))
  639. #| Result:
  640. 1
  641. |#
  642. (pec ((dr (literal-vector-field 'v R2-polar)) mr))
  643. #| Result:
  644. (v^0 (up (sqrt (+ (expt x0 2) (expt y0 2))) (atan y0 x0)))
  645. |#
  646. (pec (((d r) (literal-vector-field 'v R2-polar)) mr))
  647. #| Result:
  648. (v^0 (up (sqrt (+ (expt x0 2) (expt y0 2))) (atan y0 x0)))
  649. |#
  650. (pec ((dr (literal-vector-field 'v R2-rect)) mr))
  651. #| Result:
  652. (+ (/ (* x0 (v^0 (up x0 y0))) (sqrt (+ (expt x0 2) (expt y0 2))))
  653. (/ (* y0 (v^1 (up x0 y0))) (sqrt (+ (expt x0 2) (expt y0 2)))))
  654. |#
  655. (pec (((d r) (literal-vector-field 'v R2-rect)) mr))
  656. #| Result:
  657. (+ (/ (* x0 (v^0 (up x0 y0))) (sqrt (+ (expt x0 2) (expt y0 2))))
  658. (/ (* y0 (v^1 (up x0 y0))) (sqrt (+ (expt x0 2) (expt y0 2)))))
  659. |#
  660. ;;; Consider the two following metrics on the space
  661. (define (g-polar u v)
  662. (+ (* (dr u) (dr v))
  663. (* (* r (dtheta u)) (* r (dtheta v)))))
  664. (define (g-rect u v)
  665. (+ (* (dx u) (dx v))
  666. (* (dy u) (dy v))))
  667. (pec (((- g-polar g-rect)
  668. (literal-vector-field 'v R2-rect)
  669. (literal-vector-field 'v R2-rect))
  670. mr))
  671. #| Result:
  672. 0
  673. |#
  674. (pec (((- g-polar g-rect)
  675. (literal-vector-field 'v R2-polar)
  676. (literal-vector-field 'v R2-polar))
  677. mr))
  678. #| Result:
  679. 0
  680. |#
  681. (pec (((- g-polar g-rect)
  682. (literal-vector-field 'v R2-polar)
  683. (literal-vector-field 'v R2-polar))
  684. mp))
  685. #| Result:
  686. 0
  687. |#
  688. (pec (((- g-polar g-rect)
  689. (literal-vector-field 'v R2-rect)
  690. (literal-vector-field 'v R2-rect))
  691. mp))
  692. #| Result:
  693. 0
  694. |#
  695. |#
  696. ;;; The surface of the sphere, specialized to two dimensions.
  697. (define S^2-type (specify-manifold 'S^2))
  698. (define (S^2-coordinates orientation)
  699. (let ((orientation^-1 (invert orientation)))
  700. (lambda (manifold)
  701. (define (me m)
  702. (define (coordinates-ok? coords)
  703. (and (up? coords)
  704. (fix:= (s:dimension coords) 2)
  705. (or (not (number? (ref coords 0)))
  706. (not (< (ref coords 0) 0)))))
  707. (case m
  708. ((check-coordinates) coordinates-ok?)
  709. ((coords->point)
  710. (lambda (coords)
  711. (if (coordinates-ok? coords)
  712. (let ((colatitude (ref coords 0))
  713. (longitude (ref coords 1)))
  714. (make-manifold-point
  715. (* orientation
  716. (up (* (sin colatitude) (cos longitude))
  717. (* (sin colatitude) (sin longitude))
  718. (cos colatitude)))
  719. manifold
  720. me
  721. coords))
  722. (error "Bad coordinates: S^2-spherical" coords me))))
  723. ((check-point)
  724. (lambda (point) (my-manifold-point? point manifold)))
  725. ((point->coords)
  726. (lambda (point)
  727. (if (not ((me 'check-point) point))
  728. (error "Bad point: S^2-spherical" point me))
  729. (get-coordinates point me
  730. (lambda ()
  731. (let ((prep
  732. (* orientation^-1
  733. (manifold-point-representation point))))
  734. (if (and (up? prep)
  735. (fix:= (s:dimension prep)
  736. (manifold 'embedding-dimension)))
  737. (let ((x (ref prep 0))
  738. (y (ref prep 1))
  739. (z (ref prep 2)))
  740. ;; (if (and (number? x) (= x 0))
  741. ;; (error "S^2-spherical singular" point me))
  742. (up (acos z) (atan y x)))
  743. (error "Bad point: S^2-spherical" point me)))))))
  744. ((manifold) manifold)
  745. ((orientation) orientation)
  746. (else (error "Bad message: S^2-spherical" m me))))
  747. me)))
  748. (define %calculus-manifold-dummy-2
  749. (begin
  750. (attach-patch 'north-pole S^2-type)
  751. (attach-coordinate-system 'spherical 'north-pole S^2-type
  752. (S^2-coordinates (down (up 1 0 0) (up 0 1 0) (up 0 0 1))))
  753. (attach-patch 'tilted S^2-type)
  754. (attach-coordinate-system 'spherical 'tilted S^2-type
  755. (S^2-coordinates (down (up 1 0 0) (up 0 0 1) (up 0 -1 0))))
  756. (attach-patch 'south-pole S^2-type)
  757. (attach-coordinate-system 'spherical 'south-pole S^2-type
  758. (S^2-coordinates (down (up 1 0 0) (up 0 1 0) (up 0 0 -1))))))
  759. (define S2 (make-manifold S^2-type 2 3))
  760. (define S2-spherical
  761. (coordinate-system-at 'spherical 'north-pole S2))
  762. (define S2-tilted
  763. (coordinate-system-at 'spherical 'tilted S2))
  764. #|
  765. (define m
  766. ((S2-spherical '->point) (up 'theta 'phi)))
  767. (pec ((S2-tilted '->coords) m))
  768. #| Result:
  769. (up (acos (* -1 (sin phi) (sin theta)))
  770. (atan (cos theta) (* (sin theta) (cos phi))))
  771. |#
  772. |#
  773. (define S^n-type (specify-manifold 'S^n))
  774. ;; Manifold points are represented by
  775. ;;(up
  776. ;; (* (sin theta0) (cos theta1) )
  777. ;; (* (sin theta0) (sin theta1) (cos theta2) )
  778. ;; ...
  779. ;; (* (sin theta0) (sin theta1) ... (sin theta_n-1) )
  780. ;; (cos theta0)
  781. ;; )
  782. ;;; Notice that the (cos theta0) has been rotated to the bottom
  783. ;;; to be compatible with the traditional S^2 convention.
  784. ;;
  785. ;; The first n-1 angles must be nonzero to avoid the coordinate singularity.
  786. ;;
  787. ;; S^n-coordinates takes an orientation function that takes the dimension
  788. ;; of the embedding space (1+the dimension of the manifold) and produces the
  789. ;; matrix that shifts the location of the "north pole".
  790. (define (S^n-coordinates orientation-function)
  791. (define (list-top-to-bottom l)
  792. (append (cdr l) (list (car l))))
  793. (define (list-bottom-to-top l)
  794. (cons (car (last-pair l)) (butlast l)))
  795. (lambda (manifold)
  796. (let* ((n (manifold 'dimension))
  797. (orientation-matrix (orientation-function (+ n 1)))
  798. (orientation-inverse-matrix (invert orientation-matrix)))
  799. (define (me m)
  800. (case m
  801. ((check-coordinates)
  802. (lambda (coords)
  803. (or (and (fix:= n 1) (fix:= (s:dimension coords) 1))
  804. (and (up? coords)
  805. (fix:= (s:dimension coords) (manifold 'dimension))
  806. (let ((remaining-coords (butlast (up-structure->list coords))))
  807. (every (lambda (coord)
  808. (or (not (number? coord)) (not (< coord 0))))
  809. remaining-coords))))))
  810. ((coords->point)
  811. (lambda (coords)
  812. (if (not ((me 'check-coordinates) coords))
  813. (error "Bad coordinates: S^n-spherical" coords me))
  814. (if (fix:= n 1)
  815. (let ((pt (up (cos coords) (sin coords))))
  816. (make-manifold-point (* orientation-matrix pt)
  817. manifold me coords))
  818. (let* ((coordl (up-structure->list coords))
  819. (sines (map sin coordl)) (cosines (map cos coordl))
  820. (pt
  821. (list->up-structure
  822. (list-top-to-bottom
  823. (make-initialized-list (fix:+ n 1)
  824. (lambda (i)
  825. (if (fix:= i n)
  826. (apply * sines)
  827. (apply *
  828. (cons (list-ref cosines i)
  829. (list-head sines i))))))))))
  830. (make-manifold-point (* orientation-matrix pt)
  831. manifold me coords)))))
  832. ((check-point)
  833. (lambda (point) (my-manifold-point? point manifold)))
  834. ((point->coords)
  835. (lambda (point)
  836. ;;; FBE move after define
  837. ;; (if (not ((me 'check-point) point))
  838. ;; (error "Bad point: S^n-spherical" point me))
  839. (define (safe-atan y x)
  840. (if (and (number? y) (number? x) (= y 0) (= x 0))
  841. (warn "S^n-spherical singular" point me))
  842. (atan y x))
  843. (if (not ((me 'check-point) point))
  844. (error "Bad point: S^n-spherical" point me))
  845. (let* ((pt
  846. (reverse
  847. (list-bottom-to-top
  848. (up-structure->list
  849. (* orientation-inverse-matrix
  850. (manifold-point-representation point)))))) )
  851. (if (fix:= n 1)
  852. (safe-atan (ref pt 1) (ref pt 0))
  853. (let lp ((r (car pt)) (rest (cdr pt))
  854. (ans (list (safe-atan (car pt) (cadr pt)))))
  855. (if (null? (cdr rest))
  856. (list->up-structure ans)
  857. (let ((r (sqrt (+ (square (car rest)) (square r)))))
  858. (lp r
  859. (cdr rest)
  860. (cons (safe-atan r (cadr rest)) ans)))))))))
  861. ((manifold) manifold)
  862. ((orientation) orientation-function)
  863. (else (error "S^n-spherical: Bad message" m me))))
  864. me)))
  865. (define %calculus-manifold-dummy-3
  866. (begin
  867. (attach-patch 'north-pole S^n-type)
  868. (attach-coordinate-system 'spherical 'north-pole S^n-type
  869. (S^n-coordinates m:make-identity))
  870. (attach-patch 'tilted S^n-type)
  871. (attach-coordinate-system 'spherical 'tilted S^n-type
  872. (S^n-coordinates
  873. (let ((c (cos :pi/2)) (s (sin :pi/2)))
  874. (lambda (n)
  875. (s:generate n 'down
  876. (lambda (col)
  877. (s:generate n 'up
  878. (lambda (row)
  879. (cond ((and (= row (- n 2)) (= col (- n 1)) -1))
  880. ((and (= row (- n 1)) (= col (- n 2)) +1))
  881. ((and (= row col) (< row (- n 2))) +1)
  882. (else 0))))))))))))
  883. (define S1 (make-manifold S^n-type 1))
  884. (define S1-circular (coordinate-system-at 'spherical 'north-pole S1))
  885. (define S1-tilted (coordinate-system-at 'spherical 'tilted S1))
  886. #|
  887. (define m ((S1-circular '->point) 'theta))
  888. (pe (manifold-point-representation m))
  889. ; Result: (up (cos theta) (sin theta))
  890. (pe ((compose (S1-circular '->coords) (S1-circular '->point)) 'theta))
  891. ; Result: theta
  892. (pe ((compose (S1-circular '->coords) (S1-tilted '->point)) 'theta))
  893. ; Result: (atan (cos theta) (* -1 (sin theta)))
  894. |#
  895. (define S2p (make-manifold S^n-type 2))
  896. (define S2p-spherical (coordinate-system-at 'spherical 'north-pole S2p))
  897. (define S2p-tilted (coordinate-system-at 'spherical 'tilted S2p))
  898. #|
  899. (define m ((S2p-spherical '->point) (up 'theta 'phi)))
  900. (pe (manifold-point-representation m))
  901. ; Result: (up (* (sin theta) (cos phi))
  902. ; (* (sin phi) (sin theta))
  903. ; (cos theta))
  904. (pe ((compose (S2p-spherical '->coords) (S2p-spherical '->point))
  905. (up 'theta 'phi)))
  906. ; Result: (up theta phi)
  907. (pe ((compose (S2p-spherical '->coords) (S2p-tilted '->point))
  908. (up 'theta 'phi)))
  909. ; Result: (up (atan (sqrt (+ (* (expt (cos theta) 2) (expt (cos phi) 2))
  910. ; (expt (sin phi) 2)))
  911. ; (* -1 (sin theta) (cos phi)))
  912. ; (atan (* (sin phi) (sin theta)) (cos theta)))
  913. (pe ((compose (S2p-spherical '->coords) (S2p-spherical '->point))
  914. (up 1 0)))
  915. ;(up 1. 0.)
  916. (pe ((compose (S2p-spherical '->coords) (S2p-spherical '->point))
  917. (up 0 1)))
  918. ;(up 0 0)
  919. ;Should be warned singular!
  920. |#
  921. (define S3 (make-manifold S^n-type 3))
  922. (define S3-spherical (coordinate-system-at 'spherical 'north-pole S3))
  923. (define S3-tilted (coordinate-system-at 'spherical 'tilted S3))
  924. #|
  925. (pe ((compose (S3-spherical '->coords)
  926. (S3-spherical '->point))
  927. (up 'a 'b 'c)))
  928. ; Result: (up a b c)
  929. (pe ((compose (S3-spherical '->coords)
  930. (S3-tilted '->point))
  931. (up 'a 'b 'c)))
  932. ; Result:
  933. ;(up
  934. ; (atan
  935. ; (sqrt
  936. ; (+ (* (expt (sin c) 2) (expt (sin b) 2) (expt (cos a) 2))
  937. ; (* (expt (sin c) 2) (expt (cos b) 2))
  938. ; (expt (cos c) 2)))
  939. ; (* (sin c) (sin b) (sin a)))
  940. ; (atan (sqrt (+ (* (expt (sin b) 2) (expt (sin a) 2) (expt (cos c) 2))
  941. ; (expt (cos a) 2)))
  942. ; (* (sin a) (cos b)))
  943. ; (atan (* -1 (cos a)) (* (sin b) (sin a) (cos c))))
  944. (pe ((compose (S3-spherical '->coords)
  945. (S3-spherical '->point))
  946. (up 0 0 0)))
  947. ;(up 0 0 0)
  948. ;Should be warned singular!
  949. |#
  950. ;;; Stereographic Projection from the final coordinate.
  951. ;;
  952. ;; The default pole is p = (0 0 ... 0 1)
  953. ;; We fire a ray through m = (m_0 ... m_n)
  954. ;; x(t) = p + t(m - p)
  955. ;;
  956. ;; x(0) = p, x(1) = m
  957. ;; x_n(t) = 1-t(1+m_n), 0 = x_n(1/(1+m_n))
  958. ;;
  959. ;; The orientation function should return an orthogonal (n+1)-by-(n+1)
  960. ;; matrix. It can be interpreted as moving the pole / plane of projection
  961. ;; and possibly reflecting.
  962. ;;
  963. (define (S^n-stereographic orientation-function)
  964. (lambda (manifold)
  965. (let* ((n (manifold 'dimension))
  966. (orientation-matrix (orientation-function (+ n 1)))
  967. (orientation-inverse-matrix (invert orientation-matrix)))
  968. (define (me m)
  969. (case m
  970. ((check-coordinates)
  971. (lambda (coords)
  972. (or (and (fix:= n 1) (fix:= (s:dimension coords) 1))
  973. (and (up? coords)
  974. (fix:= (s:dimension coords) n)))))
  975. ((coords->point)
  976. (lambda (coords)
  977. (if (not ((me 'check-coordinates) coords))
  978. (error "Bad coordinates: S^n-stereographic"
  979. coords me))
  980. (let* ((coords (if (fix:= n 1) (up coords) coords))
  981. (delta (dot-product coords coords))
  982. (xn (/ (- delta 1) (+ 1 delta)))
  983. (pt (s:generate
  984. (fix:+ n 1) 'up
  985. (lambda (i)
  986. (if (fix:= i n) xn
  987. (/ (* 2 (ref coords i))
  988. (+ 1 delta)))))))
  989. (make-manifold-point (* orientation-matrix pt)
  990. manifold me coords))))
  991. ((check-point)
  992. (lambda (point) (my-manifold-point? point manifold)))
  993. ((point->coords)
  994. (lambda (point)
  995. (if (not ((me 'check-point) point))
  996. (error "Bad point: S^n" point me))
  997. (let* ((n (manifold 'dimension))
  998. (pt (* orientation-inverse-matrix
  999. (manifold-point-representation point))))
  1000. (if (and (number? (ref pt n)) (= (ref pt n) 1))
  1001. (error "S^n-stereographic singular" point me))
  1002. (let ((coords
  1003. (s:generate n 'up
  1004. (lambda (i)
  1005. (/ (ref pt i)
  1006. (- 1 (ref pt n)))))))
  1007. (if (fix:= n 1) (ref coords 0) coords)))))
  1008. ((manifold) manifold)
  1009. ((orientation) orientation-function)
  1010. (else (error "S^n-stereographic: Bad message" m me))))
  1011. me)))
  1012. (define %calculus-manifold-dummy-4
  1013. (begin
  1014. (attach-coordinate-system 'stereographic 'north-pole S^n-type
  1015. (S^n-stereographic m:make-identity))
  1016. (attach-patch 'south-pole S^n-type)
  1017. (attach-coordinate-system 'stereographic 'south-pole S^n-type
  1018. (S^n-stereographic
  1019. (lambda (n)
  1020. (m:generate n n
  1021. (lambda (i j)
  1022. (if (= i j)
  1023. (if (= j n) -1 1)
  1024. 0))))))))
  1025. #|
  1026. (define S1 (make-manifold S^n-type 1))
  1027. |#
  1028. (define S1-slope
  1029. (coordinate-system-at 'stereographic 'north-pole S1))
  1030. #|
  1031. (define m ((S1-slope '->point) 's))
  1032. (pe (manifold-point-representation m))
  1033. ; Result:
  1034. ;(up (/ (* 2 s)
  1035. ; (+ 1 (expt s 2)))
  1036. ; (/ (+ -1 (expt s 2))
  1037. ; (+ 1 (expt s 2))))
  1038. (pe (manifold-point-representation
  1039. ((compose (S1-slope '->point)
  1040. (S1-slope '->coords))
  1041. m)))
  1042. ; Result:
  1043. ;(up (/ (* 2 s)
  1044. ; (+ 1 (expt s 2)))
  1045. ; (/ (+ -1 (expt s 2))
  1046. ; (+ 1 (expt s 2))))
  1047. (pe ((compose (S1-slope '->coords)
  1048. (S1-slope '->point))
  1049. 's))
  1050. ; Result: s
  1051. |#
  1052. #|
  1053. (define S2p (make-manifold S^n-type 2))
  1054. |#
  1055. (define S2p-stereographic (coordinate-system-at 'stereographic 'north-pole S2p))
  1056. (define S2p-Riemann S2p-stereographic)
  1057. #|
  1058. (define m ((S2p-Riemann '->point) (up 'x 'y)))
  1059. (pe (manifold-point-representation m))
  1060. ; Result:
  1061. ;(up (/ (* 2 x)
  1062. ; (+ 1 (expt x 2) (expt y 2)))
  1063. ; (/ (* 2 y)
  1064. ; (+ 1 (expt y 2) (expt x 2)))
  1065. ; (/ (+ -1 (expt x 2) (expt y 2))
  1066. ; (+ +1 (expt x 2) (expt y 2))))
  1067. (pe (manifold-point-representation
  1068. ((compose (S2p-Riemann '->point) (S2p-Riemann '->coords))
  1069. m)))
  1070. ; Result:
  1071. ;(up (/ (* 2 x)
  1072. ; (+ 1 (expt x 2) (expt y 2)))
  1073. ; (/ (* 2 y)
  1074. ; (+ 1 (expt x 2) (expt y 2)))
  1075. ; (/ (+ -1 (expt x 2) (expt y 2))
  1076. ; (+ 1 (expt x 2) (expt y 2))))
  1077. (pe ((compose (S2p-Riemann '->coords) (S2p-Riemann '->point))
  1078. (up 'x 'y)))
  1079. ; Result: (up x y)
  1080. (pe (manifold-point-representation
  1081. ((S2p-Riemann '->point)
  1082. (up (cos 'theta) (sin 'theta)))))
  1083. ; Result: (up (cos theta) (sin theta) 0)
  1084. ; The equator is invariant.
  1085. |#
  1086. ;;; Gnomic Projection of the sphere
  1087. ;;
  1088. ;; We map the nothern hemisphere to the plane by firing a ray from the origin.
  1089. ;; The coordinates are given by the intersection with the z = 1 plane.
  1090. ;; x(t) = t*m
  1091. ;; x_n(t) = t*m_n, 1 = x_n(1/m_n)
  1092. ;;
  1093. ;; orientation-function should should return an n+1-by-n+1 orthogonal matrix.
  1094. ;; It can be interpreted as moving the plane of projection, and point mapped to
  1095. ;; the origin, as well as possibly reflecting.
  1096. ;;
  1097. ;; Given the coordinates x we have <x,x> = (1-m_n^2)/m_n^2
  1098. ;; 1 + <x,x> = (m_n^2 + 1 - m_n^2)/m_n^2
  1099. ;; m_n = sqrt(1/(1+<x,x>))
  1100. ;; where positive square root is sufficient for the nothern hemisphere.
  1101. (define (S^n-gnomic orientation-function)
  1102. (lambda (manifold)
  1103. (let* ((n (manifold 'dimension))
  1104. (orientation-matrix (orientation-function (+ n 1)))
  1105. (orientation-inverse-matrix (invert orientation-matrix)))
  1106. (define (me m)
  1107. (case m
  1108. ((check-coordinates)
  1109. (lambda (coords)
  1110. (or (and (fix:= n 1) (fix:= (s:dimension coords) 1))
  1111. (and (up? coords) (fix:= (s:dimension coords) n)))))
  1112. ((coords->point)
  1113. (lambda (coords)
  1114. (if (not ((me 'check-coordinates) coords))
  1115. (error "Bad coordinates: S^n" coords me))
  1116. (let* ((coords (if (fix:= n 1) (up coords) coords))
  1117. (delta (dot-product coords coords))
  1118. (d (sqrt (+ 1 delta)))
  1119. (xn (/ 1 d))
  1120. (pt (s:generate
  1121. (fix:+ n 1) 'up
  1122. (lambda (i)
  1123. (if (fix:= i n)
  1124. xn
  1125. (/ (ref coords i) d))))))
  1126. (make-manifold-point (* orientation-matrix pt)
  1127. manifold me coords))))
  1128. ((check-point)
  1129. (lambda (point) (my-manifold-point? point manifold)))
  1130. ((point->coords)
  1131. (lambda (point)
  1132. (if (not ((me 'check-point) point))
  1133. (error "Bad point: S^n-gnomic" point me))
  1134. (let* ((n (manifold 'dimension))
  1135. (pt (* orientation-inverse-matrix
  1136. (manifold-point-representation point))))
  1137. (if (and (number? (ref pt n)) (not (> 0 (ref pt n))))
  1138. (error "Point not covered by S^n-gnomic coordinate patch."
  1139. point me))
  1140. (let ((coords
  1141. (s:generate n 'up
  1142. (lambda (i)
  1143. (/ (ref pt i)
  1144. (ref pt n))))))
  1145. (if (fix:= n 1) (ref coords 0) coords)))))
  1146. ((manifold) manifold)
  1147. ((orientation) orientation-function)
  1148. (else (error "S^n: Bad message" m me))))
  1149. me)))
  1150. (define %calculus-manifold-dummy-5
  1151. (attach-coordinate-system 'gnomic 'north-pole S^n-type
  1152. (S^n-gnomic m:make-identity)))
  1153. #|
  1154. (define S1 (make-manifold S^n-type 1))
  1155. |#
  1156. (define S1-gnomic (coordinate-system-at 'gnomic 'north-pole S1))
  1157. #|
  1158. (define m ((S1-gnomic '->point) 's))
  1159. (pe (manifold-point-representation m))
  1160. ; Result: (up (/ s (sqrt (+ 1 (expt s 2))))
  1161. ; (/ 1 (sqrt (+ 1 (expt s 2)))))
  1162. (pe (manifold-point-representation
  1163. ((compose (S1-gnomic '->point) (S1-gnomic '->coords)) m)))
  1164. ; Result: (up (/ s (sqrt (+ 1 (expt s 2))))
  1165. ; (/ 1 (sqrt (+ 1 (expt s 2)))))
  1166. (pe ((compose (S1-slope '->coords) (S1-slope '->point)) 's))
  1167. ; Result: s
  1168. |#
  1169. #|
  1170. (define S2p (make-manifold S^n-type 2))
  1171. |#
  1172. (define S2p-gnomic (coordinate-system-at 'gnomic 'north-pole S2p))
  1173. #|
  1174. (define S2p-stereographic (coordinate-system-at 'stereographic 'north-pole S2p))
  1175. (define m ((S2p-gnomic '->point) (up 'x 'y)))
  1176. (pe (manifold-point-representation m))
  1177. ; Result: (up (/ x (sqrt (+ 1 (expt x 2) (expt y 2))))
  1178. ; (/ y (sqrt (+ 1 (expt x 2) (expt y 2))))
  1179. ; (/ 1 (sqrt (+ 1 (expt x 2) (expt y 2)))))
  1180. (pe (manifold-point-representation
  1181. ((compose (S2p-gnomic '->point) (S2p-gnomic '->coords))
  1182. m)))
  1183. ; Result: (up (/ x (sqrt (+ 1 (expt x 2) (expt y 2))))
  1184. ; (/ y (sqrt (+ 1 (expt x 2) (expt y 2))))
  1185. ; (/ 1 (sqrt (+ 1 (expt x 2) (expt y 2)))))
  1186. (pe ((compose (S2p-gnomic '->coords) (S2p-gnomic '->point))
  1187. (up 'x 'y)))
  1188. ; Result: (up x y)
  1189. (pe (manifold-point-representation
  1190. ((S2p-gnomic '->point)
  1191. (up (cos 'theta) (sin 'theta)))))
  1192. ; Result: (up (/ (cos theta) (sqrt 2))
  1193. ; (/ (sin theta) (sqrt 2))
  1194. ; (/ 1 (sqrt 2)))
  1195. ; The unit circle on the plane represents the intersection of S2 and
  1196. ; z = (/ 1 (sqrt 2))
  1197. ; Straight lines in the gnomic coordinates are geodesics.
  1198. ; We compute a straight line, then transform it back to stereographic coordinates.
  1199. (define q ((S2p-stereographic '->point) (up -1.5 1.5)))
  1200. (define p ((S2p-stereographic '->point) (up 1.5 0)))
  1201. (pe (simplify (simplify ((S2p-stereographic '->coords)
  1202. ((S2p-gnomic '->point)
  1203. (+ (* 't ((S2p-gnomic '->coords) p))
  1204. (* (- 1 't) ((S2p-gnomic '->coords) q))))))))
  1205. ; Result:
  1206. ;(up
  1207. ; (/ (+ (* 3.257142857142857 t) -.8571428571428571)
  1208. ; (+ -1
  1209. ; (sqrt (+ (* 11.343673469387754 (expt t 2))
  1210. ; (* -7.053061224489795 t)
  1211. ; 2.4693877551020407))))
  1212. ; (/ (+ (* -.8571428571428571 t) .8571428571428571)
  1213. ; (+ -1
  1214. ; (sqrt (+ (* 11.343673469387754 (expt t 2))
  1215. ; (* -7.053061224489795 t)
  1216. ; 2.4693877551020407)))))
  1217. |#
  1218. #|
  1219. ;; Now a fun example synthesizing the to projective coordinates.
  1220. (define S3 (make-manifold S^n-type 3))
  1221. |#
  1222. (define S3-gnomic (coordinate-system-at 'gnomic 'north-pole S3))
  1223. (define S3-stereographic (coordinate-system-at 'stereographic 'south-pole S3))
  1224. #|
  1225. ; S3 is one-to-one with the quaternions.
  1226. ; We interpret the first three components of the embedding space as the
  1227. ; i,j,k imaginary party and the 4th component as the real part.
  1228. ; The gnomic projection removes the double-cover of quaternions to rotations.
  1229. ; The solid unit-sphere of the stereographic projection from the south pole likewise.
  1230. (pe ((S3-gnomic '->coords) ((S3-stereographic '->point) (up 'x 'y 'z))))
  1231. (up (/ (* 2 x) (+ -1 (expt x 2) (expt y 2) (expt z 2)))
  1232. (/ (* 2 y) (+ -1 (expt y 2) (expt x 2) (expt z 2)))
  1233. (/ (* 2 z) (+ -1 (expt z 2) (expt x 2) (expt y 2))))
  1234. (pe ((S3-stereographic '->coords) ((S3-gnomic '->point) (up 'x 'y 'z))))
  1235. (up (/ x (+ -1 (sqrt (+ 1 (expt x 2) (expt y 2) (expt z 2)))))
  1236. (/ y (+ -1 (sqrt (+ 1 (expt y 2) (expt x 2) (expt z 2)))))
  1237. (/ z (+ -1 (sqrt (+ 1 (expt z 2) (expt x 2) (expt y 2))))))
  1238. (pe (euclidean-norm ((S3-stereographic '->coords)
  1239. ((S3-gnomic '->point) (up 'x 'y 'z)))))
  1240. (/ (sqrt (+ (expt x 2) (expt y 2) (expt z 2)))
  1241. (sqrt (+ 2
  1242. (expt x 2) (expt y 2) (expt z 2)
  1243. (* -2
  1244. (sqrt (+ 1 (expt x 2) (expt y 2) (expt z 2)))))))
  1245. |#
  1246. ;;; SO(3). Points are represented by 3x3 (down (up ...) ...)
  1247. ;;; There is only one instance of an SOn manifold defined, SO3.
  1248. ;;; As a consequence the name is not SOn but rather SO3-type.
  1249. (define SO3-type (specify-manifold 'SO3))
  1250. (define Euler-chart
  1251. (lambda (manifold)
  1252. (define (me m)
  1253. (case m
  1254. ((check-coordinates)
  1255. (lambda (coords)
  1256. (and (up? coords)
  1257. (fix:= (s:dimension coords) 3)
  1258. (or (not (number? (ref coords 0)))
  1259. (not (= (ref coords 0) 0))))))
  1260. ((coords->point)
  1261. (lambda (coords)
  1262. (if (not ((me 'check-coordinates) coords))
  1263. (error "Bad coordinates: Euler-angles" coords me))
  1264. (let ((theta (ref coords 0))
  1265. (phi (ref coords 1))
  1266. (psi (ref coords 2)))
  1267. (let ((Mx-theta (rotate-x-tuple theta))
  1268. (Mz-phi (rotate-z-tuple phi))
  1269. (Mz-psi (rotate-z-tuple psi)))
  1270. (let ((the-point (* Mz-phi Mx-theta Mz-psi)))
  1271. (make-manifold-point
  1272. the-point
  1273. manifold
  1274. me
  1275. coords))))))
  1276. ((check-point)
  1277. (lambda (point) (my-manifold-point? point manifold)))
  1278. ((point->coords)
  1279. (lambda (point)
  1280. (if (not ((me 'check-point) point))
  1281. (error "Bad manifold point: Euler-angles" point me))
  1282. (get-coordinates point me
  1283. (lambda ()
  1284. (let ((the-point
  1285. (manifold-point-representation point)))
  1286. (let ((theta (acos (ref the-point 2 2)))
  1287. (phi (atan (ref the-point 2 0)
  1288. (- (ref the-point 2 1))))
  1289. (psi (atan (ref the-point 0 2)
  1290. (ref the-point 1 2))))
  1291. (up theta phi psi)))))))
  1292. ((manifold) manifold)
  1293. (else (error "Euler-chart: Bad message" m me)) ))
  1294. me))
  1295. (define alternate-chart
  1296. (lambda (manifold)
  1297. (define (me m)
  1298. (case m
  1299. ((check-coordinates)
  1300. (lambda (coords)
  1301. (and (up? coords)
  1302. (fix:= (s:dimension coords) 3)
  1303. (or (not (number? (ref coords 0)))
  1304. (and (not (<= (ref coords 0) (- pi/2)))
  1305. (not (>= (ref coords pi/2))))))))
  1306. ((coords->point)
  1307. (lambda (coords)
  1308. (if (not ((me 'check-coordinates) coords))
  1309. (error "Bad coordinates: alternate-angles" coords me))
  1310. (let ((theta (ref coords 0))
  1311. (phi (ref coords 1))
  1312. (psi (ref coords 2)))
  1313. (let ((Mx-theta (rotate-x-tuple theta))
  1314. (Mz-phi (rotate-z-tuple phi))
  1315. (My-psi (rotate-y-tuple psi)))
  1316. (let ((the-point (* Mz-phi Mx-theta My-psi)))
  1317. (make-manifold-point the-point manifold me coords))))))
  1318. ((check-point)
  1319. (lambda (point) (my-manifold-point? point manifold)))
  1320. ((point->coords)
  1321. (lambda (point)
  1322. (if (not ((me 'check-point) point))
  1323. (error "Bad manifold point: alternate-angles" point me))
  1324. (get-coordinates point me
  1325. (lambda ()
  1326. (let ((the-point
  1327. (manifold-point-representation point)))
  1328. (let ((theta (asin (ref the-point 1 2)))
  1329. (phi
  1330. (atan (- (ref the-point 1 0))
  1331. (ref the-point 1 1)))
  1332. (psi
  1333. (atan (- (ref the-point 0 2))
  1334. (ref the-point 2 2))))
  1335. (up theta phi psi)))))))
  1336. ((manifold) manifold)
  1337. (else (error "alternate-chart: Bad message" m me))))
  1338. me))
  1339. (define %calculus-manifold-dummy-6
  1340. (begin
  1341. (attach-patch 'Euler-patch SO3-type)
  1342. (attach-coordinate-system 'Euler 'Euler-patch SO3-type Euler-chart)
  1343. (attach-patch 'alternate-patch SO3-type)
  1344. (attach-coordinate-system 'alternate 'alternate-patch SO3-type alternate-chart)))
  1345. (define SO3 (make-manifold SO3-type 3))
  1346. (define Euler-angles (coordinate-system-at 'Euler 'Euler-patch SO3))
  1347. (define alternate-angles (coordinate-system-at 'alternate 'alternate-patch SO3))
  1348. #|
  1349. (pec ((compose (alternate-angles '->coords)
  1350. (Euler-angles '->point))
  1351. (up 'theta 'phi 'psi)))
  1352. #| Result:
  1353. (up
  1354. (asin (* (cos psi) (sin theta)))
  1355. (atan (+ (* (cos theta) (sin phi) (cos psi)) (* (cos phi) (sin psi)))
  1356. (+ (* (cos phi) (cos theta) (cos psi)) (* -1 (sin psi) (sin phi))))
  1357. (atan (* -1 (sin psi) (sin theta)) (cos theta)))
  1358. |#
  1359. (pec ((compose (Euler-angles '->coords)
  1360. (alternate-angles '->point)
  1361. (alternate-angles '->coords)
  1362. (Euler-angles '->point))
  1363. (up 'theta 'phi 'psi)))
  1364. #| Result:
  1365. (up theta phi psi)
  1366. |#
  1367. |#
  1368. (define (literal-scalar-field name coordinate-system)
  1369. (let ((n (coordinate-system 'dimension)))
  1370. (let ((function-signature
  1371. (if (fix:= n 1) (-> Real Real) (-> (UP* Real n) Real))))
  1372. (let ((function
  1373. (compose (literal-function name function-signature)
  1374. (coordinate-system '->coords))))
  1375. (eq-put! function 'function-name name)
  1376. (eq-put! function 'coordinate-system coordinate-system)
  1377. function))))
  1378. (define (zero-coordinate-function c) 0)
  1379. ;;; An alias.
  1380. (define literal-manifold-function literal-scalar-field)
  1381. (define (zero-manifold-function m)
  1382. (assert (manifold-point? m))
  1383. 0)
  1384. (define (one-manifold-function m)
  1385. (assert (manifold-point? m))
  1386. 1)
  1387. (define* ((constant-manifold-function c) m)
  1388. (assert (manifold-point? m))
  1389. c)
  1390. #|
  1391. ;;; A scalar field can be defined by combining coordinate functions:
  1392. (install-coordinates R3-rect (up 'x 'y 'z))
  1393. (install-coordinates R3-cyl (up 'r 'theta 'zeta))
  1394. (define h (+ 5 (square x) (* -1 x (cube y)) (/ 1 y)))
  1395. ;;; The field, however defined, can be seen as independent of
  1396. ;;; coordinate system:
  1397. (h ((R3-rect '->point) (up 3. 4. 'z)))
  1398. ;Value: -177.75
  1399. (h ((R3-cyl '->point) (up 5. (atan 4 3) 'z)))
  1400. ;Value: -177.74999999999997
  1401. ;;; However this may be too clever, producing a traditional notation
  1402. ;;; that is hard to understand deeply. Perhaps it is better to be
  1403. ;;; explicit about what is coordinate-system independent. For
  1404. ;;; example, we can define a coordinate-free function h by composing a
  1405. ;;; definition in terms of coordinates with a coordinate function.
  1406. (define (h-concrete xy)
  1407. (let ((x (ref xy 0))
  1408. (y (ref xy 1)))
  1409. (+ 5
  1410. (square x)
  1411. (* -1 x (cube y))
  1412. (/ 1 y))))
  1413. (define h
  1414. (compose h-concrete (R3-rect '->coords)))
  1415. (h ((R3-rect '->point) (up 3. 4 5)))
  1416. ;Value: -177.75
  1417. |#
  1418. ;;; Adding in stuff to S^2-type manifolds
  1419. (define %calculus-manifold-dummy-7
  1420. (begin
  1421. (attach-coordinate-system 'stereographic 'north-pole S^2-type
  1422. (S^n-stereographic m:make-identity))
  1423. (attach-coordinate-system 'stereographic 'south-pole S^2-type
  1424. (S^n-stereographic
  1425. (lambda (n)
  1426. (m:generate n n
  1427. (lambda (i j)
  1428. (if (= i j)
  1429. (if (= j n) -1 1)
  1430. 0))))))
  1431. (attach-coordinate-system 'gnomic 'north-pole S^2-type
  1432. (S^n-gnomic m:make-identity))
  1433. (attach-coordinate-system 'gnomic 'south-pole S^2-type
  1434. (S^n-gnomic
  1435. (lambda (n)
  1436. (m:generate n n
  1437. (lambda (i j)
  1438. (if (= i j)
  1439. (if (= j n) -1 1)
  1440. 0))))))))
  1441. (define S2-stereographic
  1442. (coordinate-system-at 'stereographic 'north-pole S2))
  1443. (define S2-Riemann S2-stereographic)
  1444. (define S2-gnomic
  1445. (coordinate-system-at 'gnomic 'north-pole S2))