Three-dimensional Euclidean geometric algebra, Cl(3, 0).
This is a classic, non-projective vector algebra: grade-1 multivectors are
ordinary Cartesian vectors. Its metric is {1, 1, 1} and its basis is
e1, e2, e3.
v = x*e1 + y*e2 + z*e3Bivectors represent oriented planes and generate rotations. The
pseudoscalar e123 dualizes vectors and bivectors, which makes the familiar
three-dimensional cross product available.
Examples
iex> cross(vector(1, 0, 0), vector(0, 1, 0)) |> coordinates()
{0.0, 0.0, 1.0}
Summary
Functions
Adds two multivectors component-wise.
Returns the unsigned angle between two non-zero vectors, in radians.
Creates an oriented bivector from its xy, yz, and zx components.
Extracts the xy, yz, and zx components of a bivector.
Returns the XY plane bivector e12.
Returns the YZ plane bivector e23.
Returns the ZX plane bivector e31.
Checks whether a multivector is a blade.
Returns the number of coefficients stored by the algebra.
Returns the mapping between blade names and storage indices.
Returns the canonical sign of a multivector.
Returns the coefficient of a basis blade.
Computes the commutator product of two multivectors.
Extracts the Cartesian coordinates of a vector.
Computes the vector cross product of two vectors.
Returns the dimension of the algebra.
Computes the Euclidean distance between two vectors interpreted as points.
Returns the pseudoscalar dual of a multivector.
Formats this multivector as geometric algebra notation.
Computes the geometric product of two multivectors.
Returns the grade of a homogeneous multivector.
Extracts the grade-g component of a multivector.
Checks whether a multivector contains components of the given grade only.
Returns the grades present in a multivector.
Computes the Hodge dual of a multivector.
Computes the inverse Hodge dual of a multivector.
Computes the inner product of two multivectors.
Computes the inverse of a multivector.
Computes the inverse of a multivector.
A guard that checks if a floating point number is below the epsilon threshold.
Checks whether a multivector contains components of the given grade only.
A guard that matches multi vectors that are all zero.
Computes the left contraction of two multivectors.
Computes the Euclidean length of a vector.
Returns the maximum absolute coefficient of a multivector.
Returns the metric of the algebra.
Negates every component of a multivector.
Returns the norm of a multivector.
Normalizes a non-zero vector to unit length.
Normalizes a multivector.
Returns the scalar identity element.
Parses a string representation into a multivector.
Projects vector v onto a non-zero vector onto.
Returns the pseudoscalar
Reflects v in the plane whose normal is non-zero vector n.
Returns the component of v perpendicular to onto.
Applies the reverse operation to a multivector.
Computes the right contraction of two multivectors.
Rotates a vector or multivector with rotor r.
Creates a rotor around non-zero vector axis by angle radians.
Computes the rotor that maps one frame to another.
Turns a Multivector with only a scalar part into an elixir number.
Checks whether a multivector contains only a scalar component.
Returns the scalar coefficient of a multivector.
Computes the Euclidean scalar product of two vectors.
Creates a multivector from a string representation.
Computes the squared Euclidean length of a vector.
Returns the squared norm of a multivector.
Subtracts two multivectors component-wise.
Returns the multiplication table for the algebra.
Turns a Multivector with only a scalar part into an elixir number.
Returns the inverse pseudoscalar dual of a multivector.
Creates the Cartesian vector x*e1 + y*e2 + z*e3.
Checks whether a multivector is a vector (a pure grade-1 multivector).
Computes the outer product (wedge product) of two multivectors.
Computes the outer product of a list of multivectors.
Returns the zero multivector.
Checks whether all coefficients of a multivector are zero.
Functions
Adds two multivectors component-wise.
Examples
iex> a = new(scalar: 2)
iex> b = new(scalar: 3)
iex> add(a, b)
new(scalar: 5)
Returns the unsigned angle between two non-zero vectors, in radians.
Examples
iex> angle(vector(1, 0, 0), vector(0, 1, 0))
:math.pi() / 2
Creates an oriented bivector from its xy, yz, and zx components.
B = xy*e12 + yz*e23 + zx*e31Examples
iex> bivector(1, 2, 3)
new(e12: 1, e23: 2, e31: 3)
Extracts the xy, yz, and zx components of a bivector.
Examples
iex> bivector_coordinates(bivector(1, 2, 3))
{1.0, 2.0, 3.0}
Returns the XY plane bivector e12.
Examples
iex> bivector_xy()
new(e12: 1)
Returns the YZ plane bivector e23.
Examples
iex> bivector_yz()
new(e23: 1)
Returns the ZX plane bivector e31.
Examples
iex> bivector_zx()
new(e31: 1)
Checks whether a multivector is a blade.
A blade is a multivector containing components from at most one grade.
Scalars are considered blades.
Examples
iex> blade?(new(e1: 2))
true
iex> blade?(new(e12: 1))
true
iex> blade?(new(e1: 1, e2: 1))
true
iex> blade?(new(scalar: 2, e1: 2))
false
iex> blade?(new(e2: 2, e12: 2))
false
Returns the number of coefficients stored by the algebra.
A dimension n algebra contains 2^n basis blades.
Returns the mapping between blade names and storage indices.
Blade coefficients are stored in a fixed-blade_count tuple. This map translates canonical blade names into their corresponding tuple index.
Example
iex> blade_indices()[:e1]
1
Returns the canonical sign of a multivector.
The canonical sign is determined by the first non-zero coefficient in storage order.
Returns:
1if the first non-zero coefficient is positive-1if the first non-zero coefficient is negative0if all coefficients are zero
Examples
iex> canonical_sign(new(e1: 2))
1
iex> canonical_sign(new(e1: -2))
-1
iex> canonical_sign(new())
0
Returns the coefficient of a basis blade.
The requested blade can be given in canonical form or as any registered blade alias. Aliases are automatically converted to the canonical blade and the appropriate sign is applied.
Examples
iex> coefficient(
...> new(e1: 3),
...> :e1
...> )
3.0
Computes the commutator product of two multivectors.
The commutator is defined as half the difference between the geometric products in opposite orders:
[a, b] = (a * b - b * a) / 2This measures the non-commutativity of the geometric product.
Examples
iex> commutator(new(e1: 1), new(e2: 1))
new(e12: 1)
iex> commutator(new(e2: 1), new(e1: 1))
new(e12: -1)
iex> commutator(new(e1: 1), new(e1: 1))
new()
iex> commutator(new(e1: 1), new(scalar: 2))
new()
Extracts the Cartesian coordinates of a vector.
Examples
iex> coordinates(vector(1, 2, -3))
{1.0, 2.0, -3.0}
Computes the vector cross product of two vectors.
It is the negative pseudoscalar dual of the outer product:
a × b = -(a ∧ b) * e123Examples
iex> cross(vector(1, 0, 0), vector(0, 1, 0))
new(e3: 1)
Returns the dimension of the algebra.
This is the number of basis vectors defined by the metric.
Computes the Euclidean distance between two vectors interpreted as points.
Examples
iex> distance(vector(1, 2, 3), vector(4, 6, 3))
5.0
Returns the pseudoscalar dual of a multivector.
The dual is computed by multiplying the multivector by the inverse of the algebra's pseudoscalar.
This operation is only defined for non-degenerate algebras, where the pseudoscalar is invertible.
See hodge_dual/1 and hodge_undual/1 for the metric-independent Hodge dual.
Examples
iex> p = new(scalar: 2.0)
iex> undual(dual(p)) == p
true
iex> p = new(scalar: 2.0)
iex> dual(undual(p)) == p
true
Formats this multivector as geometric algebra notation.
This is the same representation used by Inspect.
Examples
iex> inspect(new())
"~G[0.0]"
iex> inspect(new(), custom_options: [all_blades: true])
"~G[0.0 + 0.0e1 + 0.0e2 + 0.0e12 + 0.0e3 + 0.0e13 + 0.0e23 + 0.0e123]"
iex> inspect(new(scalar: -2))
"~G[-2.0]"
iex> inspect(new(scalar: 2))
"~G[2.0]"
iex> inspect(new(scalar: -2))
"~G[-2.0]"
iex> inspect(new(e1: 1))
"~G[1.0e1]"
iex> inspect(new(scalar: 1, e1: 2))
"~G[1.0 + 2.0e1]"
iex> inspect(new(scalar: 1, e1: -2))
"~G[1.0 - 2.0e1]"
iex> inspect(new(scalar: -1, e1: -2))
"~G[-1.0 - 2.0e1]"
iex> inspect(new(scalar: -1, e1: 2))
"~G[-1.0 + 2.0e1]"
iex> inspect(new(e1: 2))
"~G[2.0e1]"
iex> inspect(new(e1: -2))
"~G[-2.0e1]"
iex> inspect(~G[ε + εe1])
"~G[ε + εe1]"
iex> inspect(~G[-ε - εe1])
"~G[-ε - εe1]"
Computes the geometric product of two multivectors.
The geometric product is the fundamental multiplication operation of geometric algebra. It combines the outer product and metric-dependent inner product into a single associative operation.
The result depends on the algebra's metric.
Examples
iex> gp(
...> new(e1: 1),
...> new(e1: 1)
...> )
new(scalar: 1)
Returns the grade of a homogeneous multivector.
The zero multivector is considered grade 0.
Returns nil for mixed-grade multivectors.
Examples
iex> grade(
...> new(scalar: 1)
...> )
0
iex> grade(
...> new(e1: 2)
...> )
1
iex> grade(
...> new(scalar: 1, e1: 2)
...> )
nil
iex> grade(
...> new()
...> )
nil
Extracts the grade-g component of a multivector.
All coefficients whose basis blades are not of grade g are set to zero.
Raises ArgumentError if g is outside the range 0..dimension().
Examples
iex> grade(
...> new(scalar: 1, e1: 2),
...> 1
...> )
new(e1: 2)
iex> grade(
...> new(scalar: 1, e1: 2),
...> 0
...> )
new(scalar: 1)
Checks whether a multivector contains components of the given grade only.
A multivector is considered to have a grade if all non-zero components belong to that grade. The zero multivector is considered to have grade 0.
Examples
iex> grade?(new(e1: 1), 1)
true
iex> grade?(new(scalar: 1, e1: 2), 2)
false
iex> grade?(new(scalar: 1), 0)
true
iex> grade?(new(), 0)
trueSee is_grade/2
Returns the grades present in a multivector.
The returned list contains every grade with at least one non-zero coefficient, ordered from lowest to highest.
Examples
iex> grades(
...> new(scalar: 1)
...> )
[0]
iex> grades(
...> new(e1: 2)
...> )
[1]
iex> grades(
...> new(scalar: 1, e1: 2)
...> )
[0, 1]
iex> grades(
...> new()
...> )
[]
Computes the Hodge dual of a multivector.
The Hodge dual maps each basis blade to its complementary blade with the appropriate orientation sign. The complementary blade is determined by the pseudoscalar of the algebra.
The operation is linear and is applied independently to each basis blade and its coefficient.
Unlike the pseudoscalar dual, the Hodge dual does not require the pseudoscalar to be invertible and is therefore also defined for degenerate algebras.
The operations are inverses:
hodge_undual(hodge_dual(a)) == a
hodge_dual(hodge_undual(a)) == aSee hodge_undual/1 for the inverse operation.
See dual/1 for the pseudoscalar-based dual.
Examples
iex> hodge_dual(new(e1: 1)) |> inspect
new(e23: 1.0) |> inspect
Computes the inverse Hodge dual of a multivector.
hodge_undual/1 reverses the blade-complement operation performed by
hodge_dual/1, mapping each basis blade back to its complementary blade
with the appropriate orientation sign.
The operation is linear and is applied independently to each basis blade and its coefficient.
Unlike the pseudoscalar dual, the Hodge dual and its inverse are defined for degenerate algebras as well.
The operations are inverses:
hodge_undual(hodge_dual(a)) == a
hodge_dual(hodge_undual(a)) == aSee hodge_dual/1 for the inverse operation.
See dual/1 for the pseudoscalar-based dual.
Examples
iex> hodge_undual(hodge_dual(new(e1: 2)))
new(e1: 2)
Computes the inner product of two multivectors.
The operation is generated from the geometric product and retains only terms satisfying the grade selection rule.
Example
iex> inner(
...> new(e1: 2),
...> new(e1: 3)
...> )
Computes the inverse of a multivector.
The inverse is computed using the reverse:
inverse(a) = reverse(a) / scalar_part(a * reverse(a))
This formula is valid when a * reverse(a) is a non-zero scalar.
Returns either {:ok, result} if inverse can be compute or :error otherwise
Examples
iex> inverse(
...> new(e1: 2)
...> )
{:ok, new(e1: 0.5) }
iex> inverse(
...> new(e1: 2)
...> )
{:ok, new(e1: 0.5)}
iex> inverse(
...> new(scalar: 0.0)
...> )
:error
Computes the inverse of a multivector.
The inverse is computed using the reverse:
inverse!(a) = reverse(a) / scalar_part(a * reverse(a))
This formula is valid when a * reverse(a) is a non-zero scalar.
Raises ArgumentError if the multivector is not invertible by this formula.
Examples
iex> inverse!(
...> new(e1: 2)
...> )
new(e1: 0.5)
iex> inverse!(
...> new(e1: 2)
...> )
new(e1: 0.5)
iex> assert_raise ArgumentError, fn ->
...> inverse!(new(scalar: 0))
...> end
A guard that checks if a floating point number is below the epsilon threshold.
Can be used in function guards:
def foo(x) when is_near_zero(x), do: x
Checks whether a multivector contains components of the given grade only.
A multivector is considered to have a grade if all non-zero components belong to that grade. The zero multivector is considered to have grade 0.
The is_grade(vector, grade) guard can be used in function guards:
def foo(mv) when is_grade(mv, 1) do
mv
endExamples
iex> grade?(new(e1: 1), 1)
true
iex> grade?(new(scalar: 1, e1: 2), 2)
false
iex> grade?(new(scalar: 1), 0)
true
iex> grade?(new(), 0)
trueSee grade?/2
A guard that matches multi vectors that are all zero.
Can be used in function guards:
def foo(x) when is_zero(x), do: x
Computes the left contraction of two multivectors.
The operation is generated from the geometric product and retains only terms satisfying the grade selection rule.
Example
iex> left_contraction(
...> new(e1: 2),
...> new(e1: 3)
...> )
Computes the Euclidean length of a vector.
Examples
iex> len(vector(2, 3, 6))
7.0
Returns the maximum absolute coefficient of a multivector.
Accepts either a multivector struct or the internal coefficient tuple.
Example
iex> max_abs_component(new(e1: 2, scalar: 5))
5.0
iex> max_abs_component(new(e1: 5, scalar: 2))
5.0
Returns the metric of the algebra.
Example:
{1, 1, 1, 0}represents a projective geometric algebra with three Euclidean basis vectors and one null basis vector.
Negates every component of a multivector.
Examples
iex> negate(vector(1, -2, 3))
new(e1: -1, e2: 2, e3: -3)
Returns the norm of a multivector.
The norm is the square root of the absolute squared norm.
Example
iex> a = new(scalar: 3)
iex> norm(a)
3.0
Normalizes a non-zero vector to unit length.
Raises ArgumentError for the zero vector.
Examples
iex> normal(vector(2, 0, 0)) |> coordinates()
{1.0, 0.0, 0.0}
Normalizes a multivector.
The result has unit norm while preserving the direction of the multivector.
Raises ArgumentError when attempting to normalize a null
multivector.
Example
iex> a = new(scalar: 2)
iex> norm(normalize!(a))
1.0
iex> normalize!(new())
** (ArgumentError) cannot normalize given null multivector ...
iex> normalize!(new(scalar: epsilon() / 2.0))
** (ArgumentError) cannot normalize given null multivector ...
Returns the scalar identity element.
This is the multiplicative identity.
Examples
iex> one()
~G"1.0"
Parses a string representation into a multivector.
The string may contain scalar coefficients and basis blades combined
using + and - operators.
Examples:
iex> parse("1 + e1")
new(scalar: 1, e1: 1)
iex> parse("foo")
** (ArgumentError) expected number ...
Projects vector v onto a non-zero vector onto.
Examples
iex> project(vector(3, 4, 5), vector(1, 0, 0)) |> coordinates()
{3.0, 0.0, 0.0}
Returns the pseudoscalar:
e1 ∧ e2 ∧ e3
iex> grades(pseudoscalar())
[3]
Reflects v in the plane whose normal is non-zero vector n.
Examples
iex> reflect(vector(1, 2, 3), vector(0, 0, 1)) |> coordinates()
{1.0, 2.0, -3.0}
Returns the component of v perpendicular to onto.
Examples
iex> reject(vector(3, 4, 5), vector(1, 0, 0)) |> coordinates()
{0.0, 4.0, 5.0}
Applies the reverse operation to a multivector.
Reverse (also called reversion) changes the sign of basis blades according to their grade:
grade 0: +
grade 1: +
grade 2: -
grade 3: -
grade 4: +
...For a blade with grade r, the sign is:
(-1)^(r(r-1)/2)Examples
iex> reverse(new(e1: 2))
new(e1: 2)
iex> reverse(new(e12: 2))
new(e12: -2)
iex> reverse(new(scalar: 3))
new(scalar: 3)
Computes the right contraction of two multivectors.
The operation is generated from the geometric product and retains only terms satisfying the grade selection rule.
Example
iex> right_contraction(
...> new(e1: 2),
...> new(e1: 3)
...> )
Rotates a vector or multivector with rotor r.
Applies the sandwich product R*v*reverse(R).
Examples
iex> rotate(rotor(vector(0, 0, 1), :math.pi()), vector(1, 0, 0)) |> coordinates() |> Tuple.to_list() |> Enum.map(&Float.round(&1, 12))
[-1.0, 0.0, 0.0]
Creates a rotor around non-zero vector axis by angle radians.
Positive angles follow the right-hand rule around the axis.
Examples
iex> rotate(rotor(vector(0, 0, 1), :math.pi() / 2), vector(1, 0, 0)) |> coordinates() |> Tuple.to_list() |> Enum.map(&Float.round(&1, 12))
[0.0, 1.0, 0.0]
Computes the rotor that maps one frame to another.
The function constructs blades from the source and target frames and computes the transformation rotor:
R = normalize(1 + T * S⁻¹)
where S is the source frame blade and T is the target frame blade.
The resulting rotor can be applied to multivectors to rotate the source frame into the target frame.
Turns a Multivector with only a scalar part into an elixir number.
iex> ~G[3.0] |> scalar()
{:ok, 3.0}
iex> ~G[3.0 + e1] |> scalar()
:error
Checks whether a multivector contains only a scalar component.
Components with an absolute value smaller than eps are considered
zero.
Examples
iex> scalar?(new(scalar: 3))
true
iex> scalar?(new(e1: 3))
false
iex> scalar?(new())
true
Returns the scalar coefficient of a multivector.
This is equivalent to retrieving the coefficient of the scalar blade.
Examples
iex> scalar_part(new(scalar: 5.0, e1: 2.0))
5.0
Computes the Euclidean scalar product of two vectors.
Examples
iex> scalar_product(vector(1, 2, 3), vector(4, 5, 6))
32.0
Creates a multivector from a string representation.
The ~G sigil provides a convenient syntax for constructing multivectors
using basis blades and coefficients.
Examples:
iex> ~G"e1 + e2"
new(e1: 1, e2: 1)
iex> ~G"2e1 - 0.5e12"
new(e1: 2, e12: -0.5)
iex> ~G"e12"
new(e12: 1)
iex> ~G"3"
new(scalar: 3)
iex> ~G[ε + εe1]
new(scalar: epsilon(), e1: epsilon())
iex> ~G[-ε - εe1]
new(scalar: -epsilon(), e1: -epsilon())The parsed expression is converted into the same representation accepted by
new/1, so blade ordering and signs are handled by the algebra implementation.
Computes the squared Euclidean length of a vector.
Examples
iex> squared_length(vector(2, 3, 6))
49.0
Returns the squared norm of a multivector.
The squared norm is computed as:
scalar_part(a * reverse(a))The result may be negative for algebras with indefinite metrics.
This is also called the Spinor Magnitude.
Example
iex> a = new(scalar: 3)
iex> squared_norm(a)
9.0
Subtracts two multivectors component-wise.
Examples
iex> a = new(scalar: 5)
iex> b = new(scalar: 2)
iex> sub(a, b)
new(scalar: 3)
Returns the multiplication table for the algebra.
The table contains precomputed geometric products between basis blades.
Each entry maps {left_blade, right_blade} to {coefficient, result_blade}.
The blades are represented internally as bitmasks.
Example
iex> table() |> Map.has_key?({1, 1})
true
Turns a Multivector with only a scalar part into an elixir number.
Raises if the given Multivector is not grade 0.
iex> ~G[3.0] |> to_scalar()
3.0
iex> ~G[3.0 + e1] |> to_scalar()
** (ArgumentError) cannot convert multivector to scalar: only grade-0 multivectors can be converted to a scalar, got ...
Returns the inverse pseudoscalar dual of a multivector.
This multiplies the multivector by the algebra's pseudoscalar
and reverses the operation performed by dual/1.
See hodge_dual/1 and hodge_undual/1 for the metric-independent Hodge dual.
Examples
iex> p = new(scalar: 3.0)
iex> undual(dual(p)) == p
true
iex> p = new(scalar: 3.0)
iex> dual(undual(p)) == p
true
Creates the Cartesian vector x*e1 + y*e2 + z*e3.
Examples
iex> vector(1, 2, -3)
new(e1: 1, e2: 2, e3: -3)
Checks whether a multivector is a vector (a pure grade-1 multivector).
Examples
iex> vector?(vector(1, 2, 3))
true
iex> vector?(pseudoscalar())
false
Computes the outer product (wedge product) of two multivectors.
The wedge product combines blades by joining their basis vectors. It is antisymmetric:
a ∧ b = -(b ∧ a)and vanishes when the operands share a basis vector.
Examples
iex> wedge(
...> new(e1: 1),
...> new(e2: 1)
...> )
new(e12: 1)
iex> wedge(
...> new(e2: 1),
...> new(e1: 1)
...> )
new(e12: -1)
iex> wedge(
...> new(e1: 1),
...> new(e1: 1)
...> )
new()
Computes the outer product of a list of multivectors.
The vectors are combined from left to right using the wedge product.
The result is a blade representing the subspace spanned by all input multivectors.
Examples
iex> wedge_all([])
new(scalar: 1)
iex> wedge_all([new(e1: 1)])
new(e1: 1)
iex> wedge_all([new(e1: 1), new(e1: 1)])
new()
iex> wedge_all([new(e1: 1), new(e2: 1)])
new(e12: 1)
iex> wedge_all([new(e2: 1), new(e1: 1)])
new(e12: -1)
Returns the zero multivector.
Examples
iex> zero()
~G"0"
Checks whether all coefficients of a multivector are zero.
Examples
iex> zero?(new())
true
iex> zero?(new(e1: 1))
false