Copyright | (c) Matti A. Eskelinen 2016-2017 |
---|---|
License | OtherLicense |
Safe Haskell | Safe |
Language | Haskell2010 |
Clifford algebras (or geometric algebras) are itself mathematically interesting objects, but also a useful tool for vector algebra. This library attempts to make the Clifford algebraic computations easy and at least somewhat computationally efficient, while keeping the implementation as general as possible.
Since definitions and terminology vary greatly, here is a (non-rigorous) summary of terms that will be used in this tutorial:
- A vector is just an element of some set (or type). Note that this set may in principle be infinite.
- A basis is a set of vectors along with a bilinear form which maps a pair of them to some number (see Clif.Basis).
- A blade is any finite concatenation (free product) of vectors which contains each vector at most once, possibly multiplied by a scalar.
- A scalar is just a number, or a number multiplying the empty product.
- A
Clif
is a collection (direct sum) of the empty product, distinct blades and their multipliers (often called a multivector). - The Clifford algebra is the set (type) of
Clif
s with the Clifford (geometric) product and direct summation.
Getting started
To begin, we just need to import the main module of the library, Clif.
import Clif
This provides us with
- Constructors for the type
Clif
withNum
,Eq
and other instances that implement the Clifford algebra, - Constructors for
Euclidean
andLorentzian
basis vectors, - The typeclass
Basis
for constructing our own algebras, - Operations of the Clifford algebra defined in Clif.Algebra.
Defining our algebra
The type
joins the type Clif
b ab
(for basis) and some field (or ring)
together to form a Clifford algebra. Only Num
aClif
s with matching types b
and a
can be multiplied directly. To generate the Clifford product between any types b
and a
, we need to specify the bilinear form between them. This is done by providing an instance of the type class
. Let us do that for Basis
b a
:Basis
Char
Double
instance Basis Char Double where metric 't' 't' = -1 metric a b = if a == b then 1 else 0
The minimal complete definition for Basis
is the function metric
, which we have here defined to be a diagonal quadratic form on Char
. This is all we need to define the reasonably high-dimensional Clifford algebra Cl(1,n)(R) where n is the number of Unicode codepoints represented by Char
, with the signature (-, +, +, ...) for ('t', 'a', 'b', ...).
Few notes:
- We could have used the provided instance for the newtype
Lorentzian
to wrapChar
with a similar metric:
instance (Ord b, Num a) => Basis (Lorentzian b) a where metric (T a) (T b) = if a == b then -1 else 0 metric (S a) (S b) = if a == b then 1 else 0 metric _ _ = 0
In that case,
for any T
a
would have the same signature as the character 't' in our definition. However, defining a metric for the plain Char
aChar
is useful for demonstration, since it provides us with pretty printouts.
- Note that as in the definition for
, we do not actually need to fix the fieldBasis
(Lorentzian
b) aa
apart from theNum
constraint while defining the basis. - If the metric is not diagonal (
for somemetric
a b /= 0a /= b
), we need to replace the default implementations of the functionscanonical
andbasisMul
in the instance with more general implementations. See Clif.Basis for details.
Construction of Clif
values
Using our Char
basis, we can start constructing values of type
using the provided constructors. We can start by introducing the vectors needed to represent Cl(1,3)(R) using the Clif
Char
Double
vec
constructor:
t = vec 't' 1 x = vec 'x' 1 y = vec 'y' 1 z = vec 'z' 1
To make it specific that we are working in Cl(1,3)(R), we can define the pseudoscalar txyz
. This can be done in a number of ways:
i = t * x * y * z i = t /\ x /\ y /\ z
- by using the
blade
constructor or its infix synonym*:
to explicitly create a blade consisting of the same basis vectors:
i = blade "txyz" 1 i = 1 *: "txyz"
Note that the last form using the infix operator *:
is used for the Show
instance to produce concise output. Each of the previous definitions will yield the following output in GHCI for i:
>>>
i
1.0 *: "txyz"
Due to the Num
instance, we do not usually need to explicitly embed scalars. If we want to be specific, we can write
answer = 42 :: Clif Char Double
Computation
We can now use any of the available operations to calculate on the Clif
values, such as
- Simple multivector algebra:
>>>
2 * x * y - y * x
1.0 *: "xy"
- Wedge products:
>>>
x /\ y
1.0 *: "xy"
- Reversion:
>>>
rev i
1.0 *: "zyxt"
>>>
x * y * z / y
-1.0 *: "xy"
Copyright
This tutorial is licensed under a Creative Commons Attribution 4.0 International License