Crate vee

Crate vee 

Source
Expand description

$V_{EE}$ – Vector Expression Emitter: Geometric Algebra Code Generator

The goal of this crate is to generate optimized code for geometric algebra flavors. Currently, this crate implements the symbolic reduction of multivector expressions up to polynomials with rational coefficients. In contrast, rational polynomials and hence polynomial division is not required for lower dimensional geometric algebra flavors as the inverse of a multivector is given by multiplying it with the inverse of its mixed-grade norm, i.e., a Study number for dimensions $D < 6$.1 See the examples below where the symbolic expressions are generated in text form. The next releases will implement code forms (e.g., Rust code in various profiles based on SIMD using lav with and without generics or arbitrary precision types using rug). The pre-generated code forms will be provided along with the code generator behind respective feature gates. When packages_as_namespaces is stable, each code form will become a crate. Currently, the plane-based pistachio flavor – Projective Geometric Algebra (PGA) – is implemented for $D \equiv N + 1 \le 8$ in all three metrics, i.e., elliptic, hyperbolic, and parabolic (Euclidean).2 The 5D, 6D, and 7D PGAs (i.e., $N = 5$, $N = 6$, and $N = 7$) are exploratory as there are no inverses based on Study numbers. They provide dimension-agnostic insights regarding duality, the choice of basis blades, and grade-preserving conditions among orthonormalization conditions. The PGA is especially of interest for computer graphics (e.g., game and physics engines) as it is the most compact flavor (i.e., a one-up flavor) unifying the established but scattered frameworks, e.g., homogeneous coordinates, Plücker coordinates, (dual) quaternions, and screw theory. Even without any knowledge of geometric algebra, an API can be more intuitive as it unifies the positional and directional aspects of geometric entities (e.g., planes, lines, points) and the linear and angular aspects of rigid-body dynamics in a dimension-agnostic way with closed-form (i.e., non-iterative) solutions up to 4D (e.g., PgaP2, PgaP3, PgaP4).3

§Operators

Following table lists the common operators shared between flavors. The code for the first three will be manually written based on Study numbers whereas the code for the remaining ones will be automatically generated based on Multivector.

\gdef\e{
  \boldsymbol e
}
\gdef\I{
  \boldsymbol I
}
\gdef\norm{
  \| a \| \equiv \sqrt{a \tilde a}
}
\gdef\unit{
  \hat a \equiv \dfrac{a}{\| a \|}
}
\gdef\inv{
  a^{-1} \equiv \dfrac{\tilde a}{\| a \|^2}
}
\gdef\rev{
  \tilde a \equiv \sum_s (-1)^{s \choose 2} \lang a \rang_s
}
\gdef\pol{
  a^{\perp} \equiv a\I
}
\gdef\not{
  a^* \equiv \sum_s \lang a \rang_s^*
    : \lang a \rang_s^* = \sum_i \alpha_i a_i^*
      : a_i a_i^* = \I
}
\gdef\unnot{
  a_* \equiv a^{***} \therefore (a^*)_* = a^{****} = a
}
\gdef\neg{
  -a \equiv (-1)a
}
\gdef\add{
  a + b \equiv \sum_s \lang a \rang_s + \sum_t \lang b \rang_t
}
\gdef\sub{
  a - b \equiv \sum_s \lang a \rang_s - \sum_t \lang b \rang_t
}
\gdef\mul{
  ab \equiv \sum_{s,t} \lang a \rang_s \lang b \rang_t
}
\gdef\div{
  \dfrac{a}{b} \equiv ab^{-1}
}
\gdef\rem{
  a \times b \equiv \frac{1}{2}(ab - ba)
}
\gdef\bitor{
  a \mid b \equiv \sum_{s,t}
    \lang
      \lang a \rang_s
      \lang b \rang_t
    \rang_{\|s - t\|}
}
\gdef\bitxor{
  a \wedge b \equiv \sum_{s,t}
    \lang
      \lang a \rang_s
      \lang b \rang_t
    \rang_{s + t}
}
\gdef\bitand{
  a \vee b \equiv {(a^* \wedge b^*)}_*
}
\gdef\shl{
  a \looparrowleft b
    \equiv \sum_{s,t} (-1)^{st} \lang b \rang_t \lang a \rang_s \lang \tilde b \rang_t
}
\gdef\shr{
  a \curvearrowright b \equiv (a \mid b) \tilde b
}
\gdef\from{
  \lang a \rang_b \equiv \sum_{s \in \{t|b = \sum_t \lang b \rang_t\}} \lang a \rang_s
}
OperatorNameFormula
a.norm()Norm (mixed grade)$\norm$
a.unit()Unit (orthonormal)$\unit$
a.inv()Inverse$\inv$
a.rev()Reverse$\rev$
a.pol()Polarity$\pol$
!aDual (right complement)$\not$
!!!aUndual (left complement)$\unnot$
-aNegation (orientation)$\neg$
B::from(a)Selection (mixed grade)$\from$
a + b, a += bSum$\add$
a - b, a -= bDifference$\sub$
a * b, a *= bProduct (geometric)$\mul$
a / b, a /= bQuotient (geometric)$\div$
a << b, a <<= bReflection ($a$ by $b$)$\shl$
a >> b, a >>= bProjection ($a$ onto $b$)$\shr$
a % bCommutator$\rem$
a | bContraction (symmetric)$\bitor$
a ^ bMeet (progressive)$\bitxor$
a & bJoin (regressive)$\bitand$

§Examples

Generates the expression for rotating a point in PgaP3, i.e., the type alias of Multivector parameterized for the Parabolic (Euclidean) 3D PGA. The PgaP3::pin() method pins symbols of PgaP3::point() with the combining x below (i.e., the Unicode combining diacritical mark "◌͓") to distinguish them from the symbols of PgaP3::rotator().

use vee::{format_eq, PgaP3 as Vee};

// Assumes motor is not orthonormalized.
format_eq!(Vee::point().pin() << Vee::motor(), [
    "+(+vv+xx+yy+zz)w͓e123",
    "+(+(+vv+xx-yy-zz)X͓+2(+vz+xy)Y͓+2(-vy+xz)Z͓+2(-Vx-Xv-Yz+Zy)w͓)e032",
    "+(+2(-vz+xy)X͓+(+vv-xx+yy-zz)Y͓+2(+vx+yz)Z͓+2(-Vy+Xz-Yv-Zx)w͓)e013",
    "+(+2(+vy+xz)X͓+2(-vx+yz)Y͓+(+vv-xx-yy+zz)Z͓+2(-Vz-Xy+Yx-Zv)w͓)e021",
]);

// Assumes motor is orthonormalized.
format_eq!(Vee::point().pin() << Vee::motor().unit(), [
    "+w͓e123",
    "+(+(+1-2yy-2zz)X͓+2(+vz+xy)Y͓+2(-vy+xz)Z͓+2(-Vx-Xv-Yz+Zy)w͓)e032",
    "+(+2(-vz+xy)X͓+(+1-2xx-2zz)Y͓+2(+vx+yz)Z͓+2(-Vy+Xz-Yv-Zx)w͓)e013",
    "+(+2(+vy+xz)X͓+2(-vx+yz)Y͓+(+1-2xx-2yy)Z͓+2(-Vz-Xy+Yx-Zv)w͓)e021",
]);

// Assumes motor and point are (ortho)normalized where point has positive orientation.
format_eq!(Vee::point().eval([(('w', "e123"), 1)]).pin() << Vee::motor().unit(), [
    "+e123",
    "+(+2(-Vx-Xv-Yz+Zy)+(+1-2yy-2zz)X͓+2(+vz+xy)Y͓+2(-vy+xz)Z͓)e032",
    "+(+2(-Vy+Xz-Yv-Zx)+2(-vz+xy)X͓+(+1-2xx-2zz)Y͓+2(+vx+yz)Z͓)e013",
    "+(+2(-Vz-Xy+Yx-Zv)+2(+vy+xz)X͓+2(-vx+yz)Y͓+(+1-2xx-2yy)Z͓)e021",
]);

The symbols are assigned to basis blades such that lowercase symbols are dual to their corresponding uppercase symbols. For blades containing $\e_0$, uppercase symbols are used. The PgaP3::swp() method swaps lowercase and uppercase symbols. This is useful for testing duality equivalences.

use vee::{format_eq, PgaP3 as Vee};

format_eq!(Vee::plane(), ["+We0", "+xe1", "+ye2", "+ze3"]);
format_eq!(Vee::point(), ["+we123", "+Xe032", "+Ye013", "+Ze021"]);

assert_ne!(!Vee::plane(), Vee::point());
assert_eq!(!Vee::plane(), Vee::point().swp());

Alternatively, symbols are labelled after their initially assigned basis blades starting with:

use vee::{format_eq, PgaP3 as Vee};

format_eq!("{:#}", Vee::point().pin() << Vee::motor().unit(), [
    "+p123*e123",
    "+(+(+1-2*v31*v31-2*v12*v12)*p032+2*(+v*v12+v23*v31)*p013+2*(-v*v31+v23*v12)*p021\
       +2*(-v0123*v23-v01*v-v02*v12+v03*v31)*p123)*e032",
    "+(+2*(-v*v12+v23*v31)*p032+(+1-2*v23*v23-2*v12*v12)*p013+2*(+v*v23+v31*v12)*p021\
       +2*(-v0123*v31+v01*v12-v02*v-v03*v23)*p123)*e013",
    "+(+2*(+v*v31+v23*v12)*p032+2*(-v*v23+v31*v12)*p013+(+1-2*v23*v23-2*v31*v31)*p021\
       +2*(-v0123*v12-v01*v31+v02*v23-v03*v)*p123)*e021",
]);

The predominant sign is factored as well with "{:-}":

use vee::{format_eq, PgaP3 as Vee};

// Unfactored predominant sign.
format_eq!(Vee::point().pin() << Vee::motor(), [
   "+(+vv+xx+yy+zz)w͓e123",
   "+(+(+vv+xx-yy-zz)X͓+2(+vz+xy)Y͓+2(-vy+xz)Z͓+2(-Vx-Xv-Yz+Zy)w͓)e032",
   "+(+2(-vz+xy)X͓+(+vv-xx+yy-zz)Y͓+2(+vx+yz)Z͓+2(-Vy+Xz-Yv-Zx)w͓)e013",
   "+(+2(+vy+xz)X͓+2(-vx+yz)Y͓+(+vv-xx-yy+zz)Z͓+2(-Vz-Xy+Yx-Zv)w͓)e021",
//                                          ^^^^^^^^^^^^^^^^^^
]);

// Factored predominant sign.
format_eq!("{:-}", Vee::point().pin() << Vee::motor(), [
   "+(+vv+xx+yy+zz)w͓e123",
   "+(+(+vv+xx-yy-zz)X͓+2(+vz+xy)Y͓+2(-vy+xz)Z͓-2(+Vx+Xv+Yz-Zy)w͓)e032",
   "+(+2(-vz+xy)X͓+(+vv-xx+yy-zz)Y͓+2(+vx+yz)Z͓-2(+Vy-Xz+Yv+Zx)w͓)e013",
   "+(+2(+vy+xz)X͓+2(-vx+yz)Y͓+(+vv-xx-yy+zz)Z͓-2(+Vz+Xy-Yx+Zv)w͓)e021",
//                                          ^^^^^^^^^^^^^^^^^^
]);

The factorization is skipped with "{:+}":

use vee::{format_eq, PgaP3 as Vee};

format_eq!("{:+}", Vee::point().pin() << Vee::motor(), [
    "+(+vvw͓+w͓xx+w͓yy+w͓zz)e123",
    "+(-2Vw͓x-2Xvw͓+X͓vv+X͓xx-X͓yy-X͓zz-2Yw͓z+2Y͓vz+2Y͓xy+2Zw͓y-2Z͓vy+2Z͓xz)e032",
    "+(-2Vw͓y+2Xw͓z-2X͓vz+2X͓xy-2Yvw͓+Y͓vv-Y͓xx+Y͓yy-Y͓zz-2Zw͓x+2Z͓vx+2Z͓yz)e013",
    "+(-2Vw͓z-2Xw͓y+2X͓vy+2X͓xz+2Yw͓x-2Y͓vx+2Y͓yz-2Zvw͓+Z͓vv-Z͓xx-Z͓yy+Z͓zz)e021",
]);

  1. S. De Keninck and M. Roelfs, “Normalization, square roots, and the exponential and logarithmic maps in geometric algebras of less than 6D”, Mathematical Methods in the Applied Sciences 47, 1425–1441

  2. M. Roelfs and S. De Keninck, “Graded Symmetry Groups: Plane and Simple”, Advances in Applied Clifford Algebras 33

  3. L. Dorst and S. De Keninck, “Physical Geometry by Plane-Based Geometric Algebra”, Advanced Computational Applications of Geometric Algebra, 43–76

Modules§

pga
Plane-Based Pistachio Flavor – Projective Geometric Algebra (PGA)

Macros§

format_eq
Formats the $lhs expression using Display and asserts the $rhs string literals.

Structs§

Factorization
Uniquely reduced but volatile form of symbolic polynomial factorization.
Monomial
Uniquely reduced form of a symbolic monomial expression.
Multivector
Uniquely reduced form of a symbolic multivector expression.
Polynomial
Uniquely reduced form of a symbolic polynomial expression.
Rational
Rational number in canonical form.
Symbol
Symbol as Unicode character with optional combining diacritical mark.

Enums§

Tree
Non-binary algebraic expression tree up to symbolic Multivector expressions.

Traits§

Algebra
A geometric algebra defined by a flavor’s basis (i.e., all its basis blades).
Choose
Finds the binomial coefficient.
Factor
Finds the greatest common divisor (GCD) and the least common multiple (LCM).

Type Aliases§

PgaE0
Multivector for Elliptic 0D PGA.
PgaE1
Multivector for Elliptic 1D PGA.
PgaE2
Multivector for Elliptic 2D PGA.
PgaE3
Multivector for Elliptic 3D PGA.
PgaE4
Multivector for Elliptic 4D PGA.
PgaE5
Multivector for Elliptic 5D PGA (exploratory).
PgaE6
Multivector for Elliptic 6D PGA (exploratory).
PgaE7
Multivector for Elliptic 7D PGA (exploratory).
PgaH0
Multivector for Hyperbolic 0D PGA.
PgaH1
Multivector for Hyperbolic 1D PGA.
PgaH2
Multivector for Hyperbolic 2D PGA.
PgaH3
Multivector for Hyperbolic 3D PGA.
PgaH4
Multivector for Hyperbolic 4D PGA.
PgaH5
Multivector for Hyperbolic 5D PGA (exploratory).
PgaH6
Multivector for Hyperbolic 6D PGA (exploratory).
PgaH7
Multivector for Hyperbolic 7D PGA (exploratory).
PgaP0
Multivector for Parabolic (Euclidean) 0D PGA.
PgaP1
Multivector for Parabolic (Euclidean) 1D PGA.
PgaP2
Multivector for Parabolic (Euclidean) 2D PGA.
PgaP3
Multivector for Parabolic (Euclidean) 3D PGA.
PgaP4
Multivector for Parabolic (Euclidean) 4D PGA.
PgaP5
Multivector for Parabolic (Euclidean) 5D PGA (exploratory).
PgaP6
Multivector for Parabolic (Euclidean) 6D PGA (exploratory).
PgaP7
Multivector for Parabolic (Euclidean) 7D PGA (exploratory).