# galgebra.ga¶

Geometric Algebra (inherits Metric)

## Members¶

class galgebra.ga.lazy_dict(d, f_value)[source]

A dictionary that creates missing entries on the fly.

When the dictionary is indexed and the key used is not one of the existing keys, self.f_value(key) is called to evaluate the key. The result is then added to the dictionary so that self.f_value is not used to evaluate the same key again.

Parameters
• d – Arguments to pass on to the dict constructor, typically a regular dictionary

• f_value (function) – The function to call to generate a value for a given key

clear() → None. Remove all items from D.
copy() → a shallow copy of D
fromkeys()

Create a new dictionary with keys from iterable and values set to value.

get()

Return the value for key if key is in the dictionary, else default.

items() → a set-like object providing a view on D’s items
keys() → a set-like object providing a view on D’s keys
pop(k[, d]) → v, remove specified key and return the corresponding value.

If key is not found, d is returned if given, otherwise KeyError is raised

popitem() → (k, v), remove and return some (key, value) pair as a

2-tuple; but raise KeyError if D is empty.

setdefault()

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None. Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values() → an object providing a view on D’s values
galgebra.ga.update_and_substitute(expr1, expr2, mul_dict)[source]

Linear expand expr1 and expr2 to get (summation convention):

expr1 = coefs1[i] * bases1[i]
expr2 = coefs2[j] * bases2[j]


where coefs1 and coefs2 are lists of are commutative expressions and bases1 and bases2 are lists of bases for the geometric algebra.

Then evaluate:

expr = coefs1[i] * coefs2[j] * mul_dict[bases1[i], bases2[j]]


where mul_dict[bases1[i], bases2[j]] contains the appropriate product of bases1[i]*bases2[j] as a linear combination of scalars and bases of the geometric algebra.

galgebra.ga.nc_subs(expr, base_keys, base_values=None)[source]

See if expr contains nc (non-commutative) keys in base_keys and substitute corresponding value in base_values for nc key. This was written since standard sympy subs was very slow in performing this operation for non-commutative keys for long lists of keys.

class galgebra.ga.GradedTuple[source]

A nested tuple grouped by grade.

self[i] refers to a the elements associated with grade i.

flat
Type

Tuple[T]

The elements flattened out in order of grade.

count()

Return number of occurrences of value.

index()

Return first index of value.

Raises ValueError if the value is not present.

class galgebra.ga.OrderedBiMap(items)[source]

A dict with an .inverse attribute mapping in the other direction

clear() → None. Remove all items from od.
copy() → a shallow copy of od
fromkeys()

Create a new ordered dictionary with keys from iterable and values set to value.

get()

Return the value for key if key is in the dictionary, else default.

items() → a set-like object providing a view on D’s items
keys() → a set-like object providing a view on D’s keys
move_to_end()

Move an existing element to the end (or beginning if last is false).

Raise KeyError if the element does not exist.

pop(k[, d]) → v, remove specified key and return the corresponding

value. If key is not found, d is returned if given, otherwise KeyError is raised.

popitem()

Remove and return a (key, value) pair from the dictionary.

Pairs are returned in LIFO order if last is true or FIFO order if false.

setdefault()

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None. Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values() → an object providing a view on D’s values
class galgebra.ga.BladeProductFunction(ga)[source]

Base class for implementations of products between blade representations

__call__(A: sympy.core.expr.Expr, B: sympy.core.expr.Expr)sympy.core.expr.Expr[source]

Perform the multiplication

of_basis_blades(blade1: sympy.core.symbol.Symbol, blade2: sympy.core.symbol.Symbol)sympy.core.expr.Expr[source]

Compute the product of two basis blades

table_dict: galgebra.ga.lazy_dict[Tuple[sympy.core.symbol.Symbol, sympy.core.symbol.Symbol], sympy.core.expr.Expr]

A cache of the result of of_basis_blades()

class galgebra.ga.BaseProductFunction(ga)[source]

Base class for implementations of products between base blade representations

of_basis_bases(base1: sympy.core.symbol.Symbol, base2: sympy.core.symbol.Symbol)sympy.core.expr.Expr[source]

Compute the product of two basis bases

class galgebra.ga.Ga(bases, *, wedge=True, **kwargs)[source]

The vector space (basis, metric, derivatives of basis vectors) is defined by the base class Metric.

The instanciating the class Ga constructs the geometric algebra of the vector space defined by the metric.

The construction includes the multivector bases, multiplication tables or functions for the geometric (*), inner (|), outer (^) products, plus the left (<) and right (>) contractions. The geometric derivative operator and any required connections for the derivative are also calculated.

Except for the geometric product in the case of a non-orthogonal set of basis vectors all products and connections (if needed) are calculated when needed and place in dictionaries (lists of tuples) to be used when needed. This greatly speeds up evaluations of multivector expressions over previous versions of this code since the products of multivector bases and connection are not calculated unless they are actually needed in the current calculation.

Only instantiate the Ga class via the Mv class or any use of enhanced printing (text or latex) will cause the bases and multiplication table entries to be incorrectly labeled .

Inherited from Metric class

Basis, basis bases, and basis blades data structures

 indexes Index tuples of basis blades bases Bases (non-commutative sympy symbols) by grade. blades Basis blades symbols by grade. mv_blades mv.Mv instances corresponding to blades. coord_vec Linear combination of coordinates and basis vectors. indexes_to_blades_dict Bidirectional map from index tuples (indices) to basis blades (blades) indexes_to_bases_dict Bidirectional map from index tuples (indices) to basis bases (bases)

Multiplication data structures

The following properties contain implementations of the operators *, ^, |, <, and >:

 mul The geometric product, $$A B$$ wedge The wedge product, $$A \wedge B$$ hestenes_dot The hestenes dot product, $$A \bullet B$$ left_contract The left contraction, $$A \rfloor B$$ right_contract The right contraction, $$A \lfloor B$$

While behaving like functions, each of these also has a BladeProductFunction.table_dict attribute, which contains a lazy lookup table of the products of basis blades.

For non-orthogonal algebras, there is one additional operation, this one mapping bases instead of blades. Unlike the others, the table_dict attribute is pre-computed:

 basic_mul The geometic product of objects in base form, $$A B$$

Reciprocal basis data structures

 galgebra.metric.Metric.r_symbols r_basis Reciprocal basis vectors $$e^{j}$$ as linear combination of basis vector symbols. r_basis_dict Dictionary to represent reciprocal basis vectors as expansions in terms of basis vectors. r_basis_mv List of reciprocal basis vectors in terms of basis multivectors.

Derivative data structures

de

Derivatives of basis functions. Two dimensional list. First entry is differentiating coordinate index. Second entry is basis vector index. Quantities are linear combinations of basis vector symbols.

grad

Geometric derivative operator from left. grad*F returns multivector derivative, F*grad returns differential operator.

rgrad

Geometric derivative operator from right. rgrad*F returns differential operator, F*rgrad returns multivector derivative.

Other members

dot_mode

Controls the behavior of dot()

value

dot aliases

'|'

hestenes_dot()

'<'

left_contract()

'>'

right_contract()

Parameters
• bases – Passed as basis to Metric.

• wedge – Use ^ symbol to print basis blades

• **kwargs – See galgebra.metric.Metric.

static dual_mode(mode='I+')[source]

Sets mode of multivector dual function for all geometric algebras in users program.

If Ga.dual_mode(mode) not called the default mode is 'I+'.

mode

return value

+I

I*self

-I

-I*self

I+

self*I

I-

-self*I

+Iinv

Iinv*self

-Iinv

-Iinv*self

Iinv+

self*Iinv

Iinv-

-self*Iinv

static com(A, B)[source]

Calculate commutator of multivectors $$A$$ and $$B$$. Returns $$(AB-BA)/2$$.

Additionally, commutator and anti-commutator operators are defined by

\begin{split}\begin{aligned} \texttt{A >> B} \equiv & {\displaystyle\frac{AB - BA}{2}} \\ \texttt{A << B} \equiv & {\displaystyle\frac{AB + BA}{2}}. \end{aligned}\end{split}
static build(*args, **kwargs)[source]

Static method to instantiate geometric algebra and return geometric algebra, basis vectors, and grad operator as a tuple.

coord_vec: sympy.core.expr.Expr

Linear combination of coordinates and basis vectors. For example in orthogonal 3D $$x*e_x+y*e_y+z*e_z$$.

make_grad(a: Union[galgebra.mv.Mv, Sequence[sympy.core.expr.Expr]], cmpflg: bool = False)galgebra.mv.Dop[source]

Obtain a gradient operator with respect to the multivector a, $$\bm{\nabla}_a$$.

mv(root=None, *args, **kwargs) → Union[galgebra.mv.Mv, Tuple[galgebra.mv.Mv, …]][source]

Instanciate and return a multivector for this, ‘self’, geometric algebra.

mvr(norm: bool = True) → Tuple[galgebra.mv.Mv, …][source]

Returns tumple of reciprocal basis vectors. If norm=True or basis vectors are orthogonal the reciprocal basis is normalized in the sense that

${i}\cdot e^{j} = \delta_{i}^{j}.$

If the basis is not orthogonal and norm=False then

$e_{i}\cdot e^{j} = I^{2}\delta_{i}^{j}.$
bases_dict(prefix: str = None) → Dict[str, sympy.core.symbol.Symbol][source]

returns a dictionary mapping basis element names to their MultiVector instances, optionally for specific grades

if you are lazy, you might do this to populate your namespace with the variables of a given layout.

>>> locals().update(ga.bases())

pdop(*args, **kwargs)galgebra.dop.Pdop[source]

Shorthand to construct a Pdop

dop(*args, **kwargs)galgebra.mv.Dop[source]

Shorthand to construct a Dop for this algebra

sdop(*args, **kwargs)galgebra.dop.Sdop[source]

Shorthand to construct a Sdop

lt(*args, **kwargs)[source]

Instanciate and return a linear transformation for this, ‘self’, geometric algebra.

sm(*args, **kwargs)galgebra.ga.Sm[source]

Instanciate and return a submanifold for this geometric algebra. See Sm for instantiation inputs.

indexes: galgebra.ga.GradedTuple[Tuple[int, ...]]

blades: galgebra.ga.GradedTuple[sympy.core.symbol.Symbol]

The bases for the multivector (geometric) algebra are formed from all combinations of the bases of the vector space, including the empty combination which is the scalars.

Each base is represented as a non-commutative symbol of the form

$e_{i_{1}}\wedge e_{i_{2}}\wedge ...\wedge e_{i_{r}}.$

where $$0 < i_{1} < i_{2} < ... < i_{r}$$ and $$0 < r \le n$$ the dimension of the vector space and $$0 < i_{j} \le n$$. The total number of all symbols of this form is $$2^{n}$$.

These are called the blade basis for the geometric algebra and any multivector can be represented by a linears combination of these blades. The number of basis vectors that are in the symbol for the blade is call the grade of the blade.

Representing the multivector as a linear combination of blades gives a blade decomposition of the multivector.

There is a linear mapping from bases to blades and blades to bases so that one can easily convert from one representation to another.

indexes_to_blades_dict: galgebra.ga.OrderedBiMap[Tuple[int, ...], sympy.core.symbol.Symbol]

Bidirectional map from index tuples (indices) to basis blades (blades)

bases: galgebra.ga.GradedTuple[sympy.core.symbol.Symbol]

Bases (non-commutative sympy symbols) by grade.

If the basis vectors are not orthogonal a second set of symbols is required in addition to the blades, given by:

$e_{i_{1}}e_{i_{2}}...e_{i_{r}}$

where $$0 < i_{1} < i_{2} < ... < i_{r}$$ and $$0 < r \le n$$ the dimension of the vector space and $$0 < i_{j} \le n$$. The total number of all symbols of this form is $$2^{n}$$. Any multivector can be represented as a linear combination of these bases.

For the case of an orthogonal set of basis vectors the bases and blades are identical, and so this attribute raises ValueError.

indexes_to_bases_dict: galgebra.ga.OrderedBiMap[Tuple[int, ...], sympy.core.symbol.Symbol]

Bidirectional map from index tuples (indices) to basis bases (bases)

mv_blades: galgebra.ga.GradedTuple[galgebra.mv.Mv]

mv.Mv instances corresponding to blades.

mv_basis: Tuple[galgebra.mv.Mv, ...]

mv.Mv instances corresponding to basis.

reduce_basis(blst)[source]

Repetitively applies reduce_basis_loop() to blst product representation until normal form is realized for non-orthogonal basis

If the basis vectors are represented by the non- commutative symbols $$e_1,...,e_n$$ then a grade $$r$$ base is the geometric product $$e_{i_1}e_{i_2}\cdots e_{i_r}$$ where $$i_1<i_2<\ldots<i_r$$ (normal form). Then in galgebra this base is represented by a single indexed non-commutative symbol with indexes $$[i_1,i_2,\ldots,i_r]$$. The total number of these bases in an n-dimensional vector space is $$2^n$$.

reduce_basis() takes the geometric products of basis vectors that are not in normal form (out of order) and reduces them to a sum of bases that are in normal form (in order). It does this by recursively applying the geometric algebra formula

$e_ie_j = 2(e_i \cdot e_j) - e_je_i$

where the scalar product $$e_i \cdot e_j$$ is obtained from the metric tensor of the vector space. This also allows one to calculate the geometric product of any two bases and grade of the geometric algebra, and form the multiplication table.

static reduce_basis_loop(g, blst)[source]

blst is a list of integers $$[i_{1},\ldots,i_{r}]$$ representing the geometric product of r basis vectors $$a_{{i_1}}\cdots a_{{i_r}}$$. reduce_basis_loop() searches along the list $$[i_{1},\ldots,i_{r}]$$ untill it finds $$i_{j} = i_{j+1}$$ and in this case contracts the list, or if $$i_{j} > i_{j+1}$$ it revises the list ($$\sim i_{j}$$ means remove $$i_{j}$$ from the list)

• Case 1: If $$i_{j} = i_{j+1}$$, return $$a_{i_{j}}^2$$ and $$[i_{1},\ldots,\sim i_{j},\sim i_{j+1},\ldots,i_{r}]$$

• Case 2: If $$i_{j} > i_{j+1}$$, return $$a_{i_{j}}.a_{i_{j+1}}$$, $$[i_{1},\ldots,\sim i_{j},\sim i_{j+1},\ldots,i_{r}]$$, and $$[i_{1},\ldots,i_{j+1},i_{j},\ldots,i_{r}]$$

This is an implementation of the formula

$e_i e_j = 2(e_i \cdot e_j) - e_j e_i$

Where $$e_i$$ and $$e_j$$ are basis vectors.

static blade_reduce(lst: List[int]) → Tuple[int, Optional[List[int]]][source]

Reduce wedge product of basis vectors to normal order.

lst is a list of indicies of basis vectors. blade_reduce sorts the list and determines if the overall number of exchanges in the list is odd or even, returning sign changes (sgn) and sorted list. If any two indicies in list are equal (wedge product is zero) sgn = 0 and lst = None are returned.

blade_expansion_dict: OrderedDict[sympy.core.symbol.Symbol, sympy.core.expr.Expr]

dictionary expanding blade basis in terms of base basis

base_expansion_dict: OrderedDict[sympy.core.symbol.Symbol, sympy.core.expr.Expr]

dictionary expanding base basis in terms of blade basis

basic_mul: galgebra.ga.BaseProductFunction

The geometic product of objects in base form, $$A B$$

mul: galgebra.ga.BladeProductFunction

The geometric product, $$A B$$

wedge: galgebra.ga.BladeProductFunction

The wedge product, $$A \wedge B$$

hestenes_dot: galgebra.ga.BladeProductFunction

The hestenes dot product, $$A \bullet B$$

scalar_product: galgebra.ga.BladeProductFunction

The scalar product, $$A * B$$

left_contract: galgebra.ga.BladeProductFunction

The left contraction, $$A \rfloor B$$

right_contract: galgebra.ga.BladeProductFunction

The right contraction, $$A \lfloor B$$

dot(A: sympy.core.expr.Expr, B: sympy.core.expr.Expr)sympy.core.expr.Expr[source]

Inner product |, <, or >.

The dot_mode attribute determines which of these is used.

grade_decomposition(A: _MaybeMv) → Dict[int, _MaybeMv][source]

Returns dictionary with grades as keys of grades of A. For example if A is a rotor the dictionary keys would be 0 and 2. For a vector the single key would be 1. Note A can be input as a multivector or an multivector object (sympy expression). If A is a multivector the dictionary entries are multivectors. If A is a sympy expression (in this case a linear combination of non-commutative symbols) the dictionary entries are sympy expressions.

split_multivector(A: _MaybeMv) → Tuple[Union[sympy.core.expr.Expr, int], Union[sympy.core.expr.Expr, int]][source]

Split multivector $$A$$ into commutative part $$a$$ and non-commutative part $$A'$$ so that $$A = a+A'$$

remove_scalar_part(A: _MaybeMv) → Union[sympy.core.expr.Expr, int][source]

Return non-commutative part (sympy object) of A.obj.

e_sq: sympy.core.expr.Expr

If self.gsym = True then $$E_{n}^2$$ is not evaluated, but is represented as $$E_{n}^2 = (-1)^{n*(n-1)/2}\operatorname{det}(g)$$ where $$\operatorname{det}(g)$$ the determinant of the metric tensor can be general scalar function of the coordinates.

r_basis: List[sympy.core.expr.Expr]

Reciprocal basis vectors $$e^{j}$$ as linear combination of basis vector symbols.

These satisfy

$e^{j}\cdot e_{k} = \delta_{k}^{j}$

where $$\delta_{k}^{j}$$ is the kronecker delta. We use the formula from Doran and Lasenby 4.94:

$e^{j} = (-1)^{j-1}e_{1} \wedge ...e_{j-1} \wedge e_{j+1} \wedge ... \wedge e_{n}*E_{n}^{-1}$

where $$E_{n} = e_{1}\wedge ...\wedge e_{n}$$.

For non-orthogonal basis $$e^{j}$$ is not normalized and must be divided by $$E_{n}^2$$ (self.e_sq) in any relevant calculations.

g_inv: sympy.matrices.dense.MutableDenseMatrix

inverse of metric tensor, g^{ij}

r_basis_dict: Dict[sympy.core.symbol.Symbol, sympy.core.expr.Expr]

Dictionary to represent reciprocal basis vectors as expansions in terms of basis vectors.

{reciprocal basis symbol: linear combination of basis symbols, ...}

r_basis_mv: List[galgebra.mv.Mv]

List of reciprocal basis vectors in terms of basis multivectors.

er_blade(er, blade, mode='*', left=True)[source]

Product (*, ^, |, <, >) of reciprocal basis vector ‘er’ and basis blade ‘blade’ needed for application of derivatives to multivectors. left is ‘True’ means ‘er’ is multiplying ‘blade’ on the left, ‘False’ is for ‘er’ multiplying ‘blade’ on the right. Symbolically for left geometric product:

$e^{j}*(e_{i_{1}}\wedge ...\wedge e_{i_{r}})$
blade_derivation(blade: sympy.core.symbol.Symbol, ib: Union[int, sympy.core.symbol.Symbol])sympy.core.expr.Expr[source]

Calculate derivatives of basis blade ‘blade’ using derivative of basis vectors calculated by metric. ‘ib’ is the index of the coordinate the derivation is with respect to or the coordinate symbol. These are requried for the calculation of the geometric derivatives in curvilinear coordinates or for more general manifolds.

‘blade_derivation’ caches the results in a dictionary, self._dbases, so that the derivation for a given blade and coordinate is never calculated more that once.

Note that the return value is not a multivector, but linear combination of basis blade symbols.

pDiff(A: galgebra.mv.Mv, coord: Union[List, sympy.core.symbol.Symbol])galgebra.mv.Mv[source]

Compute partial derivative of multivector function ‘A’ with respect to coordinate ‘coord’.

grad_sqr(A, grad_sqr_mode, mode, left)[source]

Calculate $$(grad *_{1} grad) *_{2} A$$ or $$A *_{2} (grad *_{1} grad)$$ where grad_sqr_mode = $$*_{1}$$ = *, ^, or | and mode = $$*_{2}$$ = *, ^, or |.

connection(rbase, key_base, mode, left)[source]

Compute required multivector connections of the form (Einstein summation convention) $$e^{j}*(D_{j}e_{i_{1}...i_{r}})$$ and $$(D_{j}e_{i_{1}...i_{r}})*e^{j}$$ where $$*$$ could be *, ^, |, <, or > depending upon the mode, and $$e^{j}$$ are reciprocal basis vectors.

ReciprocalFrame(basis: Sequence[galgebra.mv.Mv], mode: str = 'norm') → Tuple[galgebra.mv.Mv, …][source]

Compute the reciprocal frame $$v^i$$ of a set of vectors $$v_i$$.

Parameters
• basis – The sequence of vectors $$v_i$$ defining the input frame.

• mode

• "norm" – indicates that the reciprocal vectors should be normalized such that their product with the input vectors is 1, $$v^i \cdot v_j = \delta_{ij}$$.

• "append" – indicates that instead of normalizing, the normalization coefficient $$E^2$$ should be appended to the returned tuple. One can divide by this coefficient to normalize the vectors. The returned vectors are such that $$v^i \cdot v_j = E^2\delta_{ij}$$.

Deprecated since version 0.5.0: Arbitrary strings are interpreted as "append", but in future will be an error

Christoffel_symbols(mode=1)

mode = 1 Christoffel symbols of the first kind mode = 2 Christoffel symbols of the second kind

connect_flg: bool

True if connection is non-zero

detg: sympy.core.expr.Expr

Determinant of $$g$$, $$\det g$$

static dot_orthogonal(V1, V2, g=None)

Returns the dot product of two vectors in an orthogonal coordinate system. V1 and V2 are lists of sympy expressions. g is a list of constants that gives the signature of the vector space to allow for non-euclidian vector spaces.

This function is only used to form the dot product of vectors in the embedding space of a vector manifold or in the case where the basis vectors are explicitly defined by vector fields in the embedding space.

A g of None is for a Euclidian embedding space.

g_adj: sympy.matrices.dense.MutableDenseMatrix

metric_symbols_list(s=None)

rows of metric tensor are separated by “,” and elements of each row separated by ” “. If the input is a single row it is assummed that the metric tensor is diagonal.

Output is a square matrix.

class galgebra.ga.Sm(_Sm__u, _Sm__coords, *, ga, norm=False, name=None, root='e', debug=False)[source]

Submanifold is a geometric algebra defined on a submanifold of a base geometric algebra defined on a manifold. The submanifold is defined by a mapping from the coordinates of the base manifold to the coordinates of the submanifold. The inputs required to define the submanifold are:

Notes

The ‘Ga’ member function ‘sm’ can be used to instantiate the submanifold via (o3d is the base manifold):

coords = u, v = symbols('u, v', real=True)
sm_example = o3d.sm([sin(u)*cos(v), sin(u)*sin(v), cos(u)], coords)

eu, ev = sm_example.mv()

Parameters
• u

The coordinate map defining the submanifold which is a list of functions of coordinates of the base manifold in terms of the coordinates of the submanifold. for example if the manifold is a unit sphere then - u = [sin(u)*cos(v), sin(u)*sin(v), cos(u)].

Alternatively, a parametric vector function of the basis vectors of the base manifold. The coefficients of the bases are functions of the coordinates (coords). In this case we would call the submanifold a “vector” manifold and additional characteristics of the manifold can be calculated since we have given an explicit embedding of the manifold in the base manifold.

• coords – The coordinate list for the submanifold, for example [u, v].

• debug – True for debug output

• root (str) – Root symbol for basis vectors

• name (str) – Name of submanifold

• norm (bool) – Normalize basis if True

• ga – Base Geometric Algebra

Christoffel_symbols(mode=1)

mode = 1 Christoffel symbols of the first kind mode = 2 Christoffel symbols of the second kind

ReciprocalFrame(basis: Sequence[galgebra.mv.Mv], mode: str = 'norm') → Tuple[galgebra.mv.Mv, …]

Compute the reciprocal frame $$v^i$$ of a set of vectors $$v_i$$.

Parameters
• basis – The sequence of vectors $$v_i$$ defining the input frame.

• mode

• "norm" – indicates that the reciprocal vectors should be normalized such that their product with the input vectors is 1, $$v^i \cdot v_j = \delta_{ij}$$.

• "append" – indicates that instead of normalizing, the normalization coefficient $$E^2$$ should be appended to the returned tuple. One can divide by this coefficient to normalize the vectors. The returned vectors are such that $$v^i \cdot v_j = E^2\delta_{ij}$$.

Deprecated since version 0.5.0: Arbitrary strings are interpreted as "append", but in future will be an error

base_expansion_dict: OrderedDict[sympy.core.symbol.Symbol, sympy.core.expr.Expr]

dictionary expanding base basis in terms of blade basis

bases: galgebra.ga.GradedTuple[sympy.core.symbol.Symbol]

Bases (non-commutative sympy symbols) by grade.

If the basis vectors are not orthogonal a second set of symbols is required in addition to the blades, given by:

$e_{i_{1}}e_{i_{2}}...e_{i_{r}}$

where $$0 < i_{1} < i_{2} < ... < i_{r}$$ and $$0 < r \le n$$ the dimension of the vector space and $$0 < i_{j} \le n$$. The total number of all symbols of this form is $$2^{n}$$. Any multivector can be represented as a linear combination of these bases.

For the case of an orthogonal set of basis vectors the bases and blades are identical, and so this attribute raises ValueError.

bases_dict(prefix: str = None) → Dict[str, sympy.core.symbol.Symbol]

returns a dictionary mapping basis element names to their MultiVector instances, optionally for specific grades

if you are lazy, you might do this to populate your namespace with the variables of a given layout.

>>> locals().update(ga.bases())

basic_mul: galgebra.ga.BaseProductFunction

The geometic product of objects in base form, $$A B$$

blade_derivation(blade: sympy.core.symbol.Symbol, ib: Union[int, sympy.core.symbol.Symbol])sympy.core.expr.Expr

Calculate derivatives of basis blade ‘blade’ using derivative of basis vectors calculated by metric. ‘ib’ is the index of the coordinate the derivation is with respect to or the coordinate symbol. These are requried for the calculation of the geometric derivatives in curvilinear coordinates or for more general manifolds.

‘blade_derivation’ caches the results in a dictionary, self._dbases, so that the derivation for a given blade and coordinate is never calculated more that once.

Note that the return value is not a multivector, but linear combination of basis blade symbols.

blade_expansion_dict: OrderedDict[sympy.core.symbol.Symbol, sympy.core.expr.Expr]

dictionary expanding blade basis in terms of base basis

static blade_reduce(lst: List[int]) → Tuple[int, Optional[List[int]]]

Reduce wedge product of basis vectors to normal order.

lst is a list of indicies of basis vectors. blade_reduce sorts the list and determines if the overall number of exchanges in the list is odd or even, returning sign changes (sgn) and sorted list. If any two indicies in list are equal (wedge product is zero) sgn = 0 and lst = None are returned.

blades: galgebra.ga.GradedTuple[sympy.core.symbol.Symbol]

The bases for the multivector (geometric) algebra are formed from all combinations of the bases of the vector space, including the empty combination which is the scalars.

Each base is represented as a non-commutative symbol of the form

$e_{i_{1}}\wedge e_{i_{2}}\wedge ...\wedge e_{i_{r}}.$

where $$0 < i_{1} < i_{2} < ... < i_{r}$$ and $$0 < r \le n$$ the dimension of the vector space and $$0 < i_{j} \le n$$. The total number of all symbols of this form is $$2^{n}$$.

These are called the blade basis for the geometric algebra and any multivector can be represented by a linears combination of these blades. The number of basis vectors that are in the symbol for the blade is call the grade of the blade.

Representing the multivector as a linear combination of blades gives a blade decomposition of the multivector.

There is a linear mapping from bases to blades and blades to bases so that one can easily convert from one representation to another.

static build(*args, **kwargs)

Static method to instantiate geometric algebra and return geometric algebra, basis vectors, and grad operator as a tuple.

static com(A, B)

Calculate commutator of multivectors $$A$$ and $$B$$. Returns $$(AB-BA)/2$$.

Additionally, commutator and anti-commutator operators are defined by

\begin{split}\begin{aligned} \texttt{A >> B} \equiv & {\displaystyle\frac{AB - BA}{2}} \\ \texttt{A << B} \equiv & {\displaystyle\frac{AB + BA}{2}}. \end{aligned}\end{split}
connect_flg: bool

True if connection is non-zero

connection(rbase, key_base, mode, left)

Compute required multivector connections of the form (Einstein summation convention) $$e^{j}*(D_{j}e_{i_{1}...i_{r}})$$ and $$(D_{j}e_{i_{1}...i_{r}})*e^{j}$$ where $$*$$ could be *, ^, |, <, or > depending upon the mode, and $$e^{j}$$ are reciprocal basis vectors.

coord_vec: sympy.core.expr.Expr

Linear combination of coordinates and basis vectors. For example in orthogonal 3D $$x*e_x+y*e_y+z*e_z$$.

detg: sympy.core.expr.Expr

Determinant of $$g$$, $$\det g$$

dop(*args, **kwargs)galgebra.mv.Dop

Shorthand to construct a Dop for this algebra

dot(A: sympy.core.expr.Expr, B: sympy.core.expr.Expr)sympy.core.expr.Expr

Inner product |, <, or >.

The dot_mode attribute determines which of these is used.

static dot_orthogonal(V1, V2, g=None)

Returns the dot product of two vectors in an orthogonal coordinate system. V1 and V2 are lists of sympy expressions. g is a list of constants that gives the signature of the vector space to allow for non-euclidian vector spaces.

This function is only used to form the dot product of vectors in the embedding space of a vector manifold or in the case where the basis vectors are explicitly defined by vector fields in the embedding space.

A g of None is for a Euclidian embedding space.

static dual_mode(mode='I+')

Sets mode of multivector dual function for all geometric algebras in users program.

If Ga.dual_mode(mode) not called the default mode is 'I+'.

mode

return value

+I

I*self

-I

-I*self

I+

self*I

I-

-self*I

+Iinv

Iinv*self

-Iinv

-Iinv*self

Iinv+

self*Iinv

Iinv-

-self*Iinv

e_sq: sympy.core.expr.Expr

If self.gsym = True then $$E_{n}^2$$ is not evaluated, but is represented as $$E_{n}^2 = (-1)^{n*(n-1)/2}\operatorname{det}(g)$$ where $$\operatorname{det}(g)$$ the determinant of the metric tensor can be general scalar function of the coordinates.

er_blade(er, blade, mode='*', left=True)

Product (*, ^, |, <, >) of reciprocal basis vector ‘er’ and basis blade ‘blade’ needed for application of derivatives to multivectors. left is ‘True’ means ‘er’ is multiplying ‘blade’ on the left, ‘False’ is for ‘er’ multiplying ‘blade’ on the right. Symbolically for left geometric product:

$e^{j}*(e_{i_{1}}\wedge ...\wedge e_{i_{r}})$
g_adj: sympy.matrices.dense.MutableDenseMatrix

g_inv: sympy.matrices.dense.MutableDenseMatrix

inverse of metric tensor, g^{ij}

grad_sqr(A, grad_sqr_mode, mode, left)

Calculate $$(grad *_{1} grad) *_{2} A$$ or $$A *_{2} (grad *_{1} grad)$$ where grad_sqr_mode = $$*_{1}$$ = *, ^, or | and mode = $$*_{2}$$ = *, ^, or |.

grade_decomposition(A: _MaybeMv) → Dict[int, _MaybeMv]

Returns dictionary with grades as keys of grades of A. For example if A is a rotor the dictionary keys would be 0 and 2. For a vector the single key would be 1. Note A can be input as a multivector or an multivector object (sympy expression). If A is a multivector the dictionary entries are multivectors. If A is a sympy expression (in this case a linear combination of non-commutative symbols) the dictionary entries are sympy expressions.

hestenes_dot: galgebra.ga.BladeProductFunction

The hestenes dot product, $$A \bullet B$$

indexes: galgebra.ga.GradedTuple[Tuple[int, ...]]

indexes_to_bases_dict: galgebra.ga.OrderedBiMap[Tuple[int, ...], sympy.core.symbol.Symbol]

Bidirectional map from index tuples (indices) to basis bases (bases)

indexes_to_blades_dict: galgebra.ga.OrderedBiMap[Tuple[int, ...], sympy.core.symbol.Symbol]

Bidirectional map from index tuples (indices) to basis blades (blades)

left_contract: galgebra.ga.BladeProductFunction

The left contraction, $$A \rfloor B$$

lt(*args, **kwargs)

Instanciate and return a linear transformation for this, ‘self’, geometric algebra.

make_grad(a: Union[galgebra.mv.Mv, Sequence[sympy.core.expr.Expr]], cmpflg: bool = False)galgebra.mv.Dop

Obtain a gradient operator with respect to the multivector a, $$\bm{\nabla}_a$$.

metric_symbols_list(s=None)

rows of metric tensor are separated by “,” and elements of each row separated by ” “. If the input is a single row it is assummed that the metric tensor is diagonal.

Output is a square matrix.

mul: galgebra.ga.BladeProductFunction

The geometric product, $$A B$$

mv(root=None, *args, **kwargs) → Union[galgebra.mv.Mv, Tuple[galgebra.mv.Mv, …]]

Instanciate and return a multivector for this, ‘self’, geometric algebra.

mv_basis: Tuple[galgebra.mv.Mv, ...]

mv.Mv instances corresponding to basis.

mv_blades: galgebra.ga.GradedTuple[galgebra.mv.Mv]

mv.Mv instances corresponding to blades.

mvr(norm: bool = True) → Tuple[galgebra.mv.Mv, …]

Returns tumple of reciprocal basis vectors. If norm=True or basis vectors are orthogonal the reciprocal basis is normalized in the sense that

${i}\cdot e^{j} = \delta_{i}^{j}.$

If the basis is not orthogonal and norm=False then

$e_{i}\cdot e^{j} = I^{2}\delta_{i}^{j}.$
pDiff(A: galgebra.mv.Mv, coord: Union[List, sympy.core.symbol.Symbol])galgebra.mv.Mv

Compute partial derivative of multivector function ‘A’ with respect to coordinate ‘coord’.

pdop(*args, **kwargs)galgebra.dop.Pdop

Shorthand to construct a Pdop

r_basis: List[sympy.core.expr.Expr]

Reciprocal basis vectors $$e^{j}$$ as linear combination of basis vector symbols.

These satisfy

$e^{j}\cdot e_{k} = \delta_{k}^{j}$

where $$\delta_{k}^{j}$$ is the kronecker delta. We use the formula from Doran and Lasenby 4.94:

$e^{j} = (-1)^{j-1}e_{1} \wedge ...e_{j-1} \wedge e_{j+1} \wedge ... \wedge e_{n}*E_{n}^{-1}$

where $$E_{n} = e_{1}\wedge ...\wedge e_{n}$$.

For non-orthogonal basis $$e^{j}$$ is not normalized and must be divided by $$E_{n}^2$$ (self.e_sq) in any relevant calculations.

r_basis_dict: Dict[sympy.core.symbol.Symbol, sympy.core.expr.Expr]

Dictionary to represent reciprocal basis vectors as expansions in terms of basis vectors.

{reciprocal basis symbol: linear combination of basis symbols, ...}

r_basis_mv: List[galgebra.mv.Mv]

List of reciprocal basis vectors in terms of basis multivectors.

reduce_basis(blst)

Repetitively applies reduce_basis_loop() to blst product representation until normal form is realized for non-orthogonal basis

If the basis vectors are represented by the non- commutative symbols $$e_1,...,e_n$$ then a grade $$r$$ base is the geometric product $$e_{i_1}e_{i_2}\cdots e_{i_r}$$ where $$i_1<i_2<\ldots<i_r$$ (normal form). Then in galgebra this base is represented by a single indexed non-commutative symbol with indexes $$[i_1,i_2,\ldots,i_r]$$. The total number of these bases in an n-dimensional vector space is $$2^n$$.

reduce_basis() takes the geometric products of basis vectors that are not in normal form (out of order) and reduces them to a sum of bases that are in normal form (in order). It does this by recursively applying the geometric algebra formula

$e_ie_j = 2(e_i \cdot e_j) - e_je_i$

where the scalar product $$e_i \cdot e_j$$ is obtained from the metric tensor of the vector space. This also allows one to calculate the geometric product of any two bases and grade of the geometric algebra, and form the multiplication table.

static reduce_basis_loop(g, blst)

blst is a list of integers $$[i_{1},\ldots,i_{r}]$$ representing the geometric product of r basis vectors $$a_{{i_1}}\cdots a_{{i_r}}$$. reduce_basis_loop() searches along the list $$[i_{1},\ldots,i_{r}]$$ untill it finds $$i_{j} = i_{j+1}$$ and in this case contracts the list, or if $$i_{j} > i_{j+1}$$ it revises the list ($$\sim i_{j}$$ means remove $$i_{j}$$ from the list)

• Case 1: If $$i_{j} = i_{j+1}$$, return $$a_{i_{j}}^2$$ and $$[i_{1},\ldots,\sim i_{j},\sim i_{j+1},\ldots,i_{r}]$$

• Case 2: If $$i_{j} > i_{j+1}$$, return $$a_{i_{j}}.a_{i_{j+1}}$$, $$[i_{1},\ldots,\sim i_{j},\sim i_{j+1},\ldots,i_{r}]$$, and $$[i_{1},\ldots,i_{j+1},i_{j},\ldots,i_{r}]$$

This is an implementation of the formula

$e_i e_j = 2(e_i \cdot e_j) - e_j e_i$

Where $$e_i$$ and $$e_j$$ are basis vectors.

remove_scalar_part(A: _MaybeMv) → Union[sympy.core.expr.Expr, int]

Return non-commutative part (sympy object) of A.obj.

right_contract: galgebra.ga.BladeProductFunction

The right contraction, $$A \lfloor B$$

scalar_product: galgebra.ga.BladeProductFunction

The scalar product, $$A * B$$

sdop(*args, **kwargs)galgebra.dop.Sdop

Shorthand to construct a Sdop

sm(*args, **kwargs)galgebra.ga.Sm

Instanciate and return a submanifold for this geometric algebra. See Sm for instantiation inputs.

split_multivector(A: _MaybeMv) → Tuple[Union[sympy.core.expr.Expr, int], Union[sympy.core.expr.Expr, int]]

Split multivector $$A$$ into commutative part $$a$$ and non-commutative part $$A'$$ so that $$A = a+A'$$

wedge: galgebra.ga.BladeProductFunction

The wedge product, $$A \wedge B$$