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`

with`Num`

,`Eq`

and other instances that implement the Clifford algebra, - Constructors for
`Euclidean`

and`Lorentzian`

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 a`b`

(for *basis*) and some field (or ring)

together to form a Clifford algebra. Only `Num`

a`Clif`

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 wrap`Char`

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`

a`Char`

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 field`Basis`

(`Lorentzian`

b) a`a`

apart from the`Num`

constraint while defining the basis. - If the metric is not diagonal (

for some`metric`

a b /= 0`a /= b`

), we need to replace the default implementations of the functions`canonical`

and`basisMul`

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 `Clif`

`Char`

`Double`

**Cl**(1,3)(R) using the `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:

`>>>`

1.0 *: "txyz"`i`

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:

`>>>`

1.0 *: "xy"`2 * x * y - y * x`

- Wedge products:

`>>>`

1.0 *: "xy"`x /\ y`

- Reversion:

`>>>`

1.0 *: "zyxt"`rev i`

`>>>`

-1.0 *: "xy"`x * y * z / y`

# Copyright

This tutorial is licensed under a Creative Commons Attribution 4.0 International License