Coordinate org

This commit is contained in:
Anthony Scemama 2020-12-27 17:23:47 +01:00
parent 8efb05beb9
commit c6b48bed35
3 changed files with 467 additions and 113 deletions

273
common/coordinate.org Normal file
View File

@ -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
<<types>>
#+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

View File

@ -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 *)

View File

@ -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 *)