### 6 releases

0.3.1 | Jul 13, 2019 |
---|---|

0.3.0 | Apr 27, 2019 |

0.2.2 | Apr 12, 2019 |

0.2.1 | May 19, 2017 |

0.1.0 | Dec 17, 2015 |

#**1490** in Math

**MIT**license

58KB

1.5K
SLoC

# differential-geometry

This is a crate for differential-geometric calculations, like tensor calculus on manifolds etc.

Features (version 0.1):

- Defining coordinate systems and conversions between them.
- Defining points on a manifold.
- Defining tensors; tensor addition, subtraction, outer product, inner product, contraction, matrix inversion.

###
`lib.rs`

:

**diffgeom** is a crate aiming to leverage the Rust type system to provide
a type-safe API for tensor calculus on arbitrary manifolds.

# What is tensor calculus?

Tensors are, in a way, a generalized idea similar to vectors and matrices. They are multidimensional arrays of numbers, but not all such arrays are tensors. What makes them tensors is how they behave in coordinate transformations. The details are a topic for a whole academic lecture, so I won't go into them. What's important is that tensors can be used for describing properties of curved spaces and it is the intended use case of this crate.

# Problems

Unfortunately, Rust currently doesn't support generics over static values, so another representation of type-level numbers is required. In this crate one provided by typenum is being used. This makes it necessary to use a lot of trait bounds, which break the compiler in a few ways, so some operations require the usage of a pretty cumbersome syntax.

# Example

Below you can see a code sample presenting some simple operations.

`use` `std``::``ops``::`Mul`;`
`use` `generic_array``::``{`GenericArray`,` ArrayLength`}``;`
`use` `diffgeom``::``coordinates``::``{`CoordinateSystem`,` Point`}``;`
`use` `diffgeom``::``tensors``::``{`Vector`,` Covector`,` Matrix`,` InnerProduct`}``;`
`use` `generic_array``::`arr`;`
`use` `generic_array``::``typenum``::``consts``::``{``U0``,` `U1``,` `U2``}``;`
`fn` `main``(``)`` ``{`
`//` First, a coordinate system must be defined
`struct` `SomeSystem``;`
`impl` `CoordinateSystem ``for`` ``SomeSystem` `{`
`type` `Dimension` `=` `U2``;` `//` a two-dimensional coordinate system
`}`
`//` Each tensor should be anchored at a point, so let's create one
`let` point `=` `Point``::``<`SomeSystem`>``::`new`(``arr!``[``f64``;` `0.``0``,` `0.``0``]``)``;`
`//` A vector can be defined like that:
`let` vector `=` `Vector``::``<`SomeSystem`>``::`new`(`point`,` `arr!``[``f64``;` `1.``0``,` `2.``0``]``)``;`
`//` There are also covectors
`let` covector `=` `Covector``::``<`SomeSystem`>``::`new`(`point`,` `arr!``[``f64``;` `2.``0``,` `0.``5``]``)``;`
`//` They can be multiplied, yielding a matrix
`let` matrix `=` `<`Vector`<`SomeSystem`>` `as` Mul`<`Covector`<`SomeSystem`>``>``>``::`mul`(`vector`,` covector`)``;`
`//` Unfortunately this causes infinite recursion in the compiler:
`//` let matrix = vector * covector;
`//` They can be contracted
`let` scalar `=` `<`Vector`<`SomeSystem`>` `as` InnerProduct`<`Covector`<`SomeSystem`>`, U0, U1`>``>`
`::`inner_product`(`vector`,` covector`)``;`
`//` scalars returned by tensor functions need to be dereffed to f64
`assert_eq!``(``*`scalar`,` `*`matrix`.``trace``::``<`U0, U1`>``(``)``)``;`
`}`

#### Dependencies

~260KB