Geometries

Geometric objects can be represented in different ways depending on which geometry is used to express them. For example an oriented euclidean line in the plane can be represented as an oriented subspace of projective dimension 1 in the euclidean geometry, or as a point on the quadric of the Laguerre geometry (Blaschke cylinder). To distinguish between them some of our geometric objects allow you to pass a geometry upon initialization of a new instance.

Obtaining defined geometries

Our library already comes with some predefined geometries. Use get_geometry to obtain them with their identifier and your desired dimension:

Name

elliptic

hyperbolic

laguerre

moebius

euclidean

projective

inner product

yes

yes

yes

yes

no

no

signature

(n,0,0)

(n-1,1,0)

(n-2,1,1)

(n-1,1,0)

/

/

dual ip

yes

yes

no

yes

yes

no

dual sign

(n,0,0)

(n-1,1,0)

/

(n-1,1,0)

(n-1,0,1)

/

>>> import ddg

>>> ddg.geometry.geometries.get_geometry('elliptic 3d')
EllipticGeometry(3, is_dual=False)

>>> ddg.geometry.geometries.get_geometry('hyperbolic', 3)
HyperbolicGeometry(3, is_dual=False)

>>> ddg.geometry.geometries.get_geometry('laguerre 2d')
LaguerreGeometry(3, is_dual=False)

>>> ddg.geometry.geometries.get_geometry('moebius', 3)
MoebiusGeometry(3, is_dual=False)

>>> euclidean = ddg.geometry.geometries.get_geometry('euclidean', 4)
>>> euclidean
EuclideanGeometry(4, is_dual=False)

>>> euclidean.dualize()
EuclideanGeometry(4, is_dual=True)

>>> ddg.geometry.geometries.get_geometry('lie', 5)
LieGeometry(5, is_dual=False)

Creating a new geometry

Sometimes none of our predefined geometries will fit our problem. In this case you can easily create your own geometry:

>>> import numpy as np

>>> ddg.geometry.geometries.Geometry(dimension = 4)
Geometry(name=None, dimension=4)
>>> ddg.geometry.geometries.ProjectiveGeometry('example name 1',
...                                             dimension=4, is_dual=True)
ProjectiveGeometry(name='dual example name 1', dimension=4, is_dual=True)
>>> ddg.geometry.geometries.CayleyKleinGeometry(np.diag([1,0,3,2]),
...                                             'example name 2')
CayleyKleinGeometry(
  Quadric(
    array([[1, 0, 0, 0],
           [0, 0, 0, 0],
           [0, 0, 3, 0],
           [0, 0, 0, 2]])
  ),
  name='example name 2'
)

We have to take care when we choose names for our new geometry as only one geometry can have the same combination of name and dimension. Similar to the predefined geometries you can reobtain your own geometries with get_geometry as long as you gave it a name.

Differences between the geometry classes

  • Geometry, the most basic geometry class

  • ProjectiveGeometry, can be dualized.

  • CayleyKleinGeometry, inherits from ProjectiveGeometry, but also can have inner product and requires either a quadric, inner product function, or matrix representation of it when initialized

Conversion between geometries

We sometimes want to represent an object in a different model. For this we can use our (geometry) convert function, which chooses the appropriate way to convert an object for us. Just give source and target geometries or geometry identifiers:

>>> import ddg.geometry.conversion

>>> points = [[1,0,1],[0,1,1]]
>>> subspace = ddg.geometry.subspaces.Subspace(*points)
>>> subspace
Subspace(array([1., 0., 1.]), array([0., 1., 1.]))

>>> laguerre_point = ddg.geometry.conversion.convert(subspace, source_geometry='euclidean 2d', target_geometry='laguerre 2d')
>>> laguerre_point
Point(array([-0.70710678, -0.70710678,  0.70710678,  1.        ]))

>>> conv_back = ddg.geometry.conversion.convert(laguerre_point, 'laguerre 2d', 'euclidean 2d')
>>> conv_back == subspace
True

Adding new conversion functions

All newly added conversion functions have to be located in the geometry.conversion module and have to follow a naming convention to allow the convert function to find it:

  1. _[source geometry w/o dimension]_to_[target geometry w/o dimension], e.g.

    _laguerre_to_euclidean

  2. _[source geometry w/ dimension]_to_[target geometry w/ dimension], e.g.

    _laguerre2d_to_euclidean2d

The function convert will always try to use the dimension specific conversion functions first.