diffgeom/
lib.rs

1/*!
2**diffgeom** is a crate aiming to leverage the Rust type system to provide
3a type-safe API for tensor calculus on arbitrary manifolds.
4
5What is tensor calculus?
6========================
7
8Tensors are, in a way, a generalized idea similar to vectors and matrices. They are
9multidimensional arrays of numbers, but not all such arrays are tensors. What makes
10them tensors is how they behave in coordinate transformations. The details are a
11topic for a whole academic lecture, so I won't go into them. What's important
12is that tensors can be used for describing properties of curved spaces and it is
13the intended use case of this crate.
14
15Problems
16========
17
18Unfortunately, Rust currently doesn't support generics over static values, so
19another representation of type-level numbers is required. In this crate one
20provided by [typenum](https://github.com/paholg/typenum) is being used. This
21makes it necessary to use a lot of trait bounds, which break the compiler in
22a few ways, so some operations require the usage of a pretty cumbersome syntax.
23
24Example
25=======
26
27Below you can see a code sample presenting some simple operations.
28
29```
30# extern crate diffgeom;
31# extern crate generic_array;
32use std::ops::Mul;
33use generic_array::{GenericArray, ArrayLength};
34use diffgeom::coordinates::{CoordinateSystem, Point};
35use diffgeom::tensors::{Vector, Covector, Matrix, InnerProduct};
36use generic_array::arr;
37use generic_array::typenum::consts::{U0, U1, U2};
38
39fn main() {
40    // First, a coordinate system must be defined
41    struct SomeSystem;
42    impl CoordinateSystem for SomeSystem {
43        type Dimension = U2;    // a two-dimensional coordinate system
44    }
45
46    // Each tensor should be anchored at a point, so let's create one
47    let point = Point::<SomeSystem>::new(arr![f64; 0.0, 0.0]);
48
49    // A vector can be defined like that:
50    let vector = Vector::<SomeSystem>::new(point, arr![f64; 1.0, 2.0]);
51
52    // There are also covectors
53    let covector = Covector::<SomeSystem>::new(point, arr![f64; 2.0, 0.5]);
54
55    // They can be multiplied, yielding a matrix
56    let matrix = <Vector<SomeSystem> as Mul<Covector<SomeSystem>>>::mul(vector, covector);
57    // Unfortunately this causes infinite recursion in the compiler:
58    // let matrix = vector * covector;
59
60    // They can be contracted
61    let scalar = <Vector<SomeSystem> as InnerProduct<Covector<SomeSystem>, U0, U1>>
62        ::inner_product(vector, covector);
63
64    // scalars returned by tensor functions need to be dereffed to f64
65    assert_eq!(*scalar, *matrix.trace::<U0, U1>());
66}
67```
68*/
69pub extern crate generic_array;
70pub use generic_array::typenum;
71
72pub mod coordinates;
73pub mod macros;
74pub mod metric;
75pub mod tensors;
76
77#[cfg(test)]
78mod tests;