Galixir.Algebras.PGA3 (galixir v0.15.0)

Copy Markdown View Source

Three-dimensional Projective Geometric Algebra (PGA).

This module implements Euclidean 3D projective geometry using:

Cl(3,0,1)

with signature:

{1,1,1,0}

and basis:

e1, e2, e3, e0

where e0 is the ideal (infinite) basis vector.

PGA represents geometric objects as homogeneous multivectors:

  • Points are grade-3 trivectors
  • Lines are grade-2 bivectors
  • Planes are grade-1 vectors

Finite points are represented as:

P = e123 + x*e032 + y*e013 + z*e021

where the coefficient of e123 is the homogeneous scale.

Ideal points have zero e123 coefficient and represent directions.

Motors

Euclidean transformations are represented by motors. This module supports:

  • translations
  • rotations around lines
  • motor transformations
  • interpolation through logarithm/exponential

Examples

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

Summary

Functions

Adds two multivectors component-wise.

Computes the motor aligning corresponding point sets.

Checks whether a multivector is a blade.

Returns the mapping between blade names and storage indices.

Returns the canonical sign of a multivector.

Returns the coefficient of a basis blade.

Checks whether two homogeneous objects represent the same entity.

Tests whether an object contains another object.

Returns the dimension of the algebra.

Returns the vector from point a to point b.

Extracts a Euclidean direction vector from a line.

Computes the Euclidean distance between two points.

Computes the scalar product.

Computes the dual of a multivector.

Checks whether a point is finite.

Computes the geometric product of two multivectors.

Extracts the grade-g component of a multivector.

Returns the grades present in a multivector.

Returns the homogeneous grade of a multivector.

Checks whether an object lies entirely at infinity.

Returns the ideal point representing a line direction.

Creates the ideal point representing a direction.

Checks whether a point is ideal.

Tests whether two objects are incident.

Computes the inner product of two multivectors.

Checks whether two objects intersect in a finite object.

Computes the inverse of a multivector.

Computes the join of two objects.

Creates the line through two points.

Returns the maximum absolute coefficient of a multivector.

Computes the meet of two objects.

Computes the exponential of a bivector motor logarithm.

Computes the logarithm of a motor.

Raises a motor to a scalar power.

Negates a multivector.

Returns the norm of a multivector.

Normalizes a multivector.

Normalizes a line motor axis.

Returns the scalar identity element.

Returns the Euclidean origin point.

Checks whether two objects are parallel.

Creates a plane from coefficients.

Creates a plane from a normal vector and a point.

Extracts the normal vector from a plane.

Creates a finite point.

Returns Cartesian coordinates of a finite point.

Applies the reverse operation to a multivector.

Creates a rotation motor around an axis line.

Checks whether a multivector contains only a scalar component.

Returns the scalar coefficient of a multivector.

Computes the scalar product of two multivectors.

Returns the metric signature of the algebra.

Returns the number of coefficients stored by the algebra.

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 an object.

Creates a translation motor from a vector.

Creates a translation motor from coordinates.

Computes the inverse dual operation.

Returns a normalized line direction vector.

Returns the normalized plane normal.

Creates a Euclidean direction vector.

Computes the outer product (wedge product) of two 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 = Galixir.Algebras.PGA3.new(scalar: 2)
iex> b = Galixir.Algebras.PGA3.new(scalar: 3)
iex> Galixir.Algebras.PGA3.add(a, b)
Galixir.Algebras.PGA3.new(scalar: 5)

align(ps, qs)

Computes the motor aligning corresponding point sets.

Uses an iterative PGA look-at style construction.

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> Galixir.Algebras.PGA3.blade?(Galixir.Algebras.PGA3.new(e1: 2))
true

iex> Galixir.Algebras.PGA3.blade?(Galixir.Algebras.PGA3.new(e12: 1))
true

iex> Galixir.Algebras.PGA3.blade?(Galixir.Algebras.PGA3.new(e1: 1, e2: 1))
true

iex> Galixir.Algebras.PGA3.blade?(Galixir.Algebras.PGA3.new(scalar: 2, e1: 2))
false

iex> Galixir.Algebras.PGA3.blade?(Galixir.Algebras.PGA3.new(e2: 2, e12: 2))
false

blade_indices()

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> Galixir.Algebras.PGA3.blade_indices()[:e1]
1

blade_inverse(b)

canonical_sign(arg1)

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> Elixir.Galixir.Algebras.PGA3.canonical_sign(Elixir.Galixir.Algebras.PGA3.new(e1: 2))
1

iex> Elixir.Galixir.Algebras.PGA3.canonical_sign(Elixir.Galixir.Algebras.PGA3.new(e1: -2))
-1

iex> Elixir.Galixir.Algebras.PGA3.canonical_sign(Elixir.Galixir.Algebras.PGA3.new())
0

canonicalize(a)

coefficient(pga3, 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> Elixir.Galixir.Algebras.PGA3.coefficient( ...> Elixir.Galixir.Algebras.PGA3.new(e1: 3), ...> :e1 ...> ) 3.0

coincident?(a, b)

Checks whether two homogeneous objects represent the same entity.

commutator(a, b)

contains?(container, object)

Tests whether an object contains another object.

dimension()

Returns the dimension of the algebra.

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

direction_between_points(a, b)

Returns the vector from point a to point b.

direction_vector(line)

Extracts a Euclidean direction vector from a line.

distance(a, b)

Computes the Euclidean distance between two points.

dot(a, b)

Computes the scalar product.

dual(arg1)

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> Galixir.Algebras.PGA3.dual(Galixir.Algebras.PGA3.new(e1: 1)) |> inspect Galixir.Algebras.PGA3.new(e230: 1.0) |> inspect

finite_point?(p)

Checks whether a point is finite.

A finite point has a non-zero homogeneous component.

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

Examples

iex> Galixir.Algebras.PGA3.gp(
...>   Galixir.Algebras.PGA3.new(e1: 1),
...>   Galixir.Algebras.PGA3.new(e1: 1)
...> )
Galixir.Algebras.PGA3.new(scalar: 1)

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> Galixir.Algebras.PGA3.grade(
...>   Galixir.Algebras.PGA3.new(scalar: 1, e1: 2),
...>   1
...> )
Galixir.Algebras.PGA3.new(e1: 2)

iex> Galixir.Algebras.PGA3.grade(
...>   Galixir.Algebras.PGA3.new(scalar: 1, e1: 2),
...>   0
...> )
Galixir.Algebras.PGA3.new(scalar: 1)

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> Galixir.Algebras.PGA3.grades(
...>   Galixir.Algebras.PGA3.new(scalar: 1)
...> )
[0]

iex> Galixir.Algebras.PGA3.grades(
...>   Galixir.Algebras.PGA3.new(e1: 2)
...> )
[1]

iex> Galixir.Algebras.PGA3.grades(
...>   Galixir.Algebras.PGA3.new(scalar: 1, e1: 2)
...> )
[0, 1]

iex> Galixir.Algebras.PGA3.grades(
...>   Galixir.Algebras.PGA3.new()
...> )
[]

homogeneous_grade(x)

Returns the homogeneous grade of a multivector.

Returns nil for mixed-grade multivectors.

ideal?(x)

Checks whether an object lies entirely at infinity.

ideal_direction(line)

Returns the ideal point representing a line direction.

ideal_point(x, y, z)

Creates the ideal point representing a direction.

ideal_point?(p)

Checks whether a point is ideal.

An ideal point has no finite homogeneous component.

incident?(a, b)

Tests whether two objects are incident.

inner(arg1, arg2)

Computes the inner product of two multivectors.

The inner product retains only those terms of the geometric product whose grade is the absolute difference of the operand grades.

For homogeneous blades A and B:

grade(inner(A, B)) = |grade(A) - grade(B)|

The exact result depends on the metric signature of the algebra.

Examples

iex> Galixir.Algebras.PGA3.inner(
...>   Galixir.Algebras.PGA3.new(e1: 2),
...>   Galixir.Algebras.PGA3.new(e1: 3)
...> )
Galixir.Algebras.PGA3.new(scalar: 6)

intersects?(a, b)

Checks whether two objects intersect in a finite object.

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> Galixir.Algebras.PGA3.inverse(
    ...>   Galixir.Algebras.PGA3.new(e1: 2)
    ...> )|> inspect
    Galixir.Algebras.PGA3.new(e1: 0.5) |> inspect

join(a, b)

Computes the join of two objects.

The join produces the smallest object containing both inputs.

Examples:

point  point -> line
line  point  -> plane

line(a, b)

Creates the line through two points.

max_abs_component(arg1)

Returns the maximum absolute coefficient of a multivector.

Accepts either a multivector struct or the internal coefficient tuple.

Example

iex> Elixir.Galixir.Algebras.PGA3.max_abs_component(Elixir.Galixir.Algebras.PGA3.new(e1: 2, scalar: 5))
5.0

iex> Elixir.Galixir.Algebras.PGA3.max_abs_component(Elixir.Galixir.Algebras.PGA3.new(e1: 5, scalar: 2))
5.0

meet(a, b)

Computes the meet of two objects.

The meet is the outer product.

Examples:

plane  plane -> line
line  line   -> point

motor_exp(bv)

Computes the exponential of a bivector motor logarithm.

motor_log(mot)

Computes the logarithm of a motor.

motor_pow(motor, t)

Raises a motor to a scalar power.

Useful for motor interpolation.

negate(x)

Negates a multivector.

new(basis \\ [])

norm(a)

Returns the norm of a multivector.

The norm is the square root of the absolute squared norm.

Example

iex> a = Galixir.Algebras.PGA3.new(scalar: 3)
iex> Galixir.Algebras.PGA3.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 = Galixir.Algebras.PGA3.new(scalar: 2)
iex> Galixir.Algebras.PGA3.norm(Galixir.Algebras.PGA3.normalize(a))
1.0

normalize_line(line)

Normalizes a line motor axis.

one()

Returns the scalar identity element.

origin()

Returns the Euclidean origin point.

parallel?(a, b)

Checks whether two objects are parallel.

This is true when their intersection is an ideal object.

plane(a, b, c, d)

Creates a plane from coefficients.

Represents:

ax + by + cz + d = 0

plane_from_normal_point(n, p)

Creates a plane from a normal vector and a point.

plane_normal(p)

Extracts the normal vector from a plane.

point(x, y, z, w \\ 1)

Creates a finite point.

The homogeneous representation is:

P = e123 + x*e032 + y*e013 + z*e021

point_coordinates(p)

Returns Cartesian coordinates of a finite point.

reverse(arg1)

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> Galixir.Algebras.PGA3.reverse(Galixir.Algebras.PGA3.new(e1: 2)) |> inspect
Galixir.Algebras.PGA3.new(e1: 2)|> inspect

iex> Galixir.Algebras.PGA3.reverse(Galixir.Algebras.PGA3.new(e12: 2))|> inspect
Galixir.Algebras.PGA3.new(e12: -2)|> inspect

iex> Galixir.Algebras.PGA3.reverse(Galixir.Algebras.PGA3.new(scalar: 3))|> inspect
Galixir.Algebras.PGA3.new(scalar: 3)|> inspect

rotor(line_axis, angle)

Creates a rotation motor around an axis line.

The angle is specified in radians.

rotor_between_frames(source, target)

scalar?(pga3)

Checks whether a multivector contains only a scalar component.

Components with an absolute value smaller than eps are considered zero.

Examples

iex> Galixir.Algebras.PGA3.scalar?(Galixir.Algebras.PGA3.new(scalar: 3))
true

iex> Galixir.Algebras.PGA3.scalar?(Galixir.Algebras.PGA3.new(e1: 3))
false

iex> Galixir.Algebras.PGA3.scalar?(Galixir.Algebras.PGA3.new())
true

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

scalar_part(pga3)

Returns the scalar coefficient of a multivector.

This is equivalent to retrieving the coefficient of the scalar blade.

Examples

iex> Elixir.Galixir.Algebras.PGA3.scalar_part(Elixir.Galixir.Algebras.PGA3.new(scalar: 5.0, e1: 2.0))
5.0

scalar_product(arg1, arg2)

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> Galixir.Algebras.PGA3.scalar_product(
...>   Galixir.Algebras.PGA3.new(e1: 2),
...>   Galixir.Algebras.PGA3.new(e1: 3)
...> )
6.0

scale(s, s)

signature()

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.

size()

Returns the number of coefficients stored by the algebra.

A dimension n algebra contains 2^n basis blades.

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 = Galixir.Algebras.PGA3.new(scalar: 3)
iex> Galixir.Algebras.PGA3.squared_norm(a)
9.0

sub(arg1, arg2)

Subtracts two multivectors component-wise.

Examples

iex> a = Galixir.Algebras.PGA3.new(scalar: 5)
iex> b = Galixir.Algebras.PGA3.new(scalar: 2)
iex> Galixir.Algebras.PGA3.sub(a, b)
Galixir.Algebras.PGA3.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> Galixir.Algebras.PGA3.table() |> Map.has_key?({1, 1})
true

to_string(v)

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(Galixir.Algebras.PGA3.new())
"0"

iex> inspect(Galixir.Algebras.PGA3.new(scalar: 2))
"2.0"

iex> inspect(Galixir.Algebras.PGA3.new(e1: 1))
"e1"

iex> inspect(Galixir.Algebras.PGA3.new(scalar: 1, e1: 2))
"1.0 + 2.0e1"

transform(motor, object)

Applies a motor transformation to an object.

translator(v)

Creates a translation motor from a vector.

translator(x, y, z)

Creates a translation motor from coordinates.

undual(arg1)

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> Galixir.Algebras.PGA3.undual(Galixir.Algebras.PGA3.dual(Galixir.Algebras.PGA3.new(e1: 2)))
Galixir.Algebras.PGA3.new(e1: 2)

unit_direction_vector(line)

Returns a normalized line direction vector.

unit_plane_normal(p)

Returns the normalized plane normal.

vector(x, y, z)

Creates a Euclidean direction vector.

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> Galixir.Algebras.PGA3.wedge(
...>   Galixir.Algebras.PGA3.new(e1: 1),
...>   Galixir.Algebras.PGA3.new(e2: 1)
...> )
Galixir.Algebras.PGA3.new(e12: 1)

iex> Galixir.Algebras.PGA3.wedge(
...>   Galixir.Algebras.PGA3.new(e2: 1),
...>   Galixir.Algebras.PGA3.new(e1: 1)
...> )
Galixir.Algebras.PGA3.new(e12: -1)

iex> Galixir.Algebras.PGA3.wedge(
...>   Galixir.Algebras.PGA3.new(e1: 1),
...>   Galixir.Algebras.PGA3.new(e1: 1)
...> )
Galixir.Algebras.PGA3.new()

wedge_all(vectors)

zero()

Returns the zero multivector.

zero?(arg1)

Checks whether all coefficients of a multivector are zero.

Examples

iex> Galixir.Algebras.PGA3.zero?(Galixir.Algebras.PGA3.new())
true

iex> Galixir.Algebras.PGA3.zero?(Galixir.Algebras.PGA3.new(e1: 1))
false