clif-0.1.1.0: A Clifford algebra number type for Haskell

Copyright (c) Matti A. Eskelinen 2016-2017 MIT matti.a.eskelinen@gmail.com experimental POSIX Safe Haskell2010

Clif.Basis

Description

# Motivation

A Clifford algebra is generated by a set of linearly independent (but not necessarily orthogonal) basis vectors and a metric (bilinear form) from the vectors to a field (or unital ring). After the basis and bilinear form are fixed, the Clifford algebra is exactly the quotient of the free algebra of the basis vectors by the equality relation generated by the form (see https://en.wikipedia.org/wiki/Clifford_algebra).

# Implementation

Defining a basis is abstracted using the two-parameter typeclass Basis. A Basis b a for a Clifford algebra is defined by implementing a metric that takes two vectors of type b (for basis) and returns a number of type a, which is then used by basisMul to implement multiplication of vectors. For computational reasons, any vector type must have some canonical ordering (i.e. be an instance of Ord). The constructors for Euclidean and Lorentzian types can be used to map any such type with a corresponding metric.

While not strictly necessary for the abstraction, functions canonical and basisMul are included in the class with respective default implementations (orderOrthoBasis and orthoMul) in order to provide an easy way to override them using a more efficient implementation for a user-supplied basis. Note that the default implementations are only valid for a diagonal metric; Use orderBasis and nonOrthoMul if you define a non-diagonal metric.

Synopsis

# Classes

class (Ord b, Num a) => Basis b a where Source #

A typeclass for specifying a metric space The default implementation uses orthoMul; Replace it if you require a non-diagonal metric.

Minimal complete definition

metric

Methods

metric :: b -> b -> a Source #

canonical :: ([b], a) -> [([b], a)] Source #

basisMul :: ([b], a) -> ([b], a) -> [([b], a)] Source #

Instances

 (Ord b, Num a) => Basis (Lorentzian b) a Source # Methodsmetric :: Lorentzian b -> Lorentzian b -> a Source #canonical :: ([Lorentzian b], a) -> [([Lorentzian b], a)] Source #basisMul :: ([Lorentzian b], a) -> ([Lorentzian b], a) -> [([Lorentzian b], a)] Source # (Ord b, Num a) => Basis (Euclidean b) a Source # Methodsmetric :: Euclidean b -> Euclidean b -> a Source #canonical :: ([Euclidean b], a) -> [([Euclidean b], a)] Source #basisMul :: ([Euclidean b], a) -> ([Euclidean b], a) -> [([Euclidean b], a)] Source #

# Basis construction

newtype Euclidean a Source #

Data type for constructing Euclidean basis vectors (metric is 1 for matching vectors, 0 otherwise).

Constructors

 E FieldsgetE :: a

Instances

 Eq a => Eq (Euclidean a) Source # Methods(==) :: Euclidean a -> Euclidean a -> Bool #(/=) :: Euclidean a -> Euclidean a -> Bool # Ord a => Ord (Euclidean a) Source # Methodscompare :: Euclidean a -> Euclidean a -> Ordering #(<) :: Euclidean a -> Euclidean a -> Bool #(<=) :: Euclidean a -> Euclidean a -> Bool #(>) :: Euclidean a -> Euclidean a -> Bool #(>=) :: Euclidean a -> Euclidean a -> Bool #max :: Euclidean a -> Euclidean a -> Euclidean a #min :: Euclidean a -> Euclidean a -> Euclidean a # Show a => Show (Euclidean a) Source # MethodsshowsPrec :: Int -> Euclidean a -> ShowS #show :: Euclidean a -> String #showList :: [Euclidean a] -> ShowS # Source # Associated Typestype Rep (Euclidean a) :: * -> * # Methodsfrom :: Euclidean a -> Rep (Euclidean a) x #to :: Rep (Euclidean a) x -> Euclidean a # (Ord b, Num a) => Basis (Euclidean b) a Source # Methodsmetric :: Euclidean b -> Euclidean b -> a Source #canonical :: ([Euclidean b], a) -> [([Euclidean b], a)] Source #basisMul :: ([Euclidean b], a) -> ([Euclidean b], a) -> [([Euclidean b], a)] Source # type Rep (Euclidean a) Source # type Rep (Euclidean a) = D1 * (MetaData "Euclidean" "Clif.Basis" "clif-0.1.1.0-J52Flxh9ZsUFmLCbVUwBKK" True) (C1 * (MetaCons "E" PrefixI True) (S1 * (MetaSel (Just Symbol "getE") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * a)))

data Lorentzian a Source #

Data type for Lorentzian (mixed signature) basis vectors.

Constructors

 T a Timelike basis vector (-1) S a Spacelike basis vector (+1)

Instances

 Eq a => Eq (Lorentzian a) Source # Methods(==) :: Lorentzian a -> Lorentzian a -> Bool #(/=) :: Lorentzian a -> Lorentzian a -> Bool # Ord a => Ord (Lorentzian a) Source # Methodscompare :: Lorentzian a -> Lorentzian a -> Ordering #(<) :: Lorentzian a -> Lorentzian a -> Bool #(<=) :: Lorentzian a -> Lorentzian a -> Bool #(>) :: Lorentzian a -> Lorentzian a -> Bool #(>=) :: Lorentzian a -> Lorentzian a -> Bool #max :: Lorentzian a -> Lorentzian a -> Lorentzian a #min :: Lorentzian a -> Lorentzian a -> Lorentzian a # Show a => Show (Lorentzian a) Source # MethodsshowsPrec :: Int -> Lorentzian a -> ShowS #show :: Lorentzian a -> String #showList :: [Lorentzian a] -> ShowS # Source # Associated Typestype Rep (Lorentzian a) :: * -> * # Methodsfrom :: Lorentzian a -> Rep (Lorentzian a) x #to :: Rep (Lorentzian a) x -> Lorentzian a # (Ord b, Num a) => Basis (Lorentzian b) a Source # Methodsmetric :: Lorentzian b -> Lorentzian b -> a Source #canonical :: ([Lorentzian b], a) -> [([Lorentzian b], a)] Source #basisMul :: ([Lorentzian b], a) -> ([Lorentzian b], a) -> [([Lorentzian b], a)] Source # type Rep (Lorentzian a) Source # type Rep (Lorentzian a) = D1 * (MetaData "Lorentzian" "Clif.Basis" "clif-0.1.1.0-J52Flxh9ZsUFmLCbVUwBKK" False) ((:+:) * (C1 * (MetaCons "T" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * a))) (C1 * (MetaCons "S" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * a))))

orthoMul :: Basis b a => ([b], a) -> ([b], a) -> ([b], a) Source #

Multiplies together two blades of orthogonal vectors and simplifies the results to canonical order using orderOrthoBasis.

nonOrthoMul :: (Eq a, Basis b a) => ([b], a) -> ([b], a) -> [([b], a)] Source #

Multiplies two blades of (possibly non-orthogonal) basis vectors and simplifies the result to canonical order using orderBasis. Note that this generally results in a direct sum of blades, i.e. a list.

freeMul :: Num a => ([b], a) -> ([b], a) -> ([b], a) Source #

Free multiplication of scaled blades (concatenation of vectors and multiplication of scalars).

# Computation of canonical order

orderOrthoBasis :: Basis b a => [b] -> [b] -> a -> ([b], a) Source #

Canonical (ordered) form of a scaled basis blade of orthogonal vectors Uses a gnome sort to commute the basis vectors to order and keeps track of the commutations w.r.t. the blade multiplier, applying the equation

ba = -ab

for each consecutive pair ba in wrong order. Note that this relation holds only for a basis with a diagonal bilinear form, for others use the more general (albeit slower) orderBasis.

orderBasis :: (Eq a, Basis b a) => [([b], a)] -> [b] -> a -> [([b], a)] Source #

Canonical (ordered) form of a scaled basis blade of vectors Uses a gnome sort to commute the basis vectors to order and keeps track of the commutations applying the equation

ab = 2 B(a,b) - ba

for any given bilinear form B between the basis vectors and the number ring. Note that this is slower than using orderOrthoBasis if your bilinear form is diagonal (B(a,b) = 0 for a != b)