[ANN] Grassmann.jl : Differential geometric algebra

Grassmann algebra, Clifford algebra, and conformal geometric algebra are powerful algebraic tools

To help bring conformal geometric algebra to julia, the Grassmann library now provides most of the basic tools needed to begin working with a fully generalized MultiVector algebra.

This package is a work in progress providing the necessary tools to work with arbitrary dual MultiVector elements with optional origin. Due to the parametric type system for the generating VectorSpace , the Julia compiler can fully preallocate and often cache values efficiently. Both static and mutable vector types are supported.

It is currently possible to do both high-performance numerical computations with Grassmann and it is also currently possible to use symbolic scalar coefficients when the Reduce package is also loaded.

Fully general products available for high-performance and sparse computation include ∧,∨,β‹…,* (exterior, regressive, interior, geometric). Some unary operations include complementleft , complementright , reverse, involve , conj , and adjoint .

Notable features

What’s particularly special about Grassmann is its ability to handle caching and code generation in a tiered multi-stage setup and the ability to easily handle the creation of extra specialized methods to replace composite or dynamic dispatch scenarios with more efficient code.

This can work up to N=62 indices in the VectorSpace, reaching a 4,611,686,018,427,387,904 dimensional TensorAlgebra space, which is much beyond what Julia arrays can handle natively.

julia> using Grassmann

julia> i,j,k = complementright.((-Ξ›(3).v1,-Ξ›(3).v2,-Ξ›(3).v3))
(-1v₂₃, 1v₁₃, -1v₁₂)

julia> @btime i^2, j^2, k^2, i*j*k
  158.925 ns (5 allocations: 112 bytes)
(-1v, -1v, -1v, -1v)

julia> @btime -(j+k) * (j+k)
  176.233 ns (8 allocations: 240 bytes)

julia> @btime -(j+k) * i
  111.394 ns (6 allocations: 192 bytes)
0 - 1v₁₂ - 1v₁₃

The Grassmann package is fully general, and includes number systems such as quaternions 1,i,j,k.

Design, code generation

Due to the abstract generality of the product algebra code generation, it is possible to extend the Grassmann library to include additional high performance products with few extra definitions. Operations on ultra-sparse representations for very high dimensional algebras will be gaining further performance enhancements in future updates, while the standard lower dimensional algebras already are highly performant and optimized. Thanks to the design of the product algebra code generation, any additional optimizations to the type stability will automatically enhance all the different products simultaneously. Likewise, any new product formulas will be able to quickly gain from the setup of all of the existing optimizations.

Calculating some bivectors

There are are a variety of resources online which help with the introduction to the subject. One notable video useful for just about anybody interested in geometric algebra was posted by @waldyrious

Some of the examples in that video can be verified using Reduce, Grassmann in julia

julia> using Reduce,Grassmann; basis"4"
Reduce (Free CSL version, revision 4590), 11-May-18 ...
(⟨++++⟩, v, v₁, vβ‚‚, v₃, vβ‚„, v₁₂, v₁₃, v₁₄, v₂₃, vβ‚‚β‚„, v₃₄, v₁₂₃, v₁₂₄, v₁₃₄, v₂₃₄, v₁₂₃₄)

julia> P,Q = :px*v1 + :py*v2 + :pz* v3 + v4, :qx*v1 + :qy*v2 + :qz*v3 + v4
(pxv₁ + pyvβ‚‚ + pzv₃ + 1.0vβ‚„, qxv₁ + qyvβ‚‚ + qzv₃ + 1.0vβ‚„)

julia> P∧Q
0.0 + (px * qy - py * qx)v₁₂ + (px * qz - pz * qx)v₁₃ + (px - qx)v₁₄ + (py * qz - pz * qy)v₂₃ + (py - qy)vβ‚‚β‚„ + (pz - qz)v₃₄

julia> R = :rx*v1 + :ry*v2 + :rz*v3 + v4
rxv₁ + ryvβ‚‚ + rzv₃ + 1.0vβ‚„

julia> P∧Q∧R
0.0 + ((px * qy - py * qx) * rz - ((px * qz - pz * qx) * ry - (py * qz - pz * qy) * rx))v₁₂₃ + (((px * qy - py * qx) + (py - qy) * rx) - (px - qx) * ry)v₁₂₄ + (((px * qz - pz * qx) + (pz - qz) * rx) - (px - qx) * rz)v₁₃₄ + (((py * qz - pz * qy) + (pz - qz) * ry) - (py - qy) * rz)v₂₃₄

In this example, the exterior product of points is inspected and compared with inner,cross products.

It is my hope to use absorb of the feedback from the geomtric algebra community when making ongoing improvements to help refine the package’s source code generation and sparse specialization.


For a gentler introduction, I would recommend The Vector Algebra War: a historical perspective (video, 13min). As someone lacking rigorous mathematical background, I find that this sort of layman-friendly introductions greatly help motivate the initial exploration of this field, and consumption of more advanced materials.

For those more familiar with the concepts used in GA, the Ganja.js Cheat Sheets provide some really nice and comprehensive reference sheets.

It may also be worth noting the (abandoned?) package GeoAlg.jl by @andrioni:

work-in-progress straight port of Fontijne’s reference implementation of geometric algebra utilities to Julia.


Thank you. I can’t wait to try this out!

Daniel Fontijne’s OpenGL GAViewer still has one of the best graphic displays for multivectors I have seen, but its development has been defunct for a while now. I’ve scanned through his source and most of the drawing takes place in only a few methods. It might be nice to merge Grassmann.jl with GAViewer’s color/display methods on top of Makie.jl to explore multivectors and spaces. I’ve been waiting for Makie’s WebGL backend before tackling something like this.


There is also pyganja based on ganja.js for visualization, perhaps that would be easier to port since in Julia we already have python interoperability?

The Grassmann package is going to remain a separate package, it is intended for the abstract mathematical representation aspect of geometric algebra. Any visualization library would best be placed into a separate repository, since visualization requires additional many dependencies.

Perhaps you could get started on such a repository? related issue on using SymPy with Grassmann

1 Like

Looks great! So this is now more of a Geometric / Clifford Algebra package than a Grassmann Algebra package? Do you plan on supporting custom metrics in as a generalization to just specifying the signature?

I had tried doing something similar a while ago but got stuck figuring out a satisfactory way of supporting non-diagonal metrics.

1 Like

Roughly speaking, these algebras of Geometric / Clifford / Grassmann types are all fundamentally the same thing, with slightly different notations, formalisms, and preferences. The package itself implements conformal geometric algebra and it is named after Grassmann, who is often not adequately cited for his role in the invention of linear algebra and many other related subjects.

Yes, I do have an interest in that regard… but it is much lower on my list of design priorities. My primary goal was to get started an initial setup intended for high performance. The current setup helps facilitate the highest performance possible for most standard conformal geometric algebras.

There are a couple of ideas I got for that, but I have other goals first. You could open an issue for it?

To those interested, I opened up a new pull-request to discuss the sign value of LinearAlgebra.I when interpreted as a generalized universal pseudoscalar value

Since LinearAlgebra.I has a sign associated to it, I would like to interpret that as a minus sign, which is helpful in the theory and expressiveness of various formulas, but am opening it for discussion

Some new features have been added to fully support multivariable and higher-order dual numbers, i.e. Taylor numbers and Cartan differential forms.

The tangent map takes V to its tangent bundle and can be applied repeatedly or specified tangent(V,order) for higher.

julia> V = tangent(ℝ^3)

julia> V'

julia> V+V'

The chain rule is encoded into Grassmann algebra when a tangent bundle is used, demonstrated here symbolically with Reduce by using the dual number definition:

julia> using Grassmann, Reduce
Reduce (Free CSL version, revision 4590), 11-May-18 ...

julia> @mixedbasis tangent(ℝ^1)
(⟨+-β‚ΒΉβŸ©*, v, v₁, wΒΉ, ϡ₁, βˆ‚ΒΉ, v₁wΒΉ, v₁ϡ₁, vβ‚βˆ‚ΒΉ, w¹ϡ₁, wΒΉβˆ‚ΒΉ, Ο΅β‚βˆ‚ΒΉ, v₁w¹ϡ₁, v₁wΒΉβˆ‚ΒΉ, vβ‚Ο΅β‚βˆ‚ΒΉ, wΒΉΟ΅β‚βˆ‚ΒΉ, v₁wΒΉΟ΅β‚βˆ‚ΒΉ)

julia> a,b = :x*v1 + :dx*Ο΅1, :y*v1 + :dy*Ο΅1
(xv₁ + dxϡ₁, yv₁ + dyϡ₁)

julia> a * b
x * y + (dy * x - dx * y)v₁ϡ₁

Additionally, the generalized exponential map is implemented

julia> exp(Ο€*Ξ›(ℝ^2).v12)
-1.0000000000000004 + 3.3443843799521084e-16v₁₂

Unfortunately, the logarithm function is not converging yet…

This looks cool, what are some applications for Grassman algebra?

can you post a small contained practical example?

1 Like

It can be used for pretty much anything involving geometry, vectors, rotations, differentiations, etc

For example, quantum computing, automatic differentiation, differential geometry, algebraic forms, invariant theory, electric circuits, wave scattering, spacetime geometry, relativity, computer graphics, photogrammetry, and much more.

Currently, I am creating this package to learn geometric algebra itself, since I was not taught this subject and nobody explained it to me or working with me. Therefore, I am just learning it from scratch.

My goal is to implement a multi-dimensional continued fraction algorithm for special functions and also to solve the Navier-Stokes and Maxwell equations.

However, since I am somebody interested in the foundations of pure mathematics, the Applied Math aspect takes a back seat for me. My primary goal is to explore the foundations of mathematics, to make a better language for expressing complicated geometric scientific problems. In order to achieve this, I must make sure that the foundations are absolutely correct and highly extensible for many purposes. This is why I am not using Grassman for specific applications yet, to focus on foundations.

In the long-term future, I imagine that this kind of mathematics could become very central to most scientific and engineering research applications; however, it is still in early stages of development.

I would be excited to see what other people might want to do with it, there are countless possibilities.

So in conclusion, I am mainly focusing on researching the foundations of mathematics and how to combine various areas of math into a unified and efficient geometric algebra framework. In order to apply this in the future, I am doing the necessary work of constructing the underlying foundations.

In the future, I will have applications such as quantum computing and partial differential equations.


If you can point me in the general direction of an example in these areas that would be great.

I can relate

Have a look at ganja.js works in browser

For photogrammetry, this kind of math was used in the matrix movies


In v0.1.4 of Grassmann the null-basis of the conformal split has been fully incorporated into the algebra

julia> using Grassmann; @basis S"βˆžβˆ…++"
(βŸ¨βˆžβˆ…++⟩, v, v∞, vβˆ…, v₁, vβ‚‚, vβˆžβˆ…, vβˆžβ‚, vβˆžβ‚‚, vβˆ…β‚, vβˆ…β‚‚, v₁₂, vβˆžβˆ…β‚, vβˆžβˆ…β‚‚, vβˆžβ‚β‚‚, vβˆ…β‚β‚‚, vβˆžβˆ…β‚β‚‚)

julia> v∞^2, vβˆ…^2, v1^2, v2^2
(0v, 0v, v, v)

julia> v∞ β‹… vβˆ…

julia> vβˆžβˆ…^2

julia> vβˆžβˆ… * v∞, vβˆžβˆ… * vβˆ…
(-1v∞, vβˆ…)

julia> v∞ * vβˆ…, vβˆ… * v∞
(-1 + 1vβˆžβˆ…, -1 - 1vβˆžβˆ…)

This provides the point at infinity v∞, the origin vβˆ…, and the Minkowski plane vβˆžβˆ… also.


In physics, we see clifford algebras show up directly in a few different cases. There are two particularly common cases:

The first is for the creation and annihilation operators of fermions which form a clifford algebra of order 2n with signature (+ (n times), - (n times) ).

The second is for representing rotations and lorentz transforms, where you get the clifford algebras of order 3 of signature (+,+,+) to describe rotations and of order 4 with signature (+,+,+,-) in relativistic physics. In those cases it’s also useful to consider the representation theory of Clifford algebras, which gives the Gamma matrices acting on spinors.

That’s just in physics. You can use them to do a lot of other stuff conveniently as well. For example, you can use them to simplify the linear algebra that you would use when writing a raytracer.


Grassmann.jl v0.2 has now been released with many new features along with the following,

Today the first draft of the Differential geometric algebra using Leibniz, Grassmann paper is released:


This is supposed to be my submission for the JuliaCon 2019 proceesings, with 6-page limit it has to be concise to introduce the most important concepts and nuances. Later a more detailed a longer version will also be published. If anybody has comments about topics that could be expanded on in these papers, it could be directed to either this concise version or to the longer version in the future.

The source is made available here and here with the PDF linked from DropBox.


Next week at JuliaCon I will be giving a lightning talk on the Grassmann.jl package, I’d like to know if anyone is interested in meeting afterwards so I can answer a few questions or discuss applications you have in mind.


With v0.3.1 of Grassmann.jl it is now fairly stable to work with higher-order generalizations of derivations.

Using the tangent(V,D,#) space it is possible to explore the higher order Leibniz derivations.

Based on the definitions of differential geometric algebra, a higher order derivation is βˆ‚i^(D+1)==0:

julia> using Reduce, Grassmann; @mixedbasis tangent(ℝ^2,3,2);

julia> x = :x*v1 + βˆ‚1v1 + βˆ‚1*βˆ‚1v1 + βˆ‚1*βˆ‚1*βˆ‚1v1
0.0 + xv₁ + (1 + (1 + 1βˆ‚β‚)βˆ‚β‚)βˆ‚β‚v₁

julia> x^2
x ^ 2 + (2x + (2x + 1 + (2 * (x + 1))βˆ‚β‚)βˆ‚β‚)βˆ‚β‚

julia> x^3
0.0 + (x ^ 3)v₁ + (3 * x ^ 2 + (3 * (x + 1) * x + (3 * x ^ 2 + 6x + 1)βˆ‚β‚)βˆ‚β‚)βˆ‚β‚v₁

julia> x^7
0.0 + (x ^ 7)v₁ + (7 * x ^ 6 + (7 * (x + 3) * x ^ 5 + (7 * (x ^ 2 + 6x + 5) * x ^ 4)βˆ‚β‚)βˆ‚β‚)βˆ‚β‚v₁

julia> x^8
x ^ 8 + (8 * x ^ 7 + (4 * (2x + 7) * x ^ 6 + (8 * (x ^ 2 + 7x + 7) * x ^ 5)βˆ‚β‚)βˆ‚β‚)βˆ‚β‚

julia> x^11
0.0 + (x ^ 11)v₁ + (11 * x ^ 10 + (11 * (x + 5) * x ^ 9 + (11 * (x ^ 2 + 10x + 15) * x ^ 8)βˆ‚β‚)βˆ‚β‚)βˆ‚β‚v₁

As you can see, this is the 3rd order Leibniz-Taylor algebra. Arbitrary Leibniz-Taylor algebras are supported.

julia> V(βˆ‡)
0v₁₂ + 1βˆ‚β‚v₁ + 0βˆ‚β‚‚v₁ + 0βˆ‚β‚vβ‚‚ + 1βˆ‚β‚‚vβ‚‚ + 0βˆ‚β‚β‚‚

julia> V(βˆ‡)^2
0 + 1βˆ‚β‚βˆ‚β‚ + 1βˆ‚β‚‚βˆ‚β‚‚

julia> V(βˆ‡)^3
0.0 + 1βˆ‚β‚βˆ‚β‚βˆ‚β‚v₁ + 1βˆ‚β‚‚βˆ‚β‚‚βˆ‚β‚‚vβ‚‚ + 1βˆ‚β‚‚βˆ‚β‚β‚‚v₁ + 1βˆ‚β‚βˆ‚β‚β‚‚vβ‚‚

julia> V(βˆ‡)^4

By having GeometryTypes.Point interoperability, the Grassmann is now compatible with Makie:

using Grassmann, Makie
@basis S"∞+++" # 4D, Riemann sphere
sub = V(2,3,4) # 3D, SubManifold
glines(f,r=-2Ο€:0.0001:2Ο€) = lines([Point(sub(Grassmann.vector(f(t)))) for t ∈ r]);
f(t) = ↓(exp(t*v∞*(sin(3t)*3v1+cos(2t)*7v2-sin(5t)*4v3)/2)>>>↑(v1+v2-v3));
glines(f) # make plot in Makie

Note that Point(sub(Grassmann.vector(f(t)))) is used to convert the TensorAlgebra into the required GeometryTypes.Point format for AbstractPlotting.

Preferably, I’d like to completely bypass the Point abstraction and just directly plot and compute with the multivector TensorAlgebra type system… but I might need some help from @sdanisch for that.


That’s awesome. :blush:

1 Like

Wow, yeah this is great!

1 Like