npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-geometric-algebra

v0.5.1

Published

TypeScript Geometric Algebra generator

Downloads

91

Readme

ts-geometric-algebra

Ts-geometric-algebra is a Clifford Algebra Generator for TypeScript and JavaScript. It generates Geometric Algebras of any signature and is mostly combatible with Ganja.js. There is no operator overloading or inline functions yet due to lack of support in TypeScript.

(Mathematically, an algebra generated by ts-geometric-algebra is a graded exterior (Grassmann) algebra with a non-metric outer product, extended (Clifford) with geometric and contraction inner products, a Poincare duality operator and the main involutions and morphisms.)

(Technically, ts-geometric-algebra is a code generator producing classes that reificate algebraic literals.)

(Practically, ts-geometric-algebra enables algebraic operations over reals, complex numbers, dual numbers, hyperbolic numbers, vectors, spacetime events, quaternions, dual quaternions, biquaternions or any other Clifford Algebra with full type support from TypeScript.)

Discourse and Discord

Visit bivector.net for our forum and chat - the perfect place for questions and support.

Using ts-geometric-algebra for the first time

Install ts-geometric-algebra using npm :

npm install ts-geometric-algebra

And require it in your script :

const Algebra = require('ts-geometric-algebra').default;

The Algebra Function

To create an Algebra, call the Algebra function specifying the metric signature (number of positive, negative and zero dimensions). The result is an ES6 class implementing the requested clifford algebra.

function Algebra( p, q, r );
  // p    = number of positive dimensions.
  // q    = optional number of negative dimensions.
  // r    = optional number of zero dimensions.

An extended syntax is also available that allows you to further tweak the created Algebra.

function Algebra( p, q, r, {baseType, metric, mulTable, disableUnroll} )
  // p        = number of positive dimensions.
  // q        = optional number of negative dimensions.
  // r        = optional number of zero dimensions.
  // baseType = Float32Array or similar
  // metric   = basis vector inner products in custom order, must agree with p, q and r
  // mulTable = Custom signs for the Caley table
  // disableUnroll = (boolean) prevent loop unrolling of performance critical methods

Here are some examples :

// Basic
const Hyper   = Algebra(1);         // Hyperbolic numbers.
const Complex = Algebra(0, 1);      // Complex numbers.
const Dual    = Algebra(0, 0, 1);   // Dual numbers.
const H       = Algebra(0, 2);      // Quaternions.

// Clifford
const Cl2 = Algebra(2);             // Clifford algebra for 2D vector space.
const Cl3 = Algebra(3);             // Clifford algebra for 3D vector space.
const TimeSpace = Algebra(1, 3);    // Clifford algebra for timespace vectors.

// Geometric
const PGA2D = Algebra(2, 0, 1);     // Projective Euclidean 2D plane. (dual)
const PGA3D = Algebra(3, 0, 1);     // Projective Euclidean 3D space. (dual)
const CGA2D = Algebra(3, 1);        // Conformal 2D space.
const CGA3D = Algebra(4, 1);        // Conformal 3D space.

// High-Dimensional GA
const DCGA3D = Algebra(6, 2);       // Double Conformal 3D Space.
const TCGA3D = Algebra(9, 3);       // Triple Conformal 3D Space.
const DCGSTA = Algebra(4, 8);       // Double Conformal Geometric Space Time Algebra.
const QCGA   = Algebra(9, 6);       // Quadric Conformal Geometric Algebra.

You can now use these classes to generate algebraic elements. Those elements will have all of the expected properties. (norm, blade access, dot, wedge, mul, dual, inverse, etc ...)

Unlike Ganja.js you must use them in a 'classic' programming style syntax like the example below.

const Complex = Algebra(0, 1);       // Complex numbers.
const a = Complex.fromGanja([3, 2]); // 3 + 2i
const b = Complex.fromGanja([1, 4]); // 1 + 4i
return a.mul(b);                     // returns [-5, 14]

Altough not as pretty or fun as Ganja.js you have the full advantage of types and autocompletion.

Methods

| Object oriented | Ganja Equivalent | Explanation | |-------------------------|--------------------|-----------------| | x.equals(y) | N/A | Strict equality | | x.closeTo(y, tol?) | N/A | Equality within given tolerance | | x.hasNaN() | N/A | Check for Not-a-Numbers | | x.hasInfinity() | N/A | Check for (negative) infinity | | x.isNil(tol?) | N/A | Equal or close to zero | | x.isGrade(g, tol?) | N/A | Only has components of grade g | | x.s | x.s | Scalar part (get/set) | | x.ps | N/A | Pseudoscalar part (get/set) | | x.getAt(...idx) | N/A | Metric-aware coefficient of the product of basis factors defined by idx | | x.setAt(...idx, a) | N/A | Set coefficient of product of basis factors idx as a | | x.norm() | x.Length | Conjugate norm (metric-aware) | | x.vnorm() | x.VLength | Vector norm (ignores metric) {x.length is array length} | | x.taxicabNorm() | N/A | L1 norm (ignores metric) | | x.maxNorm() | N/A | Linfinity norm (ignores metric) | | x.neg() | N/A | Negation (additive inverse) | | x.cwAbs() | N/A | Component-wise absolute value | | x.involute() | x.Involute | Negation of basis factors | | x.rev() | x.Reverse | Reversal of basis factors {x.reverse is array reversal} | | x.conjugate() | x.Conjugate | Conjugation (combined involution and reversal) | | x.adjugate() | N/A | Unscaled multiplicative inverse (suitable for int base class) | | x.inverse() | x.Inverse | Multiplicative inverse | | x.square() | x.Mul(x) | Multiplicative squaring () | | x.normalize(a?) | x.Normalize | x with norm set to a (default 1) | | x.rotorNormalize() | N/A | Normalize rotor x | | x.sqrt() | N/A | Square root. Currently reliable only in dimensions < 2 | | x.rotorSqrt() | N/A | Rotor square root. Available in certain metrics. | | x.exp() | x.Exp | Exponential function | | x.bivectorExp() | x.Exp | Bivector exponential function (optimized) | | x.log() | x.Log | (Motor) Logarithm. Generic exp inverse available only in dimensions < 2 | | x.rotorLog() | x.Log | Rotor Logarithm | | x.clone() | x.Scale(1) | Independent copy | | x.dual() | x.Dual (*) | Metric independent dual: x.mul(x.dual()) = Cl.pseudoscalar() | | x.undual() | N/A | Inverse of x.dual() | | x.scale(a) | x.Scale(a) | Scalar multiplication | | x.pow(n) | x.Pow(n) | Multiply x with itself n times | | x.applyWeights(ws) | N/A | Replace each basis factor with a weighted copy for every weight in ws | | x.negateGrades(...gs) | x.Map(...gs) | Negate the given grades | | x.add(y) | x.Add(y) | Component-wise addition () | | x.sub(y) | x.Sub(y) | Component-wise subtraction () | | x.mul(y) | x.Mul(y) | Geometric product of x and y () | | x.lmul(y) | y.Mul(x) | Geometric product from the left () | | x.div(y) | x.Div(y) | Geometric division from the right | | x.ldiv(y) | y.Inverse.Mul(x) | Left inverse product | | x.ldivs(y) | x.Inverse.Mul(y) | Geometric division from the left | | x.wedge(y) | x.Wedge(y) | Wedge (outer) product. Metric independent () | | x.lwedge(y) | y.Wedge(x) | Wedge product from the left () | | x.vee(y) | x.Vee(y) | Vee (dual) product. Metric indepentend. x.vee(y) = y.dual().wedge(x.dual()).undual() () | | x.lvee(y) | y.Vee(x) | Vee product from the left () | | x.rotorMean(y) | N/A | Geometric mean of rotors x and y | | x.contract(y, ctn) | N/A | Contract x by y using criterion ctn | | x.dot(y) | x.Dot(y) | Dot product. Symmetric criterion () | | x.dotL(y) | x.LDot(y) | Left contraction of x by y () | | x.ldotL(y) | y.LDot(x) | Left contraction of y by x () | | x.dotR(y) | N/A | Right contraction of x by y | | x.ldotR(y) | N/A | Right contraction of y by x | | x.dotS(y) | N/A | Scalar product. Nil criterion | | x.imag() | N/A | Filter out grade 0 | | x.even() | x.Even() | Filter out odd grades | | x.grade(n) | x.Grade(n) | Keep only grade n components | | x.vector() | x.Vector | Array of vector components | | x.vector(n) | N/A | Array of n-vector components | | x.rotor() | N/A | Array of components of even grade | | x.ganja() | x | Array of all components in lexicographic order | | x.invScale(y, t?) | N/A | Ratio of weights between coincident x and y. Returs NaN if non-coincidence exteeds threshold t. | x.grades(t?) | N/A | Array of grades present in x exceeding threshold t (default 0) | | x.meetJoin(y, t?) | N/A | True (of threshold t) meet and join of blades x and y | | x.star(y) | N/A | Scalar product with number result | | Cl.zero() | Cl.Scalar(0) | Zero element | | Cl.scalar(a?) | Cl.Scalar(a) | Scalar element of size a (default 1) | | Cl.pseudoscalar(a?) | N/A | Pseudoscalar element of size a (default 1) | | Cl.basisBlade(...idx) | N/A | Unit basis blade given by the product of the given basis factors | | Cl.fromVector(vs) | Cl.Vector(...vs) | Vector element with given components (from an array) | | Cl.fromVector(vs, 2) | Cl.Bivector(...vs) | Bivector element with given components (lexicographic order) | | Cl.fromVector(vs, 3) | Cl.Trivector(...vs) | Trivector element with given components | | Cl.fromVector(vs, g) | Cl.nVector(g, ...vs) | g-vector element with given components | | Cl.fromRotor(vs) | N/A | Even grade element with given components | | Cl.fromGanja(vs) | new Cl(vs) | New element with components given in lexicographic order | | Cl.dimensions | --> | Math.log(Cl.describe().basis.length)/Math.LN2 number of dimensions | | Cl.size | --> | Cl.describe().basis.length algebra size | | Cl.metric | --> | Cl.describe().metric.slice(1, n+1) basis vector metric | | Cl.mulTable | --> | Similar to Cl.describe().mulTable but signs only | | new Cl(vs) | N/A | Not recommended, use fromGanja instead. New element with components given in bit field order |

(*) Only in degenerate metrics (**) Loop unrolled for maximum performance

Dual Zoo

| Object oriented | Function Oriented | Ganja Equivalent | Explanation | |----------------------|-----------------------|---------------------|-----------------| | x.podge() | podge(x) | x.Mul(ps) | Right-multiplication by Cl.pseudoscalar() | | x.unpodge() | unpodge(x) | x.Div(ps) | Right-division by Cl.pseudoscalar() | | x.podgeL() | podgeL(x) | ps.Mul(x) | Left-multiplication by Cl.pseudoscalar() | | x.unpodgeL() | unpodgeL(x) | ps.Inverse.Mul(x) | Left-division by Cl.pseudoscalar() | | x.star() | star(x) | N/A | Non-degenerate x.podge() | | x.unstar() | unstar(x) | N/A | Inverse of x.star() | | x.starL(x) | starL(x) | x.Dual (*) | Non-degenerate x.podgeL() | | x.unstarL(x) | unstarL(x) | N/A | Inverse of x.starL() | | x.hodge() | hodge(x) | N/A | Hodge dual | | x.unhodge() | unhodge(x) | N/A | Inverse of x.hodge() | | x.hodgeL() | hodgeL(x) | N/A | Left Hodge dual | | x.unhodgeL() | unhodgeL(x) | N/A | Inverse of x.hodgeL() |

(*) Only in non-degenerate metrics

Rotor operation availability

| Metric (pqr) | Available operations | |--------------|----------------------| | p+q+r <= 2 | (all) | | 400 | rotorSqrt, rotorNormalize | | 310 | rotorSqrt, rotorNormalize | | 301 | rotorLog, rotorSqrt, rotorNormalize | | 410 | rotorSqrt, rotorNormalize |

Functions

| Function Oriented | Ganja Equivalent | Explanation | |--------------------------|--------------------|-----------------| | equals(x, y) | N/A | Strict equality | | closeTo(x, y, tol?) | N/A | Equality within given tolerance | | hasNaN(x) | N/A | Check for Not-a-Numbers | | hasInfinity(x) | N/A | Check for (negative) infinity | | isNil(x, tol?) | N/A | Equal or close to zero | | isGrade(x, g, tol?) | N/A | Only has components of grade g | | norm(x) | x.Length | Conjugate norm (metric-aware) | | vnorm(x) | x.VLength | Vector norm (ignores metric) {x.length is array length} | | taxicabNorm(x) | N/A | L1 norm (ignores metric) | | maxNorm(x) | N/A | Linfinity norm (ignores metric) | | neg(x) | N/A | Negation (additive inverse) | | cwAbs(x) | N/A | Component-wise absolute value | | involute(x) | x.Involute | Negation of basis factors | | rev(x) | x.Reverse | Reversal of basis factors {x.reverse is array reversal} | | conjugate(x) | x.Conjugate | Conjugation (combined involution and reversal) | | adjugate(x) | x.Inverse | Unscaled multiplicative inverse | | inverse(x) | x.Inverse | Multiplicative inverse | | square(x) | x.Mul(x) | Multiplicative squaring () | | normalize(x, a?) | x.Normalize | x with norm set to a (default 1) | | rotorNormalize(x) | N/A | Normalize rotor x | | sqrt(x) | N/A | Square root. Currently reliable only in dimensions < 2 | | rotorSqrt(x) | N/A | Rotor square root. Available in certain metrics. | | exp(x) | x.Exp | Exponential function | | bivectorExp(x) | x.Exp | Bivector exponential function (optimized) | | log(x) | x.Log | (Motor) Logarithm. Generic exp inverse available only in dimensions < 2 | | rotorLog(x) | x.Log | Rotor Logarithm | | clone(x) | x.Scale(1) | Independent copy | | dual(x) | x.Dual (*) | Metric independent dual: x.mul(x.dual()) = Cl.pseudoscalar() | | undual(x) | N/A | Inverse of x.dual() | | scale(x, a) | x.Scale(a) | Scalar multiplication | | pow(x, n) | x.Pow(n) | Multiply x with itself n times | | applyWeights(x, ws) | N/A | Replace each basis factor with a weighted copy for every weight in ws | | negateGrades(x, ...gs) | x.Map(...gs) | Negate the given grades | | add(...args) | x.Add(y) | Component-wise addition () | | sub(x, y) | x.Sub(y) | Component-wise subtraction () | | mul(...args) | x.Mul(y) | Geometric product of x and y () | | div(x, y) | x.Div(y) | Geometric division from the right | | ldivs(x, y) | x.Inverse.Mul(y) | Geometric division from the left | | wedge(...args) | x.Wedge(y) | Wedge (outer) product. Metric independent () | | vee(...args) | x.Vee(y) | Vee (dual) product. Metric indepentend. vee(x, y) = undual(dual(y), dual(x)) () | | rotorMean(x, y) | N/A | Geometric mean of rotors x and y | | contract(x, y, ctn) | N/A | Contract x by y using criterion ctn | | dot(x, y) | x.Dot(y) | Dot product. Symmetric criterion () | | dotL(x, y) | x.LDot(y) | Left contraction of x by y () | | dotR(x, y) | N/A | Right contraction of x by y | | dotS(x, y) | N/A | Scalar product. Nil criterion | | imag(x) | N/A | Filter out grade 0 | | even(x) | x.Even() | Filter out odd grades | | grade(x, n) | x.Grade(n) | Keep only grade n components | | invScale(x, y, t?) | N/A | Ratio of weights between coincident x and y. Returs NaN if non-coincidence exteeds threshold t. | grades(x, t?) | N/A | Array of grades present in x exceeding threshold t (default 0) | | meetJoin(x, y, t?) | N/A | True (of threshold t) meet and join of blades x and y | | star(x, y) | N/A | Scalar product with number result |

(*) Only in degenerate metrics (**) Loop unrolled for maximum performance

The functions equals, closeTo, add, sub, mul, div, ldivs, wedge, vee also work on the number type.

Linear equation solver

You can solver equations of the form (for the moment pretending that javascript has scalar multiplication of arrays)

x = coeffs[0] * basis[0] + coeffs[1] * basis[1] + ... + coeffs[n-1] * basis[n-1]

for the unknown coefficients coeffs.

const coeffs = vLinSolve(x, basis);

This comes with the added cost of algebra creation on each call. If you need to do a lot of solving create your algebra beforehand.

import {Algebra, linSolve} from 'ts-geometric-algebra';
const Grassmann = Algebra(0, 0, 3);
const x = Grassmann.fromVector([1, 2, 3]);
const basis = [
  Grassmann.fromVector([1, 1, 1]),
  Grassmann.fromVector([0, 1, -1]),
  Grassmann.fromVector([-1, 2, -2])
];
const coeffs = linSolve(x, basis);  // [ 2.5, -3.5, 1.5 ]

Octonions

While all generated geometric algebras are associative it's possible to produce non-associative algebras using custom multiplication tables. This package comes with a pre-configured table for Octonions and monkey-patches conjugate, inverse, sqrt, exp and log to work correctly.

import {makeOctonion} from 'ts-geometric-algebra';
const O = makeOctonion();
const e1 = Octonion.basisBlade(0);
const e2 = Octonion.basisBlade(1);
const e4 = Octonion.basisBlade(2);

e1.mul(e2).mul(e4)  // [0, 0, 0, 0, 0, 0, +1]
e1.mul(e2.mul(e4))  // [0, 0, 0, 0, 0, 0, -1]