Skip to content

Commit

Permalink
Provide grade selection and cleanup algebra/type inference
Browse files Browse the repository at this point in the history
Evaluation and compute contexts now reside in the namespace of
each algebra's module.

Points in pga now remain dualized. Homogenization happens only
when cast to a VGA point.

EGA -> VGA has been renamed (other algebras are also used to
compute in "Euclidean" space).

The bivector exponential is now evaluated using lower-level ops.

Deprecate logarithm until conditionals and variadic transcendentals
are available in a compute context.
  • Loading branch information
jeremyong committed Nov 30, 2019
1 parent f4eaeac commit e859994
Show file tree
Hide file tree
Showing 20 changed files with 823 additions and 1,082 deletions.
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ For the most complete and up-to-date documentation, please refer to the project

## Runtime and Compile-time performance

Early results are showing that GAL is >2x faster than versor but with slower compile times which depend on
the expression complexity.
GAL is slowly converging to hand-optimized code for computing with geometric entities in the various algebras.
The goal is, of course, perfect convergence (up to auto-vectorization at least).

Runtime and compile time performance is achieved by using the following approach to expression evaluation.

1. Expressions are encoded using standard expression tree templates.
1. Expressions are encoded using flattened arrays of Reverse-Polish Notation nodes.
2. Expression inputs are entities that are encoded with flat representations (e.g. an R3 point is just 3 floats and not tied to a multivector representation).
3. Prior to evaluation, expression inputs are expressed in indeterminate multivector form (parameters of each input are expressed via integral tags, not floating-point values). This is encoded using 3 flat compile-time arrays per multivector (storing intederminates, monomials, and polynomials) for fast simplification and evaluation.
4. Expressions are expanded in indeterminate form using polynomial coefficients so that term arithmetic can happen exactly over the field of rationals. A number of techniques are used to put strict upper bounds on compile time memory and CPU usage whever possible.
Expand Down Expand Up @@ -52,7 +52,8 @@ Please adjust the snippet above per recommendations from the journal you wish to

Being a template-library, GAL is header-only and can be installed by either linking the `gal` interface target via cmake or by copying the files in `src` to a known include path.

To build the tests, you need a C++ compiler (currently untested via MSVC) that supports C++17 or greater.
To build the tests, you need a C++ compiler that supports C++17 or greater.
Older compilers that purport to support C++17 *may not work* due to invalid conformance.

```sh
# From the root directory of this project
Expand All @@ -76,6 +77,11 @@ is usually not used to retain finer control over numerical stability. However, u
considerably over traditional linear algebra approaches. The second flag enables fused-multiply-add
instructions which both improves precision and is available on most hardware.

## MSVC

MSVC is not yet supported because this library relies on several techniques that break under MSVC due to a
lack of standards conformance. Help is appreciated in this regard (especially if you're a VC++ dev!).

## Motivation

Geometric Algebra promises (and fulfills) a unified algebraic system for manipulating geometric objects
Expand Down Expand Up @@ -151,20 +157,24 @@ For more complete documentation, please refer to the [project page](https://jere
Example usage:

```c++
#include <gal/vga.hpp>
#include <gal/pga.hpp>

// Let's work with the projectivized dual space of R3
using point = gal::pga::point<float>;
using gal::pga::compute;

// We'll specify our points in R^3
using point = gal::vga::point<float>;

// Let's construct a few random points.
// Each of these points occupies no more than 12 bytes (+ alignment padding) but
// carry with them compile time representations of the PGA
// Each of these points occupies no more than 12 bytes (+ alignment padding).
point p1{2.4f, 3.6f, 1.3f};
point p2{-1.1f, 2.7f, 5.0f};
point p3{-1.8f, -2.7f, -4.3f};

// We issue a computation using the `compute` method which accepts a lambda
plane<float> p = compute<gal::pga::plane<float>>([](auto p1, auto p2, auto p3)
// We issue a computation using the `compute` method which accepts a lambda.
// Note that when we supply VGA points, the points become automatically dualized.
plane<float> p = gal::pga::compute<gal::pga::plane<float>>([](auto p1, auto p2, auto p3)
{
// The p1, p2, and p3 variables here are shadow types of the points residing
// "in the engine" and we operate with them using any of the operations:
Expand Down
8 changes: 4 additions & 4 deletions docs/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ To use GAL, you need to minimally include a single header corresponding to the m

| Header | Space | Namespace | Description
--- | --- | --- | ---
`gal/ega.hpp` | \(\mathbb{R}_{3, 0, 0}\) | `gal::ega` | Canonical 3D Euclidean space
`gal/vga.hpp` | \(\mathbb{R}_{3, 0, 0}\) | `gal::vga` | 3D Euclidean vector space
`gal/pga2.hpp` | \(\mathbf{P}(\mathbb{R}^*_{2, 0, 1})\) | `gal::pga2` | Projectivized 2D Euclidean plane
`gal/pga.hpp` | \(\mathbf{P}(\mathbb{R}^*_{3, 0, 1})\) | `gal::pga` | Projectivized 3D Euclidean space
`gal/cga2.hpp` | \(\mathbf{C}(\mathbb{R}_{3, 1, 0})\) | `gal::cga2` | Conformalized 2D Euclidean plane
Expand Down Expand Up @@ -74,7 +74,7 @@ All entities support initialization the way you'd expect. For example `point<dou

Where appropriate, entities may support the `normalize` method, which mutates the entity as appropriate for its type. A divide-by-zero check is not performed. In all cases in fact, the library adopts the philosophy that the user should not pay for what the user does not use.

Entities are stored sparsely regardless of the model they are in with *no additional overhead* for multivector basis-index bookkeeping. For example, `sizeof(point<float>)` is 12 (3 floats) regardless of whether you are working with CGA (where the point is represented as \(\mathbf{o} + p_x\mathbf{e_x} + p_y\mathbf{e_y} + p_z\mathbf{e_z} + \frac{1}{2}p^2\boldsymbol\infty\)) or in EGA (where the point is simply \(p_x\mathbf{e_x} + p_y\mathbf{e_y} + p_z\mathbf{e_z}\)).
Entities are stored sparsely regardless of the model they are in with *no additional overhead* for multivector basis-index bookkeeping. For example, `sizeof(point<float>)` is 12 (3 floats) regardless of whether you are working with CGA (where the point is represented as \(\mathbf{o} + p_x\mathbf{e_x} + p_y\mathbf{e_y} + p_z\mathbf{e_z} + \frac{1}{2}p^2\boldsymbol\infty\)) or in VGA (where the point is simply \(p_x\mathbf{e_x} + p_y\mathbf{e_y} + p_z\mathbf{e_z}\)).

### Evaluating expressions

Expand Down Expand Up @@ -229,7 +229,7 @@ This creates the quantity \(3.2e_{01} + 1.2e_{02}\) and can be used in a compute
algorithm.hpp # Compile-time routines (i.e. sorting, rearrangement)
cga.hpp # Provides conformal geometric algebra
cga2.hpp # Provides 2D conformal geometric algebra (aka compass ruler algebra)
ega.hpp # Provides 3D geometric algebra
vga.hpp # Provides 3D vector space geometric algebra
engine.hpp # Defines various mechanisms for evaluating expressions at runtime
entity.hpp # Describes the statically-typed representation of runtime multivectors
expression_debug.hpp # Debug facilities
Expand All @@ -248,7 +248,7 @@ This creates the quantity \(3.2e_{01} + 1.2e_{02}\) and can be used in a compute
*[GA]: Geometric Algebra
*[MSVC]: Microsoft Visual C++
*[GCC]: GNU C Compiler
*[EGA]: Euclidean Geometric Algebra
*[VGA]: "Common" Euclidean Vector Space Geometric Algebra
*[PGA]: Projective Geometric Algebra
*[CGA]: Conformal Geometric Algebra
*[PR]: Pull Request
Expand Down
Loading

0 comments on commit e859994

Please sign in to comment.