Galixir.Algebras.CGA3 (galixir v0.28.0)

Copy Markdown View Source

Three-dimensional Conformal Geometric Algebra (CGA).

This module implements CGA for Euclidean 3-space using the metric:

{1, 1, 1, 1, -1}

with basis:

e1, e2, e3, ep, em

The Euclidean basis vectors represent ordinary 3D coordinates. The additional conformal basis vectors are combined into the null vectors:

e_o   = (ep + em) / 2
e_inf = em - ep

Here e_o uses the letter o for origin; it is not the basis vector e0 (e-subscript zero).

Points are embedded into conformal space using:

P(x,y,z) =
  e_o
  + x*e1
  + y*e2
  + z*e3
  + 1/2(x²+y²+z²)e_inf

Lines, planes, and point-defined spheres use outer-product null-space (OPNS) representations. The center-and-radius form of sphere/2 is an inner-product null-space (IPNS) representation.

Examples

iex> p = Galixir.Algebras.CGA3.point(1, 2, 3)
iex> Galixir.Algebras.CGA3.point_coordinates(p)
{1.0, 2.0, 3.0}

Summary

Functions

Adds two multivectors component-wise.

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.

Removes coefficients whose absolute value is below eps.

Returns the coefficient of a basis blade.

Tests whether a conformal point lies on an object.

Returns the dimension of the algebra.

Computes the dual of a multivector.

Returns the conformal infinity vector.

Returns the conformal origin vector, e_o (e-subscript letter o).

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 inner product of two multivectors.

Computes the inverse of a multivector.

Checks whether a multivector contains components of the given grade only.

A guard that matches multi vectors that are all zero.

Computes the join of two CGA objects.

Computes the left contraction of two multivectors.

Creates a line through two conformal points.

Returns the maximum absolute coefficient of a multivector.

Computes the meet (intersection) of two CGA objects.

Returns the metric of the algebra.

Returns the norm of a multivector.

Normalizes a multivector.

Normalizes a conformal point to have conformal weight one.

Returns the scalar identity element.

Returns the conformal representation of the Euclidean origin.

Creates a plane through three conformal 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 the CGA3 pseudoscalar

Applies the reverse operation to a multivector.

Computes the right contraction of two multivectors.

Creates a rotor from a bivector and angle.

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.

Creates a sphere from a center point and radius.

Creates a sphere through four conformal points.

Returns the squared norm of a multivector.

Subtracts two multivectors component-wise.

Returns the multiplication table for the algebra.

Applies a motor transformation to a CGA object.

Creates a translator motor from a Euclidean vector.

Creates a translator motor.

Computes the inverse dual operation.

Creates a Euclidean vector.

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

add(arg1, arg2)

Adds two multivectors component-wise.

Examples

iex> a = new(scalar: 2)
iex> b = new(scalar: 3)
iex> add(a, b)
new(scalar: 5)

basis_name(int)

blade?(a)

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

blade_count()

Returns the number of coefficients stored by the algebra.

A dimension n algebra contains 2^n basis blades.

blade_indices()

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

blade_inverse(b)

canonical_sign(cga3)

Returns the canonical sign of a multivector.

The canonical sign is determined by the first non-zero coefficient in storage order.

Returns:

  • 1 if the first non-zero coefficient is positive
  • -1 if the first non-zero coefficient is negative
  • 0 if all coefficients are zero

Examples

iex> canonical_sign(new(e1: 2))
1

iex> canonical_sign(new(e1: -2))
-1

iex> canonical_sign(new())
0

canonical_sign_tuple(arg)

canonicalize(a)

cleanup(m, eps \\ epsilon())

Removes coefficients whose absolute value is below eps.

Use this after floating-point calculations to remove round-off noise. The default is the algebra's epsilon/0 value.

Examples

iex> new(e1: 1.0, e2: 1.0e-12) |> cleanup() |> coefficient(:e2)
0.0

iex> new(e1: 1.0e-4) |> cleanup(1.0e-3) |> coefficient(:e1)
0.0

coefficient(cga3, blade)

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

commutator(a, b)

contains?(object, point)

Tests whether a conformal point lies on an object.

Lines, planes, and point-defined spheres use their OPNS representation, so incidence is tested with the outer product. A center-and-radius sphere uses its IPNS vector representation, so incidence is tested with the scalar product.

Examples

iex> contains?(sphere(origin(), 1), point(1, 0, 0))
true

iex> contains?(line(point(0, 0, 0), point(1, 0, 0)), point(0, 1, 0))
false

dimension()

Returns the dimension of the algebra.

This is the number of basis vectors defined by the metric.

dual(cga3)

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(e23pm: 1.0) |> inspect

dual_tuple(arg)

e_inf()

Returns the conformal infinity vector.

It is the null vector e_inf = em - ep and represents the direction of points at infinity.

Examples

iex> scalar_product(e_inf(), e_inf())
0.0

e_o()

Returns the conformal origin vector, e_o (e-subscript letter o).

The origin is defined as e_o = (ep + em) / 2 and satisfies e_o · e_inf = -1.

Examples

iex> scalar_product(e_o(), e_inf())
-1.0

epsilon()

format(value, opts)

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 + 0.0ep + 0.0e1p + 0.0e2p + 0.0e12p + 0.0e3p + 0.0e13p + 0.0e23p + 0.0e123p + 0.0em + 0.0e1m + 0.0e2m + 0.0e12m + 0.0e3m + 0.0e13m + 0.0e23m + 0.0e123m + 0.0epm + 0.0e1pm + 0.0e2pm + 0.0e12pm + 0.0e3pm + 0.0e13pm + 0.0e23pm + 0.0e123pm]"

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]"

gp(lhs, rhs)

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)

grade(x)

Returns the grade of a homogeneous multivector.

The zero multivector is considered grade 0.

Returns nil for mixed-grade multivectors.

iex> grade( ...> new(scalar: 1) ...> ) 0

iex> grade( ...> new(e1: 2) ...> ) 1

iex> grade( ...> new(scalar: 1, e1: 2) ...> ) nil

iex> grade( ...> new() ...> ) nil

grade(t, g)

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)

grade?(mv, g)

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)
true

See is_grade/2

grades(arg1)

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()
...> )
[]

inner(arg1, arg2)

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)
...> )

inverse(a)

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

is_blade(mv)

(macro)

is_grade(mv, grade)

(macro)

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
end

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)
true

See grade?/2

is_zero(mv)

(macro)

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

join(a, b)

Computes the join of two CGA objects.

The join is the outer product:

join(a,b) = a  b

The operands must use compatible representations. In particular, joining conformal points creates an OPNS point pair, not a line; use line/2 to include e_inf.

Examples

iex> join(point(0, 0, 0), point(1, 0, 0)) |> grades()
[2]

left_contraction(arg1, arg2)

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)
...> )

line(a, b)

Creates a line through two conformal points.

The line is represented by:

L = a  b  e_inf

Examples

iex> l = line(point(0, 0, 0), point(1, 0, 0))
iex> contains?(l, point(2, 0, 0))
true
iex> contains?(l, point(0, 1, 0))
false

max_abs_component(cga3)

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

max_abs_component_tuple(arg)

meet(a, b)

Computes the meet (intersection) of two CGA objects.

The meet is implemented through duality:

meet(a,b) = dual(dual(a)  dual(b))

Examples

iex> x_axis = line(point(-1, 0, 0), point(1, 0, 0))
iex> yz_plane = plane(point(0, 0, 0), point(0, 1, 0), point(0, 0, 1))
iex> contains?(meet(x_axis, yz_plane), origin())
true

metric()

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.

new(basis \\ [])

norm(a)

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

normalize(a)

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

normalize_point(p)

Normalizes a conformal point to have conformal weight one.

Finite conformal points satisfy -p · e_inf = 1 after normalization.

Raises ArgumentError if the point has zero weight.

Examples

iex> p = point(2, 3, 4) |> scale(5) |> normalize_point()
iex> scalar_product(p, e_inf())
-1.0

one()

Returns the scalar identity element.

This is the multiplicative identity.

Examples

iex> gp(one(), new(e1: 2))
new(e1: 2)

origin()

Returns the conformal representation of the Euclidean origin.

Examples

iex> point_coordinates(origin())
{0.0, 0.0, 0.0}

plane(a, b, c)

Creates a plane through three conformal points.

The plane is represented by:

Π = a  b  c  e_inf

Examples

iex> p = plane(point(0, 0, 0), point(1, 0, 0), point(0, 1, 0))
iex> contains?(p, point(2, 3, 0))
true
iex> contains?(p, point(0, 0, 1))
false

point(x, y, z)

Embeds a Euclidean point into conformal space.

Uses the standard CGA point embedding:

P = e_o + x*e1 + y*e2 + z*e3
    + 1/2(x²+y²+z²)e_inf

Examples

iex> point_coordinates(point(1, 2, 3))
{1.0, 2.0, 3.0}

point?(p)

Returns whether a multivector is a finite conformal point.

A finite point is a grade-1 null vector with non-zero conformal weight.

Examples

iex> point?(point(1, 2, 3))
true

iex> point?(vector(1, 2, 3))
false

point_coordinates(p)

Extracts Euclidean coordinates from a conformal point.

Returns:

{x, y, z}

The point may be scaled by any non-zero scalar.

Raises ArgumentError for a point at infinity.

Examples

iex> point(2, 3, 4) |> scale(7) |> point_coordinates()
{2.0, 3.0, 4.0}

iex> point_coordinates(e_inf())
** (ArgumentError) cannot extract coordinates from point at infinity

pseudoscalar()

Returns the CGA3 pseudoscalar:

e1  e2  e3  ep  em

Examples

iex> grades(pseudoscalar())
[5]

reverse(cga3)

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)

reverse_tuple(arg)

right_contraction(arg1, arg2)

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)
...> )

rotor(bivector, angle)

Creates a rotor from a bivector and angle.

The angle is measured in radians. The bivector determines the rotation plane and is normalized internally.

Examples

iex> {x, y, z} = point(1, 0, 0) |> transform(rotor(new(e12: 1), :math.pi() / 2)) |> cleanup() |> point_coordinates()
iex> abs(x) < 1.0e-10 and abs(y - 1.0) < 1.0e-10 and z == 0.0
true

rotor_between_frames(source, target)

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.

scalar?(cga3)

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

scalar?(arg, eps \\ 1.0e-12)

scalar_part(cga3)

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

scalar_product(a, b)

Computes the scalar product of two multivectors.

Returns the scalar part of their geometric product.

Examples

iex> scalar_product(new(e1: 1), new(e1: 1))
1.0

scale(s, s)

sigil_G(arg, list)

(macro)

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.

sphere(center, radius)

Creates a sphere from a center point and radius.

The radius is encoded using the infinity vector term. Unlike sphere/4, this returns the sphere's IPNS vector representation.

Examples

iex> s = sphere(point(1, 2, 3), 2)
iex> contains?(s, point(3, 2, 3))
true
iex> contains?(s, point(4, 2, 3))
false

sphere(a, b, c, d)

Creates a sphere through four conformal points.

The resulting multivector represents the unique sphere containing the four points.

Examples

iex> s = sphere(point(1, 0, 0), point(-1, 0, 0), point(0, 1, 0), point(0, 0, 1))
iex> contains?(s, point(0, -1, 0))
true

squared_norm(a)

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

sub(arg1, arg2)

Subtracts two multivectors component-wise.

Examples

iex> a = new(scalar: 5)
iex> b = new(scalar: 2)
iex> sub(a, b)
new(scalar: 3)

table()

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

transform(object, motor)

Applies a motor transformation to a CGA object.

Uses the sandwich product M * X * reverse(M). Translation motors returned by translator/3 and rotation motors returned by rotor/2 can be supplied directly.

Examples

iex> point(1, 2, 3) |> transform(translator(3, -1, 2)) |> point_coordinates()
{4.0, 1.0, 5.0}

translator(v)

Creates a translator motor from a Euclidean vector.

Examples

iex> translator(vector(1, 2, 3)) == translator(1, 2, 3)
true

translator(x, y, z)

Creates a translator motor.

The motor translates objects by the Euclidean displacement:

{x,y,z}

Examples

iex> point(1, 2, 3) |> transform(translator(3, -1, 2)) |> point_coordinates()
{4.0, 1.0, 5.0}

undual(cga3)

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)

undual_tuple(arg)

vector(x, y, z)

Creates a Euclidean vector.

This creates only the Euclidean part:

x*e1 + y*e2 + z*e3

Use point/3 to create a conformal point.

Examples

iex> point?(vector(1, 2, 3))
false

wedge(arg1, arg2)

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()

wedge_all(vectors)

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.

zero()

Returns the zero multivector.

Examples

iex> zero()
~G"0"

zero?(arg1)

Checks whether all coefficients of a multivector are zero.

Examples

iex> zero?(new())
true

iex> zero?(new(e1: 1))
false