Two-dimensional Conformal Geometric Algebra (CGA).
This module implements CGA for the Euclidean plane using the signature:
{1, 1, 1, -1}with basis vectors:
e1, e2, ep, emwhere ep and em are the positive and negative null-space basis
used to construct the conformal origin and infinity vectors.
The conformal basis is defined as:
e_inf = e_m + e_p
e_o = (e_m - e_p) / 2Points are embedded using the standard conformal embedding:
P(x,y) = e_o + x*e1 + y*e2 + 1/2(x²+y²)e_infObjects are represented as multivectors and can be combined using the
operations provided by Galixir.GeometricAlgebra.
Examples
iex> p = Galixir.Algebras.CGA2.point(2, 3)
iex> Galixir.Algebras.CGA2.point_coordinates(p)
{2.0, 3.0}
Summary
Functions
Adds two multivectors component-wise.
Checks whether a multivector is a blade.
Returns the mapping between blade names and storage indices.
Returns the canonical sign of a multivector.
Creates a circle from a center point and radius.
Creates a circle from Euclidean coordinates and radius.
Returns whether a multivector is an OPNS circle.
Extracts the Euclidean parameters of an OPNS circle or line.
Classifies a geometric object and extracts its Euclidean parameters.
Removes coefficients whose absolute value is below eps.
Returns the coefficient of a basis blade.
Tests whether a point lies on a conformal object.
Returns the dimension of the algebra.
Computes the scalar product of two multivectors.
Computes the dual of a multivector.
Returns the conformal infinity vector.
Returns the conformal origin vector.
Computes the geometric product of two multivectors.
Extracts the grade-g component of a multivector.
Returns the grades present in a multivector.
Computes the inner product of two multivectors.
Computes the inverse of a multivector.
Computes the left contraction of two multivectors.
Creates a conformal line through two points.
Returns whether a multivector is an OPNS line.
Returns the Euclidean coefficients of an OPNS line.
Returns the maximum absolute coefficient of a multivector.
Computes the meet (incidence) operation between two objects.
Returns the norm of a multivector.
Normalizes a multivector.
Normalizes a conformal point so that its weight is one.
Returns the scalar identity element.
Creates a plane object from three points.
Embeds a Euclidean point into conformal space.
Returns whether a multivector is a finite conformal point.
Extracts Euclidean coordinates from a conformal point.
Returns whether a multivector has the grade of a point pair.
Returns the CGA pseudoscalar
Applies the reverse operation to a multivector.
Computes the right contraction of two multivectors.
Creates a Euclidean rotation rotor.
Computes the rotor that maps one frame to another.
Checks whether a multivector contains only a scalar component.
Returns the scalar coefficient of a multivector.
Computes the scalar product of two multivectors.
Creates a multivector from a string representation.
Returns the metric signature of the algebra.
Returns the number of coefficients stored by the algebra.
Splits a point pair into its two conformal points.
Returns the squared norm of a multivector.
Subtracts two multivectors component-wise.
Returns the multiplication table for the algebra.
Formats a multivector using standard geometric algebra notation.
Applies a motor transformation to a CGA object.
Creates a translator motor for translating by (x, y).
Computes the inverse dual operation.
Creates a Euclidean vector embedded in CGA.
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)
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 mapping between blade names and storage indices.
Blade coefficients are stored in a fixed-size 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
Creates a circle from a center point and radius.
The returned multivector represents the conformal circle object.
Examples
iex> circle(1, 2, 3) ~G"1.5e12p + 2.5e12m + 2.0e1pm - e2pm"
iex> circle?(circle(1, 2, 3)) true
iex> circle_parameters(circle(1, 2, 3)) {:circle, {{1.0, 2.0}, 3.0}}
Creates a circle from Euclidean coordinates and radius.
Returns whether a multivector is an OPNS circle.
Lines are also represented by grade-3 blades, so line?/1 should be
used to distinguish between circles and lines.
Examples
iex> circle?(circle(point(0, 0), 2))
true
Extracts the Euclidean parameters of an OPNS circle or line.
Returns either
{:circle, {{x, y}, radius}}{:line, {a, b, c}}
where the line satisfies ax + by + c = 0.
Examples
iex> circle_parameters(circle(point(1, 2), 3))
{:circle, {{1.0, 2.0}, 3.0}}
Classifies a geometric object and extracts its Euclidean parameters.
Returns one of
{:point, {x, y}}{:line, {a, b, c}}{:circle, {{x, y}, radius}}{:point_pair, kind, {p1, p2}}{:unknown, multivector}
Examples
iex> classify(point(2, 3))
{:point, {2.0, 3.0}}
iex> classify(point(2, 3))
{:point, {2.0, 3.0}}
iex> classify(point(-5, 4))
{:point, {-5.0, 4.0}}
iex> {:line, {a, b, c}} = classify(line(point(0, 0), point(0, 1)))
iex> abs(a) == 1.0 and b == 0.0 and c == 0.0
true
iex> {:line, {a, b, c}} = classify(line(point(0, 0), point(1, 0)))
iex> a == 0.0 and abs(b) == 1.0 and c == 0.0
true
iex> classify(circle(point(0, 0), 2))
{:circle, {{0.0, 0.0}, 2.0}}
iex> classify(circle(point(3, -2), 5))
{:circle, {{3.0, -2.0}, 5.0}}
iex> pp =
...> meet(
...> circle(point(0, 0), 2),
...> line(point(-3, 0), point(3, 0))
...> )
iex> {:point_pair, :real, points} = classify(pp)
iex> Enum.sort(Tuple.to_list(points))
[{-2.0, 0.0}, {2.0, 0.0}]
iex> pp =
...> meet(
...> circle(point(0, 0), 1),
...> line(point(-2, 0), point(2, 0))
...> )
iex> match?({:point_pair, :real, _}, classify(pp))
true
iex> classify(new(e1: 1))
{:unknown, new(e1: 1)}
Removes coefficients whose absolute value is below eps.
This is useful for cleaning up floating-point round-off errors after geometric computations.
Examples
iex> new(e1: 1.0, e2: 1.0e-12)
...> |> cleanup()
...> |> coefficient(:e2)
0.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
Tests whether a point lies on a conformal object.
Returns true when the incidence meet operation produces the zero
multivector.
Returns the dimension of the algebra.
This is the number of basis vectors defined by the signature.
Computes the scalar product of two multivectors.
This is the scalar part of the geometric product.
Computes the dual of a multivector.
The dual maps each basis blade to its complementary blade with the appropriate orientation sign. The complement is determined by the full pseudoscalar of the algebra.
The operation is linear and applies independently to every coefficient.
Examples
iex> dual(new(e1: 1)) |> inspect
new(e2pm: 1.0) |> inspect
Returns the conformal infinity vector.
The infinity vector represents the point at infinity in conformal space:
e_inf = e_m + e_p## Examples
iex> dot(e_inf(), e_inf()) 0.0
Returns the conformal origin vector.
The origin is defined as:
e_o = (e_m - e_p) / 2
## Examplesiex> dot(e_o(), e_inf()) -1.0
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 signature.
Examples
iex> gp(
...> new(e1: 1),
...> new(e1: 1)
...> )
new(scalar: 1)
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)
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 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.
Raises ArgumentError if the multivector is not invertible by this formula.
## Examples
iex> inverse(
...> new(e1: 2)
...> )|> inspect
new(e1: 0.5) |> inspect
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)
...> )
Creates a conformal line through two points.
The line is represented using the outer product:
L = a ∧ b ∧ e_inf
Returns whether a multivector is an OPNS line.
Examples
iex> line?(line(point(0, 0), point(1, 0)))
true
iex> line?(circle(point(0, 0), 1))
false
Returns the Euclidean coefficients of an OPNS line.
The returned tuple {a, b, c} satisfies
ax + by + c = 0Examples
iex> {a, b, c} = line_parameters(line(point(0, 0), point(0, 1))) iex> {abs(a), b, c} {1.0, 0.0, 0.0}
iex> line_parameters(line(point(0, 0), point(1, 2))) {-2.0, 1.0, 0.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
Computes the meet (incidence) operation between two objects.
Currently implemented as the outer product.
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 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
Normalizes a conformal point so that its weight is one.
Raises ArgumentError if the point has zero weight.
Examples
iex> p = point(2, 3) |> scale(5)
iex> normalized = normalize_point(p)
iex> dot(normalized, e_o())
1.0
Returns the scalar identity element.
This is the multiplicative identity:
1## Examples
iex> one() ~G"1.0"
Creates a plane object from three points.
In CGA2 this corresponds to the generalized line/circle construction obtained from three points and infinity.
Embeds a Euclidean point into conformal space.
Uses the standard CGA point representation:
P = e_o + x*e1 + y*e2 + 1/2(x²+y²)e_inf
Returns whether a multivector is a finite conformal point.
A finite point is a grade-1 null vector with non-zero weight.
Examples
iex> point?(point(1, 2))
true
iex> point?(new(e1: 1, e2: 1))
false
Extracts Euclidean coordinates from a conformal point.
Returns a tuple:
{x, y}
Returns whether a multivector has the grade of a point pair.
This function only checks the grade. Use split/1 to determine whether
the bivector represents a valid point pair.
Examples
iex> pp = meet(
...> circle(point(0, 0), 2),
...> line(point(-2, 0), point(2, 0))
...> )
iex> point_pair?(pp)
true
Returns the CGA pseudoscalar:
e1 ∧ e2 ∧ ep ∧ em
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)) |> inspect
new(e1: 2)|> inspect
iex> reverse(new(e12: 2))|> inspect
new(e12: -2)|> inspect
iex> reverse(new(scalar: 3))|> inspect
new(scalar: 3)|> inspect
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)
...> )
Creates a Euclidean rotation rotor.
Rotates by angle radians around the origin.
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.
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 scalar product of two multivectors.
The scalar product is the grade-0 component of the geometric product:
<a b>₀The result depends on the metric signature of the algebra. In particular, basis vectors with negative or null squares affect the result.
Examples
iex> scalar_product(
...> new(e1: 2),
...> new(e1: 3)
...> )
6.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)The parsed expression is converted into the same representation accepted by
new/1, so blade ordering and signs are handled by the algebra implementation.
Returns the metric signature of the algebra.
Example:
{1, 1, 1, 0}represents a projective geometric algebra with three Euclidean basis vectors and one null basis vector.
Returns the number of coefficients stored by the algebra.
A dimension n algebra contains 2^n basis blades.
Splits a point pair into its two conformal points.
Returns
{:real, p1, p2}for two real points,{:imag, p1, p2}for an imaginary point pair, or:invalidif the bivector is not a valid point pair.
Examples
iex> l = line(point(-2, 0), point(2, 0)) iex> c = circle(point(0, 0), 1) iex> {:real, p1, p2} = split(meet(c, l)) iex> Enum.sort([point_coordinates(p1), point_coordinates(p2)]) [{-1.0, 0.0}, {1.0, 0.0}]
iex> c1 = circle(point(-0.5, 0), 1) iex> c2 = circle(point(0.5, 0), 1) iex> {:real, p1, p2} = split(meet(c1, c2)) iex> [{x1, y1}, {x2, y2}] = Enum.sort([point_coordinates(p1), point_coordinates(p2)]) iex> abs(x1) < 1.0e-10 and abs(x2) < 1.0e-10 true iex> (y1 < 0) != (y2 < 0) true iex> abs(abs(y1) - :math.sqrt(0.75)) < 1.0e-10 true iex> abs(abs(y2) - :math.sqrt(0.75)) < 1.0e-10 true
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.
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
Formats a multivector using standard geometric algebra notation.
Zero coefficients are omitted. Coefficients of 1 and -1 are elided for
non-scalar basis blades.
Examples
iex> inspect(new())
"0"
iex> inspect(new(scalar: 2))
"2.0"
iex> inspect(new(e1: 1))
"e1"
iex> inspect(new(scalar: 1, e1: 2))
"1.0 + 2.0e1"
Applies a motor transformation to a CGA object.
Performs the sandwich product:
M * X * reverse(M)
Creates a translator motor for translating by (x, y).
The returned motor can be applied with transform/2.
Computes the inverse dual operation.
undual/1 reverses the blade complement operation performed by
dual/1.
For non-degenerate Euclidean algebras this corresponds to applying the dual operation twice with the appropriate pseudoscalar factor. In degenerate algebras the result depends on the implemented dual convention.
Examples
iex> undual(dual(new(e1: 2)))
new(e1: 2)
Creates a Euclidean vector embedded in CGA.
The vector is represented only by its Euclidean components:
x*e1 + y*e2It is not a conformal point. Use point/2 to embed a point.
Examples
iex> point?(vector(1, 2)) false
iex> point?(point(1, 2)) true
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.
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