From c6b48bed35384aaaca4aeb93c6bc70d9987e1926 Mon Sep 17 00:00:00 2001 From: Anthony Scemama Date: Sun, 27 Dec 2020 17:23:47 +0100 Subject: [PATCH] Coordinate org --- common/coordinate.org | 273 ++++++++++++++++++++++++++++++++++++++ common/lib/coordinate.ml | 171 ++++++++++++++++-------- common/lib/coordinate.mli | 136 +++++++++++-------- 3 files changed, 467 insertions(+), 113 deletions(-) create mode 100644 common/coordinate.org diff --git a/common/coordinate.org b/common/coordinate.org new file mode 100644 index 0000000..ea53cb5 --- /dev/null +++ b/common/coordinate.org @@ -0,0 +1,273 @@ +#+begin_src elisp tangle: no :results none +(setq pwd (file-name-directory buffer-file-name)) +(setq name (file-name-nondirectory (substring buffer-file-name 0 -4))) +(setq lib (concat pwd "lib/")) +(setq testdir (concat pwd "test/")) +(setq mli (concat lib name ".mli")) +(setq ml (concat lib name ".ml")) +(setq test-ml (concat testdir name ".ml")) +(org-babel-tangle) +#+end_src + +* Coordinate + :PROPERTIES: + :header-args: :noweb yes :comments both + :END: + + Coordinates in 3D space. + + All operations on points are done in atomic units. Therefore, + all coordinates are given in bohr and manipulated with this + module. + +** Type + + #+NAME: types + #+begin_src ocaml :tangle (eval mli) +type bohr +type angstrom + +type xyz = { + x : float ; + y : float ; + z : float ; +} + +type 'a point = xyz + +type t = bohr point + +type axis = X | Y | Z + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +<> + #+end_src + +** Creation / conversion + +*** ~make~ + + Creates a point in atomic units. + + #+begin_src ocaml :tangle (eval mli) +val make : 'a point -> t + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +external make : 'a point -> t = "%identity" + #+end_src + +*** ~make_angstrom~ + + Creates a point in angstrom. + + #+begin_src ocaml :tangle (eval mli) +val make_angstrom : 'a point -> angstrom point + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +external make_angstrom : 'a point -> angstrom point = "%identity" + #+end_src + +*** ~bohr_to_angstrom~ + + Converts a point in bohr to angstrom. + + #+begin_src ocaml :tangle (eval mli) +val bohr_to_angstrom : bohr point -> angstrom point + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +let b_to_a b = Constants.a0 *. b + +let bohr_to_angstrom { x ; y ; z } = + make { x = b_to_a x ; + y = b_to_a y ; + z = b_to_a z ; } + #+end_src + +*** ~angstrom_to_bohr~ + + Converts a point in angstrom to bohr. + + #+begin_src ocaml :tangle (eval mli) +val angstrom_to_bohr : angstrom point -> bohr point + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +let a_to_b a = Constants.a0_inv *. a + +let angstrom_to_bohr { x ; y ; z } = + make { x = a_to_b x ; + y = a_to_b y ; + z = a_to_b z ; } + #+end_src + +*** ~zero~ + + ~zero~ = (0., 0., 0.) + + #+begin_src ocaml :tangle (eval mli) +val zero : bohr point + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +let zero = + make { x = 0. ; y = 0. ; z = 0. } + #+end_src + +*** ~get~ + + Extracts the projection of the coordinate on an axis. + + #+begin_example +Coordinate.(get Y { x=1. ; y=2. ; z=3. }) ;; +- : float = 2. + #+end_example + + #+begin_src ocaml :tangle (eval mli) +val get : axis -> bohr point -> float + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +let get axis { x ; y ; z } = + match axis with + | X -> x + | Y -> y + | Z -> z + #+end_src + +** Vector operations + +*** Scale + + #+begin_src ocaml :tangle (eval mli) +val ( |. ) : float -> t -> t + #+end_src + + #+begin_example +Coordinate.( + 2. |. { x=1. ; y=2. ; z=3. } +) ;; +- : Coordinate.t = {Qcaml.Common.Coordinate.x = 2.; y = 4.; z = 6.} + #+end_example + + #+begin_src ocaml :tangle (eval ml) :exports none +let ( |. ) s { x ; y ; z } = + make { x = s *. x ; + y = s *. y ; + z = s *. z ; } + #+end_src + +*** Add + + #+begin_src ocaml :tangle (eval mli) +val ( |+ ) : t -> t -> t + #+end_src + + #+begin_example +Coordinate.( + { x=1. ; y=2. ; z=3. } |+ { x=2. ; y=3. ; z=1. } +);; +- : Coordinate.t = {Qcaml.Common.Coordinate.x = 3.; y = 5.; z = 4.} + #+end_example + + #+begin_src ocaml :tangle (eval ml) :exports none +let ( |+ ) + { x = x1 ; y = y1 ; z = z1 } + { x = x2 ; y = y2 ; z = z2 } = + make { x = x1 +. x2 ; + y = y1 +. y2 ; + z = z1 +. z2 ; } + #+end_src + +*** Subtract + + #+begin_src ocaml :tangle (eval mli) +val ( |- ) : t -> t -> t + #+end_src + + #+begin_example +Coordinate.( + { x=1. ; y=2. ; z=3. } |- { x=2. ; y=3. ; z=1. } +);; +- : Coordinate.t = {Qcaml.Common.Coordinate.x = -1.; y = -1.; z = 2.} + #+end_example + + #+begin_src ocaml :tangle (eval ml) :exports none +let ( |- ) + { x = x1 ; y = y1 ; z = z1 } + { x = x2 ; y = y2 ; z = z2 } = + make { x = x1 -. x2 ; + y = y1 -. y2 ; + z = z1 -. z2 ; } + #+end_src + +*** Negative + + #+begin_src ocaml :tangle (eval mli) +val neg : t -> t + #+end_src + + #+begin_example +Coordinate.neg { x=1. ; y=2. ; z=3. } ;; +- : Coordinate.t = {Qcaml.Common.Coordinate.x = -1.; y = -2.; z = -3.} + #+end_example + + #+begin_src ocaml :tangle (eval ml) :exports none +let neg a = -1. |. a + #+end_src + +*** Dot product + + #+begin_src ocaml :tangle (eval mli) +val dot : t -> t -> float + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +let dot + { x = x1 ; y = y1 ; z = z1 } + { x = x2 ; y = y2 ; z = z2 } = + x1 *. x2 +. + y1 *. y2 +. + z1 *. z2 + #+end_src + +*** Norm + + #+begin_src ocaml :tangle (eval mli) +val norm : t -> float + #+end_src + + $\ell{^2}$ norm of the vector. + + #+begin_src ocaml :tangle (eval ml) :exports none +let norm u = + sqrt ( dot u u ) + #+end_src + + +** Printers + + Coordinates can be printed in bohr or angstrom. + + #+begin_src ocaml :tangle (eval mli) +val pp : Format.formatter -> t -> unit +val pp_bohr: Format.formatter -> t -> unit +val pp_angstrom : Format.formatter -> t -> unit + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +open Format +let pp ppf c = + fprintf ppf "@[@[%8.4f@] @[%8.4f@] @[%8.4f@]@]" c.x c.y c.z + +let pp_bohr ppf c = + fprintf ppf "@[(@[%10f@], @[%10f@], @[%10f@] Bohr)@]" c.x c.y c.z + +let pp_angstrom ppf c = + let c = bohr_to_angstrom c in + fprintf ppf "@[(@[%10f@], @[%10f@], @[%10f@] Angs)@]" c.x c.y c.z + #+end_src + diff --git a/common/lib/coordinate.ml b/common/lib/coordinate.ml index 3109d8e..fed9d11 100644 --- a/common/lib/coordinate.ml +++ b/common/lib/coordinate.ml @@ -1,3 +1,4 @@ +(* [[file:../coordinate.org::*Type][Type:2]] *) type bohr type angstrom @@ -11,79 +12,135 @@ type 'a point = xyz type t = bohr point -external make : 'a point -> t = "%identity" -external make_angstrom : 'a point -> angstrom point = "%identity" - - type axis = X | Y | Z +(* Type:2 ends here *) +(* [[file:../coordinate.org::*~make~][~make~:2]] *) +external make : 'a point -> t = "%identity" +(* ~make~:2 ends here *) -let a_to_b a = Constants.a0_inv *. a +(* [[file:../coordinate.org::*~make_angstrom~][~make_angstrom~:2]] *) +external make_angstrom : 'a point -> angstrom point = "%identity" +(* ~make_angstrom~:2 ends here *) + +(* [[file:../coordinate.org::*~bohr_to_angstrom~][~bohr_to_angstrom~:2]] *) let b_to_a b = Constants.a0 *. b let bohr_to_angstrom { x ; y ; z } = - make - { - x = b_to_a x ; - y = b_to_a y ; - z = b_to_a z ; - } + make { x = b_to_a x ; + y = b_to_a y ; + z = b_to_a z ; } +(* ~bohr_to_angstrom~:2 ends here *) + +(* [[file:../coordinate.org::*~angstrom_to_bohr~][~angstrom_to_bohr~:2]] *) +let a_to_b a = Constants.a0_inv *. a let angstrom_to_bohr { x ; y ; z } = - make - { - x = a_to_b x ; - y = a_to_b y ; - z = a_to_b z ; - } - + make { x = a_to_b x ; + y = a_to_b y ; + z = a_to_b z ; } +(* ~angstrom_to_bohr~:2 ends here *) +(* [[file:../coordinate.org::*~zero~][~zero~:2]] *) let zero = - make { x = 0. ; y = 0. ; z = 0. } - - -(** Linear algebra *) -let ( |. ) s { x ; y ; z } = - make { - x = s *. x ; - y = s *. y ; - z = s *. z ; - } - -let ( |+ ) { x = x1 ; y = y1 ; z = z1 } { x = x2 ; y = y2 ; z = z2 } = - make { - x = x1 +. x2 ; - y = y1 +. y2 ; - z = z1 +. z2 ; - } - - -let ( |- ) { x = x1 ; y = y1 ; z = z1 } { x = x2 ; y = y2 ; z = z2 } = - make { - x = x1 -. x2 ; - y = y1 -. y2 ; - z = z1 -. z2 ; - } - - -let neg a = -1. |. a - - -let dot { x = x1 ; y = y1 ; z = z1 } { x = x2 ; y = y2 ; z = z2 } = - x1 *. x2 +. y1 *. y2 +. z1 *. z2 - - -let norm u = - sqrt ( dot u u ) - + make { x = 0. ; y = 0. ; z = 0. } +(* ~zero~:2 ends here *) +(* [[file:../coordinate.org::*~get~][~get~:2]] *) let get axis { x ; y ; z } = match axis with | X -> x | Y -> y - | Z -> z + | Z -> z +(* ~get~:2 ends here *) + +(* #+begin_example + * Coordinate.( + * 2. |. { x=1. ; y=2. ; z=3. } + * ) ;; + * - : Coordinate.t = {Qcaml.Common.Coordinate.x = 2.; y = 4.; z = 6.} + * #+end_example *) + + +(* [[file:../coordinate.org::*Scale][Scale:2]] *) +let ( |. ) s { x ; y ; z } = + make { x = s *. x ; + y = s *. y ; + z = s *. z ; } +(* Scale:2 ends here *) + + + +(* #+begin_example + * Coordinate.( + * { x=1. ; y=2. ; z=3. } |+ { x=2. ; y=3. ; z=1. } + * );; + * - : Coordinate.t = {Qcaml.Common.Coordinate.x = 3.; y = 5.; z = 4.} + * #+end_example *) + + +(* [[file:../coordinate.org::*Add][Add:2]] *) +let ( |+ ) + { x = x1 ; y = y1 ; z = z1 } + { x = x2 ; y = y2 ; z = z2 } = + make { x = x1 +. x2 ; + y = y1 +. y2 ; + z = z1 +. z2 ; } +(* Add:2 ends here *) + + + +(* #+begin_example + * Coordinate.( + * { x=1. ; y=2. ; z=3. } |- { x=2. ; y=3. ; z=1. } + * );; + * - : Coordinate.t = {Qcaml.Common.Coordinate.x = -1.; y = -1.; z = 2.} + * #+end_example *) + + +(* [[file:../coordinate.org::*Subtract][Subtract:2]] *) +let ( |- ) + { x = x1 ; y = y1 ; z = z1 } + { x = x2 ; y = y2 ; z = z2 } = + make { x = x1 -. x2 ; + y = y1 -. y2 ; + z = z1 -. z2 ; } +(* Subtract:2 ends here *) + + + +(* #+begin_example + * Coordinate.neg { x=1. ; y=2. ; z=3. } ;; + * - : Coordinate.t = {Qcaml.Common.Coordinate.x = -1.; y = -2.; z = -3.} + * #+end_example *) + + +(* [[file:../coordinate.org::*Negative][Negative:2]] *) +let neg a = -1. |. a +(* Negative:2 ends here *) + +(* [[file:../coordinate.org::*Dot product][Dot product:2]] *) +let dot + { x = x1 ; y = y1 ; z = z1 } + { x = x2 ; y = y2 ; z = z2 } = + x1 *. x2 +. + y1 *. y2 +. + z1 *. z2 +(* Dot product:2 ends here *) + + + +(* $\ell{^2}$ norm of the vector. *) + + +(* [[file:../coordinate.org::*Norm][Norm:2]] *) +let norm u = + sqrt ( dot u u ) +(* Norm:2 ends here *) + +(* [[file:../coordinate.org::*Printers][Printers:2]] *) open Format let pp ppf c = fprintf ppf "@[@[%8.4f@] @[%8.4f@] @[%8.4f@]@]" c.x c.y c.z @@ -94,4 +151,4 @@ let pp_bohr ppf c = let pp_angstrom ppf c = let c = bohr_to_angstrom c in fprintf ppf "@[(@[%10f@], @[%10f@], @[%10f@] Angs)@]" c.x c.y c.z - +(* Printers:2 ends here *) diff --git a/common/lib/coordinate.mli b/common/lib/coordinate.mli index 0521de1..5c73384 100644 --- a/common/lib/coordinate.mli +++ b/common/lib/coordinate.mli @@ -1,10 +1,8 @@ -(** Type for coordinates in 3D space. - - All operations on points are done in atomic units. Therefore, - all coordinates are given in bohr and manipulated with this - module. - *) +(* Type + * + * #+NAME: types *) +(* [[file:../coordinate.org::types][types]] *) type bohr type angstrom @@ -18,91 +16,117 @@ type 'a point = xyz type t = bohr point -val make : 'a point -> t -(** Creates a point in atomic units *) - -val make_angstrom : 'a point -> angstrom point -(** Creates a point in Angstrom *) - type axis = X | Y | Z +(* types ends here *) +(* ~make~ + * + * Creates a point in atomic units. *) + + +(* [[file:../coordinate.org::*~make~][~make~:1]] *) +val make : 'a point -> t +(* ~make~:1 ends here *) + +(* ~make_angstrom~ + * + * Creates a point in angstrom. *) + + +(* [[file:../coordinate.org::*~make_angstrom~][~make_angstrom~:1]] *) +val make_angstrom : 'a point -> angstrom point +(* ~make_angstrom~:1 ends here *) + +(* ~bohr_to_angstrom~ + * + * Converts a point in bohr to angstrom. *) + + +(* [[file:../coordinate.org::*~bohr_to_angstrom~][~bohr_to_angstrom~:1]] *) val bohr_to_angstrom : bohr point -> angstrom point -(** Converts a point in bohr to angstrom. *) +(* ~bohr_to_angstrom~:1 ends here *) + +(* ~angstrom_to_bohr~ + * + * Converts a point in angstrom to bohr. *) +(* [[file:../coordinate.org::*~angstrom_to_bohr~][~angstrom_to_bohr~:1]] *) val angstrom_to_bohr : angstrom point -> bohr point -(** Converts a point in Angstrom to bohr. *) +(* ~angstrom_to_bohr~:1 ends here *) + +(* ~zero~ + * + * ~zero~ = (0., 0., 0.) *) +(* [[file:../coordinate.org::*~zero~][~zero~:1]] *) val zero : bohr point -(** [zero = { x = 0. ; y=0. ; z=0. }] *) +(* ~zero~:1 ends here *) + +(* ~get~ + * + * Extracts the projection of the coordinate on an axis. + * + * #+begin_example + * Coordinate.(get Y { x=1. ; y=2. ; z=3. }) + * - float: 2. + * #+end_example *) +(* [[file:../coordinate.org::*~get~][~get~:1]] *) val get : axis -> bohr point -> float -(** Extracts the projection of the coordinate on an axis. - - Example: - - [Coordinate.(get Y) { x=1. ; y=2. ; z=3. } -> 2.] - -*) - -(** {1 Vector operations} *) +(* ~get~:1 ends here *) +(* Scale *) + +(* [[file:../coordinate.org::*Scale][Scale:1]] *) val ( |. ) : float -> t -> t -(** Scale by a float. +(* Scale:1 ends here *) - Example: - - [ 2. |. { x=1. ; y=2. ; z=3. } -> { x=2. ; y=4. ; z=6. } ] - - *) +(* Add *) +(* [[file:../coordinate.org::*Add][Add:1]] *) val ( |+ ) : t -> t -> t -(** Add two vectors. +(* Add:1 ends here *) - Example: - - {[{ x=1. ; y=2. ; z=3. } |+ { x=2. ; y=3. ; z=1. } -> - { x=3. ; y=5. ; z=4. }]} - - *) +(* Subtract *) +(* [[file:../coordinate.org::*Subtract][Subtract:1]] *) val ( |- ) : t -> t -> t -(** Subtract two vectors. +(* Subtract:1 ends here *) - Example: - - {[{ x=1. ; y=2. ; z=3. } |- { x=2. ; y=3. ; z=1. } -> - { x=-1. ; y=-1. ; z=2. }]} - - *) +(* Negative *) +(* [[file:../coordinate.org::*Negative][Negative:1]] *) val neg : t -> t -(** Example: +(* Negative:1 ends here *) -{[Coordinate.neg { x=1. ; y=2. ; z=-3. } -> - { x=-1. ; y=-2. ; z=3. }]} +(* Dot product *) - *) +(* [[file:../coordinate.org::*Dot product][Dot product:1]] *) val dot : t -> t -> float -(** Dot product. *) +(* Dot product:1 ends here *) + +(* Norm *) +(* [[file:../coordinate.org::*Norm][Norm:1]] *) val norm : t -> float -(** L{^2} norm of the vector. *) +(* Norm:1 ends here *) + +(* Printers + * + * Coordinates can be printed in bohr or angstrom. *) -(** {2 Printers} *) - -val pp: Format.formatter -> t -> unit - +(* [[file:../coordinate.org::*Printers][Printers:1]] *) +val pp : Format.formatter -> t -> unit val pp_bohr: Format.formatter -> t -> unit - val pp_angstrom : Format.formatter -> t -> unit - +(* Printers:1 ends here *)