"""Spherical geometry module.
"""
import numpy as np
import ddg
from ddg.geometry.moebius_models import _ProjectiveSubgeometry
__all__ = ["ProjectiveModel"]
[docs]class ProjectiveModel(_ProjectiveSubgeometry):
"""Spherical geometry as a subgeometry of Möbius geometry.
.. rubric:: Model space
The model space is the Möbius quadric with matrix `diag([1,...,1, -1])`.
.. rubric:: Representation of objects
Geometric objects are represented as Möbius spheres, i.e. Quadric objects
contained in the Möbius quadric.
Parameters
----------
dimension : int
Attributes
----------
dimension : int
Notes
-----
This class supports comparison with `==`. Two geometries are equal
if and only if they have the same type and `dimension`.
This class also supports the `in` operator to check whether a point is in
the model space.
"""
@property
def fixed_point(self):
"""Point inside the Möbius quadric used to compute the metric.
This is the origin with representative [0,...,0, 1].
Returns
-------
ddg.geometry.Point
"""
p = np.zeros(self.ambient_dimension + 1)
p[-1] = 1
return ddg.geometry.Point(p)
[docs] def d(self, v, w):
"""Spherical metric
Given by the formula ::
<x, y> / (<x, p> <y, p>) = -2 * sin^2(d([x],[y]) / 2)
Where p is some point inside the quadric. In our case, we take the
origin e_n+2.
Parameters
----------
v, w : ddg.geometry.Point or array_like of shape (n,)
Returns
-------
float
"""
if isinstance(v, ddg.geometry.Point):
v = v.point
if isinstance(w, ddg.geometry.Point):
w = w.point
p = self.fixed_point.point
b = self.inner_product
arg = np.sqrt(-0.5 * b(v, w) / (b(v, p) * b(w, p)))
if ddg.nonexact.isclose(arg, 1):
return np.pi
return 2 * np.arcsin(arg)