Ganja.js
:triangular_ruler: Javascript Geometric Algebra Generator for Javascript, c++, c#, rust, python. (with operator overloading and algebraic literals) -
Install / Use
/learn @enkimute/Ganja.jsREADME
ganja.js - Geometric Algebra for javascript.
Geometric Algebra - Not Just Algebra
<IMG TITLE="Geometric Algebra - Not Just Algebra" SRC="images/ganja_thumb.jpg" WIDTH=100%>Ganja.js is a Geometric Algebra code generator for javascript. It generates Clifford algebras and sub-algebras of any signature and implements operator overloading and algebraic constants.
@misc{ganja.js,
doi = {10.5281/ZENODO.3635774},
url = {https://zenodo.org/record/3635774},
author = {De Keninck, Steven},
title = {ganja.js},
howpublished = {Zenodo. https://doi.org/10.5281/ZENODO.3635774},
year = {2020}
}
(Mathematically, an algebra generated by ganja.js is a graded exterior (Grassmann) algebra (or one of its subalgebras) 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, ganja.js is a code generator producing classes that reificate algebraic literals and expressions by using reflection, a built-in tokenizer and a simple AST translator to rewrite functions containing algebraic constructs to their procedural counterparts.)
(Practically, ganja.js enables real math syntax inside javascript, with element, vector and matrix operations over reals, complex numbers, dual numbers, hyperbolic numbers, vectors, spacetime events, quaternions, dual quaternions, biquaternions or any other Clifford Algebra.)
(Seriously, look at the examples, run some quick numbers using the GAlculator or play the wedge game first.)
Discourse and Discord
Visit bivector.net for our forum and chat - the perfect place for questions and support.
New !
ganja.js now has a nodejs based templated source generator that allows the creation of arbitrary algebras for C++, C#, python and rust. The generated code provides in a flat multivector format and operator overloading. Check the 'codegen' folder for the source, several algebras are available in pregenerated versions.
- C++ pre-generated sources
- C# pre-generated sources
- rust pre-generated sources
- python pre-generated sources
Contents
1. Reasons to use ganja<BR> 2. Using ganja for the first time<BR> 3. Getting free ganja samples<BR> 4. Ganja for experienced users<BR> 5. Ganja ingredients and syntax<BR> 6. Ganja starterkit : PGA2D P(R*<sub>2,0,1</sub>)<BR> 7. Ganja starterkit : PGA3D P(R*<sub>3,0,1</sub>)<BR>
<A NAME="Features"></A>
Reasons to use ganja
Ganja.js makes doing Geometric Algebra in your browser easy and fun. Its inline syntax and graphing makes math in the browser feel like .. math.
- Operator overloading
- Algebraic constants
- Supports any metric (positive,negative,zero) and dimensionality (also +10)
- smallish (20kb on the wire)
- matrix-free inverses up to 5D.
- geometric, inner (left contraction), outer (wedge) and regressive (vee) product
- conjugate, Reverse, Involute, Dual (Poincare), Negative
- 4 API's (inline, asciimath, object oriented, functional)
- Easy graph function for 1D and 2D functions, Projective 2D, 3D and conformal 2D and 3D elements. (SVG/webGL/OPNS)
- Supports vectors and matrices in all its algebras.
- There's a game that teaches you how to use ganja.js !
<A NAME="Started"></A>
Using ganja for the first time
Install ganja.js using npm :
npm install ganja.js
And require it in your script :
var Algebra=require('ganja.js');
Or in the browser, just include the ganja.js script. (ganja.js has no dependencies)
<SCRIPT SRC="https://unpkg.com/ganja.js"></SCRIPT>
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, func );
// p = number of positive dimensions.
// q = optional number of negative dimensions.
// r = optional number of zero dimensions.
// func = optional function. (shorthand .. it is passed to .inline and executed)
An extended syntax is also available that allows you to further tweak the created Algebra.
function Algebra( options, func );
// options = object containing subset of
// {
// p, integer number of positive dimensions.
// q, integer number of negative dimensions.
// r, integer number of zero dimensions.
// metric, [a,b,..] array with metric per generating dimensions. (e.g. [0,1,1] for PGA2D)
// basis, ["1","e1","e2"] basis that overrules the standard cannonical basis.
// Cayley, [["1","e1"],["e1","-1"]] Cayley table to overrule standard GA tables.
// baseType, float32Array (default), float64Array, .. baseType to be used for the Elements.
// mix Set to true to enable interoperable sub-algebras. (defaults to false).
// }
// returns : algebra class if no func supplied, function result if func supplied.
Here are some examples :
// Basic
var Hyper = Algebra(1); // Hyperbolic numbers.
var Complex = Algebra(0,1); // Complex numbers.
var Dual = Algebra(0,0,1); // Dual numbers.
var H = Algebra(0,2); // Quaternions.
// Clifford
var Cl2 = Algebra(2); // Clifford algebra for 2D vector space.
var Cl3 = Algebra(3); // Clifford algebra for 3D vector space.
var timeSpace = Algebra(1,3); // Clifford algebra for timespace vectors.
// SubAlgebras
var Complex = Algebra({p:3,basis:['1','e123']}); // Complex Numbers as subalgebra of Cl3
var H = Algebra({p:3,basis:['1','e12','e13','e23']}); // Quaternions as even subalgebra of Cl3
// Geometric
var PGA2D = Algebra(2,0,1); // Projective Euclidean 2D plane. (dual)
var PGA3D = Algebra(3,0,1); // Projective Euclidean 3D space. (dual)
var CGA2D = Algebra(3,1); // conformal 2D space.
var CGA3D = Algebra(4,1); // Conformal 3D space.
// High-Dimensional GA
var DCGA3D = Algebra(6,2); // Double Conformal 3D Space.
var TCGA3D = Algebra(9,3); // Triple Conformal 3D Space.
var DCGSTA = Algebra(4,8); // Double Conformal Geometric Space Time Algebra.
var 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. (Length, blade access, Dot, Wedge, Mul, Dual, Inverse, etc ...)
And while not advised you could use them in a 'classic' programming style syntax like the example below.
var Complex = Algebra(0,1); // Complex numbers.
var a = new Complex([3,2]); // 3+2i
var b = new Complex([1,4]); // 1+4i
return a.Mul(b); // returns [-5, 14]
This however, is not very pretty. It's not that much fun either. Luckily, ganja.js provides an alternate way to write algebraic functions, literals and expressions.
The inline function
Your Algebra class exposes this interface through the inline function. It accepts a javascript function, and translates it to use the Algebra of your choice. Using the inline function, the above example is written :
Algebra(0,1).inline(()=>(3+2e1)*(1+4e1))(); // return [-5,14]
Note that if you are immediately executing the function, you can add it as a last parameter to your Algebra constructor call.
Algebra(0,1,()=>(3+2e1)*(1+4e1)); // return [-5,14]
The inline syntax is powerful and flexible. It offers full operator overloading, overloads scientific e-notation to allow you to directly specify basis blades and allows using arrays or lambda expressions without the need for calling brackets in algebraic expressions.
Algebra(2,0,1,()=>{
// Direct specification of basis blades using e-notation.
var xy_bivector = 1e12,
pseudoscalar = 1e012;
// Operator overloading .. * = geometric product, ^ = wedge, & = vee, << = dot, >>> = sandwich ...
var xy_bivector_from_product = 1e1 * 1e2;
// Directly specified point.
var some_point = 1e12 + 0.4e01 + 0.5e02;
// Function that returns point.
var function_that_returns_point = ()=>some_point + 0.5e01;
// Join of point and function .. notice no calling brackets ..
var join_between_point_and_function = some_point & function_that_returns_point;
// Same line as above.. but as function.. (so will update if the point changes)
var function_that_returns_join = ()=>some_point & function_that_returns_point;
// Binary operations on arrays also work as expected.
var even = [1,2,3,4,5]*2;
// Even if those contain multivectors or other arrays :
var funky = [1, 1e01+0.5e02, [3,4]] * 3 + [1,2,3];
// All elements and functions can be rendered directly. (again, no calling brackets).
var canvas = this.graph([ some_point, function_that_returns_point, function_that_returns_join ]);
});
Under the hood, ganja.js will translate these f
