ddg.geometry.subspaces module

class ddg.geometry.subspaces.Subspace(*points, atol=None, rtol=None)[source]

Bases: Embeddable, LinearTransformable

Subspace of a projective space. Represented by a number of vectors in homogeneous coordinates.

Parameters:
*pointsarray_like of list or numpy.ndarray of shape (n,)

Homogeneous coordinate vectors spanning the subspace. If the span is 1-dimensional, automatically casts to subspaces.Point

Non-float dtypes will be converted to float.

atol, rtolfloat (default=None)

Tolerances that will be used internally by the class. If these are set to None, the global defaults will be used.

See also

Point

Notes

Subspaces can be empty. In this case, points are stored as an empty matrix with shape (n,0) if the ambient dimension is n-1. Empty spaces must be initialized with 0-vectors.

Attributes:
points

List of points spanning the subspace in homogeneous coordinates.

matrix
affine_points

List of points spanning the affine part of the subspace.

affine_matrix

Matrix whose columns span the affine part of the subspace.

affine_point_and_directions

Return point in the subspace and directions.

dimension
ambient_dimension
codimension

Methods

at_infinity()

Whether the object is contained in the hyperplane at infinity.

property points

List of points spanning the subspace in homogeneous coordinates.

Returns:
list of numpy.ndarray of shape (ambient_dimension+1,)
embed(subspace=None)[source]

The embedded object.

We can embed a subset X of n-dimensional projective space into m-dimensional space (where m >= n) by choosing an n-dimensional subspace S in RP^m together with a basis B. We then interpret the original homogeneous coordinates as coordinates w.r.t. this basis B.

More concretely: If M is the matrix of S, we define

X.embed(S) := { [M @ x] | [x] in X }.

X.embed(S) must be the same kind of object as X, for example if X is a euclidean sphere, the basis M must be chosen so that X.embed(S) is also a euclidean sphere.

Parameters:
subspaceSubspace (default=None)

Subspace in m-dimensional ambient space whose dimension is the ambient dimension of self (where m >= n). The homogeneous coordinates of points are used as cordinates w.r.t. the given basis of subspace.

The default is the coordinate hyperplane {x_n+1 = 0} in (n+1)-dimensional space, where n is the ambient dimension of self. The basis is the standard basis with the second to last basis vector missing.

Returns:
type(self)

Object in m-dimensional ambient space contained in subspace.

Raises:
ValueError

If embedding w.r.t. the given basis would result in an object of a different type.

unembed(subspace=None)[source]

Inverse of embed.

Parameters:
subspaceSubspace (default=None)

k-dim. subspace to treat as the new ambient space. coordinates of points will be computed w.r.t. the given basis of subspace.

The default is the coordinate hyperplane {x_n = 0} which will fail if the object is not contained in this subspace.

Returns:
type(self)

Object in k-dim. ambient space.

Raises:
ValueError
  • If object is not contained in subspace.

  • If coordinate computation would result in an object of a different type.

property affine_points

List of points spanning the affine part of the subspace.

Computes points in affine coordinates that, when homogenized, form a basis for the subspace.

Returns:
list of numpy.ndarray of shape (ambient_dimension,)
property affine_matrix

Matrix whose columns span the affine part of the subspace.

Computes points in affine coordinates that, when homogenized, form a basis for the subspace. Returns them as the columns of a matrix.

Returns:
numpy.ndarray of shape (ambient_dimension, dimension+1)
Raises:
ValueError

If the subspace is at infinity.

property affine_point_and_directions

Return point in the subspace and directions.

Returns affine coordinate vectors p and d1, …, dk such that the original subspace is spanned by [p,1], [d1,0], …, [dk,0].

The point is the one that is closest to the zero vector in affine coordinates and the directions are orthonormal.

Returns:
numpy.ndarray, list of numpy.ndarray
at_infinity()[source]

Whether the object is contained in the hyperplane at infinity.

Returns:
bool
property dimension
property ambient_dimension
property codimension
transform(F)[source]

Return a linearly transformed copy.

The transformation is assumed to be a projective transformation in homogeneous coordinates.

Parameters:
Fnumpy.ndarray of shape (ambient_dimension + 1, ambient_dimension + 1)
Returns:
type(self)
dualize(ambient_space=None)[source]

Return dual subspace.

Parameters:
ambient_spaceSubspace (default=None)

Other subspace containing this subspace that should be used as ambient space when dualizing. None means whole space.

Returns:
Subspace
orthonormalize()[source]

Returns subspace with a regularized basis. Useful for visualization.

See orthonormalize_subspace() for full documentation.

See also

orthonormalize_subspace

Equivalent function

center(center, remove_index=None, insert_index=0)[source]

Returns subspace with a point inserted into the basis. Useful for visualization.

See center_subspace() for full documentation.

See also

center_subspace

Equivalent function

orthonormalize_and_center(center)[source]

Returns subspace with a regularized basis and a point inserted in the basis Useful for visualization.

See orthonormalize_and_center_subspace() for full documentation.

See also

orthonormalize_and_center_subspace

Equivalent function

dehomogenize()[source]

Returns subspace with last entries of basis vectors normalized to 1. Useful for visualization.

See dehomogenize_subspace() for full documentation.

See also

dehomogenize_subspace

Equivalent function

change_affine_picture(before, after=-1)

Transform the object to a different affine view.

Dehomogenizing the object post-transform with affine component after will produce the same affine picture as dehomogenizing the object pre-transform with affine component before.

The actual transformation that achieves this just permutes the homogeneous coordinates as follows: It deletes the entry at before and inserts it again at position after.

Here are two examples of how you might use this function:

  1. You defined a projective object X with a certain affine picture in mind and you followed our convention of using affine component -1. You now want to see what it would look like when dehomogenized using a different affine component i. To do this, you would just do X_ = X.change_affine_picture(i) and then visualize the object normally.

  2. You don’t like our convention of dehomogenizing by the last component and want to define your object X with the affine picture with respect to affine component i in mind. To visualize your object as you imagine it, you would also do X_ = X.change_affine_picture(i).

Parameters:
beforeint
afterint (default=-1)
Returns:
type(self)
class ddg.geometry.subspaces.Point(point, atol=None, rtol=None)[source]

Bases: Subspace

Subclass for points (0-dim. projective subspaces).

Parameters:
pointlist or numpy.ndarray of shape (n,)
atol, rtolfloat (default=None)

Tolerances that will be used internally by the class. If these are set to None, the global defaults will be used.

Attributes:
point

Homogeneous coordinate vector representing the point.

affine_point

Affine coordinate vector representing the point.

property point

Homogeneous coordinate vector representing the point.

Returns:
numpy.ndarray (dimension+1,)
property affine_point

Affine coordinate vector representing the point.

Returns:
numpy.ndarray of shape (dimension,)
Raises:
ValueError

If the point is at infinity.

property affine_matrix

Matrix whose columns span the affine part of the subspace.

Computes points in affine coordinates that, when homogenized, form a basis for the subspace. Returns them as the columns of a matrix.

Returns:
numpy.ndarray of shape (ambient_dimension, dimension+1)
Raises:
ValueError

If the subspace is at infinity.

property affine_point_and_directions

Return point in the subspace and directions.

Returns affine coordinate vectors p and d1, …, dk such that the original subspace is spanned by [p,1], [d1,0], …, [dk,0].

The point is the one that is closest to the zero vector in affine coordinates and the directions are orthonormal.

Returns:
numpy.ndarray, list of numpy.ndarray
property affine_points

List of points spanning the affine part of the subspace.

Computes points in affine coordinates that, when homogenized, form a basis for the subspace.

Returns:
list of numpy.ndarray of shape (ambient_dimension,)
property ambient_dimension
at_infinity()

Whether the object is contained in the hyperplane at infinity.

Returns:
bool
center(center, remove_index=None, insert_index=0)

Returns subspace with a point inserted into the basis. Useful for visualization.

See center_subspace() for full documentation.

See also

center_subspace

Equivalent function

change_affine_picture(before, after=-1)

Transform the object to a different affine view.

Dehomogenizing the object post-transform with affine component after will produce the same affine picture as dehomogenizing the object pre-transform with affine component before.

The actual transformation that achieves this just permutes the homogeneous coordinates as follows: It deletes the entry at before and inserts it again at position after.

Here are two examples of how you might use this function:

  1. You defined a projective object X with a certain affine picture in mind and you followed our convention of using affine component -1. You now want to see what it would look like when dehomogenized using a different affine component i. To do this, you would just do X_ = X.change_affine_picture(i) and then visualize the object normally.

  2. You don’t like our convention of dehomogenizing by the last component and want to define your object X with the affine picture with respect to affine component i in mind. To visualize your object as you imagine it, you would also do X_ = X.change_affine_picture(i).

Parameters:
beforeint
afterint (default=-1)
Returns:
type(self)
property codimension
dehomogenize()

Returns subspace with last entries of basis vectors normalized to 1. Useful for visualization.

See dehomogenize_subspace() for full documentation.

See also

dehomogenize_subspace

Equivalent function

property dimension
dualize(ambient_space=None)

Return dual subspace.

Parameters:
ambient_spaceSubspace (default=None)

Other subspace containing this subspace that should be used as ambient space when dualizing. None means whole space.

Returns:
Subspace
embed(subspace=None)

The embedded object.

We can embed a subset X of n-dimensional projective space into m-dimensional space (where m >= n) by choosing an n-dimensional subspace S in RP^m together with a basis B. We then interpret the original homogeneous coordinates as coordinates w.r.t. this basis B.

More concretely: If M is the matrix of S, we define

X.embed(S) := { [M @ x] | [x] in X }.

X.embed(S) must be the same kind of object as X, for example if X is a euclidean sphere, the basis M must be chosen so that X.embed(S) is also a euclidean sphere.

Parameters:
subspaceSubspace (default=None)

Subspace in m-dimensional ambient space whose dimension is the ambient dimension of self (where m >= n). The homogeneous coordinates of points are used as cordinates w.r.t. the given basis of subspace.

The default is the coordinate hyperplane {x_n+1 = 0} in (n+1)-dimensional space, where n is the ambient dimension of self. The basis is the standard basis with the second to last basis vector missing.

Returns:
type(self)

Object in m-dimensional ambient space contained in subspace.

Raises:
ValueError

If embedding w.r.t. the given basis would result in an object of a different type.

orthonormalize()

Returns subspace with a regularized basis. Useful for visualization.

See orthonormalize_subspace() for full documentation.

See also

orthonormalize_subspace

Equivalent function

orthonormalize_and_center(center)

Returns subspace with a regularized basis and a point inserted in the basis Useful for visualization.

See orthonormalize_and_center_subspace() for full documentation.

See also

orthonormalize_and_center_subspace

Equivalent function

property points

List of points spanning the subspace in homogeneous coordinates.

Returns:
list of numpy.ndarray of shape (ambient_dimension+1,)
transform(F)

Return a linearly transformed copy.

The transformation is assumed to be a projective transformation in homogeneous coordinates.

Parameters:
Fnumpy.ndarray of shape (ambient_dimension + 1, ambient_dimension + 1)
Returns:
type(self)
unembed(subspace=None)

Inverse of embed.

Parameters:
subspaceSubspace (default=None)

k-dim. subspace to treat as the new ambient space. coordinates of points will be computed w.r.t. the given basis of subspace.

The default is the coordinate hyperplane {x_n = 0} which will fail if the object is not contained in this subspace.

Returns:
type(self)

Object in k-dim. ambient space.

Raises:
ValueError
  • If object is not contained in subspace.

  • If coordinate computation would result in an object of a different type.

ddg.geometry.subspaces.subspace_from_rows(matrix, **kwargs)[source]

Create subspace using the rows of a matrix as points.

Parameters:
matrixnumpy.ndarray of shape (k+1,n+1)
**kwargsdict

Other arguments to be passed to the Subspace.

Returns:
ddg.geometry.subspaces.Subspace

Notes

An empty subspace can be created by giving a 0-matrix or a matrix with shape (0,n+1).

ddg.geometry.subspaces.subspace_from_columns(matrix, **kwargs)[source]

Create subspace using the columns of a matrix as points.

Parameters:
matrixnumpy.ndarray of shape (n+1,k+1)
**kwargsdict

Other arguments to be passed to the Subspace.

Returns:
ddg.geometry.subspaces.Subspace

Notes

An empty subspace can be created by giving a 0-matrix or a matrix with shape (n,0).

ddg.geometry.subspaces.hyperplane_from_normal(normal, level=None, point=None, **kwargs)[source]

An affine hyperplane defined by either <x, normal> == level, or the normal and a point (given in affine coordinates) on the plane.

ddg.geometry.subspaces.normals(subspace)[source]

Return all normal directions of a subspace.

If p1, p2 are two points in the subspace in affine coordinates and n is a normal direction, then

<p1 - p2, n> = 0.

Parameters:
subspaceSubspace
Returns:
list of numpy.ndarray of shape (subspace.ambient_dimension,)

Normals in affine coordinates.

ddg.geometry.subspaces.normal_with_level(hyperplane)[source]

Unit normal vector and negative level of a hyperplane in one vector.

A hyperplane having normal N and level l means that in affine coordinates, the hyperplane is the set of points x such that

<x, N> = l,

which is equivalent to

<x, N> - l = 0.

This function computes a representative vector v = [N, -l] of the dual space, normalized such that N has unit length.

-N and -l define the same hyperplane. To fix this sign, an orientation would have to be given on the hyperplane. This function does not distinguish between the two choices, so the sign should be treated as random.

Parameters:
hyperplaneSubspace

Hyperplane in n-dimensional ambient space.

Returns:
Nlnumpy.ndarray of shape (n+1,)

The vector [N, -l]. The subspace Point(Nl).dualize() is the original hyperplane.

ddg.geometry.subspaces.normal(hyperplane)[source]

Unit normal vector N of a hyperplane.

The hyperplane consists of all points x such that

<x, N> = l

where l is the level of the hyperplane.

Parameters:
hyperplaneSubspace

Hyperplane in n-dimensional ambient space.

Returns:
Nnumpy.ndarray of shape (n,)
ddg.geometry.subspaces.level(hyperplane)[source]

Level l of a hyperplane.

The hyperplane consists of all points x such that

<x, N> = l

where N is the unit normal of the hyperplane.

The level is the distance of the hyperplane from the origin in the normal direction, i.e. the hyperplane contains l * N.

Parameters:
hyperplaneSubspace

Hyperplane in n-dimensional ambient space.

Returns:
lfloat
ddg.geometry.subspaces.angle_bisectors(hyperplane1, hyperplane2)[source]

Create the two angle bisecting hyperplanes of two given hyperplanes. The first entry in the output is the angle bisector that is orientation preserving. The second one is orientation reversing.

Parameters:
hyperplane1ddg.geometry.Subspace
hyperplane2ddg.geometry.Subspace
Returns:
(ddg.geometry.Subspace, ddg.geometry.Subspace)
ddg.geometry.subspaces.angle_bisector_orientation_preserving(hyperplane1, hyperplane2)[source]

Create the orientation preserving angle bisecting hyperplane of two given hyperplanes. It is orientation preserving in the sense, that reflection in this angle bisector maps one hyperplane to the other with matching orientation.

Parameters:
hyperplane1ddg.geometry.Subspace
hyperplane2ddg.geometry.Subspace
Returns:
ddg.geometry.Subspace
ddg.geometry.subspaces.angle_bisector_orientation_reversing(hyperplane1, hyperplane2)[source]

Create the orientation reversing angle bisecting hyperplane of two given hyperplanes. It is orientation reversing in the sense, that reflection in this angle bisector maps one hyperplane to the other with opposite orientation.

Parameters:
hyperplane1ddg.geometry.Subspace
hyperplane2ddg.geometry.Subspace
Returns:
ddg.geometry.Subspace
ddg.geometry.subspaces.perpendicular_bisector(p1, p2)[source]

Create a hyperplane orthogonal to the join of p1 and p2.

It intersects this line in the midpoint of p1.affine_point and p2.affine_point.

Parameters:
p1: ddg.geometry.subspaces.Point
p2: ddg.geometry.subspaces.Point
Returns:
ddg.geometry.Subspace

Hyperplane that is orthogonal to the input line.

ddg.geometry.subspaces.subspace_from_affine_points(*points, **kwargs)[source]

Create a subspace from affine points.

Parameters:
*pointsiterable of numpy.ndarray or list

Affine coordinate vectors

**kwargsdict

Other keyword arguments to be passed to the subspace.

Returns:
ddg.geometry.subspaces.Subspace

Subspace spanned by the given points

ddg.geometry.subspaces.subspace_from_affine_rows(matrix, **kwargs)[source]

Create a subspace from the rows of a matrix, interpreted as affine coordinates.

Parameters:
matrixnumpy.ndarray

Array whichs columns describe the affine points

**kwargsdict

Other keyword arguments to be passed to the subspace.

Returns:
ddg.geometry.subspaces.Subspace

Subspace spanned by the given points

ddg.geometry.subspaces.subspace_from_affine_columns(matrix, **kwargs)[source]

Create a subspace from the columns of a matrix, interpreted as affine coordinates.

Parameters:
matrixnumpy.ndarray

Array whichs columns describe the affine points

**kwargsdict

Other keyword arguments to be passed to the subspace.

Returns:
ddg.geometry.subspaces.Subspace

Subspace spanned by the given points

ddg.geometry.subspaces.subspace_from_affine_points_and_directions(points, directions, **kwargs)[source]

Create a subspace from affine points and directions.

Parameters:
points(list of numpy.array) or numpy.array

List of points or a single point

directions(list of numpy.array) or numpy.array

List of directions or a single direction

**kwargsdict

Other keyword arguments to be passed to the subspace.

Returns:
ddg.geometry.subspaces.Subspace

Subspace spanned by the given points and directions

Raises:
ValueError

If both points and directions are empty lists.

ddg.geometry.subspaces.random_subspace(ambient_dimension, subspace_dimension=None, seed=None)[source]

Create a random subspace.

Parameters:
ambient_dimensionint
subspace_dimensionint (default=None)

Dimension of the resulting subspace. If None, this is chosen randomly between 0 and ambient_dimension (inclusive).

seedint, numpy.random.Generator or None (default=None)

Passes a fixed seed to default Generator class. If passed a Generator, just uses that generator for random generation.

Returns:
Subspace
ddg.geometry.subspaces.random_contained_subspace(subspace, dimension=None, seed=None)[source]

Create a random subspace contained in another subspace.

Parameters:
subspaceSubspace

The subspace that should contain the resulting subspace.

dimensionint (default=None)

Dimension of the resulting subspace. If None, this is chosen randomly between 0 and subspace.dimension (inclusive).

seedint, numpy.random.Generator or None (default=None)

Passes a fixed seed to default Generator class. If passed a Generator, just uses that generator for random generation.

Returns:
Subspace
Raises:
ValueError

If dimension is greater than subspace.dimension.

ddg.geometry.subspaces.orthonormalize_subspace(subspace)[source]

Regularize the basis of a subspace. Useful for visualization.

Returns an equal subspace with a basis of the form [p, v1,...,vk], where p is the point in the subspace closest to the origin with last entry 1 and v1,...,vk are orthonormal direction vectors at infinity. This is only possible if the subspace is not at infinity.

When using the “convex” parametrization in to_smooth_net, the parametrization of the subspace with this new basis will be

f(x1,...,xk) = p + x1 * v1 + ... + xk * vk
Parameters:
subspaceSubspace
Returns:
Subspace

The same subspace with the regularized basis.

Raises:
ValueError

If subspace is at infinity.

ddg.geometry.subspaces.center_subspace(subspace, center, remove_index=None, insert_index=0)[source]

Insert a specific point into the basis of a subspace.

This is especially useful in preparation for visualization: When applying this function and then using the “convex” parametrization in to_smooth_net, the parametrization will be centered around the new center, if it is a point not at infinity.

Parameters:
subspaceSubspace
centerPoint or numpy.ndarray of shape (k,) or (k+1,)

Where k is the ambient dimension of the subspace. Point must lie in subspace. Can be given as Point object or as array containing affine or homogeneous coordinates.

remove_indexint (default=None)

Index of basis vector that should be replaced with center. If None, we search for one.

insert_indexint (default=0)

Index where center should be inserted.

Returns:
Subspace

The same subspace with a basis that has center at position insert_index.

Raises:
ValueError
  • If center does not lie in the subspace.

  • If the vector at remove_index could not be replaced with center while still having a basis.

ddg.geometry.subspaces.orthonormalize_and_center_subspace(subspace, center)[source]

Regularize the basis of a subspace. Useful for visualization.

Returns an equal subspace with a basis of the form [p, v1,...,vk], where p is the center with last entry 1 and v1,...,vk are orthonormal direction vectors at infinity. This is only possible if the subspace is not at infinity.

When using the “convex” parametrization in to_smooth_net, the parametrization of the subspace with this new basis will be

f(x1,...,xk) = p + x1 * v1 + ... + xk * vk
Parameters:
subspaceSubspace
centerPoint or numpy.ndarray of shape (k,) or (k+1,)

Where k is the ambient dimension of the subspace. Point must lie in subspace. Can be given as Point object or as array containing affine or homogeneous coordinates.

Returns:
Subspace

The same subspace with the regularized basis.

Raises:
ValueError
  • If center does not lie in the subspace.

  • If subspace is at infinity.

ddg.geometry.subspaces.dehomogenize_subspace(subspace)[source]

Normalize last entries of basis vectors not at infinity to 1.

Parameters:
subspaceSubspace
Returns:
Subspace

The same subspace with normalized basis vectors.

ddg.geometry.subspaces.whole_space(dimension, **kwargs)[source]

Create whole space of a certain dimension as a trivial subspace.

Parameters:
Dimensionint

Dimension of the space.

**kwargs

Keyword arguments other than points to be passed to Subspace.

Returns:
ddg.geometry.subspaces.Subspace

See also

Subspace
ddg.geometry.subspaces.coordinate_hyperplane(n, zero_component=-1, origin_index=-1)[source]

“Equatorial plane” in n-dimensional space.

Returns the coordinate hyperplane {x_i = 0}, where i=zero_component.

Parameters:
nint

Ambient dimension

zero_componentint (default=-1)

Which component should be 0 in this hyperplane in affine coordinates.

origin_indexint (default=-1)

Where to insert the “origin” (the point not at infinity)

Returns:
Subspace
ddg.geometry.subspaces.join_subspaces(subspace1, subspace2)[source]

Construct the join of two subspaces.

Parameters:
subspace1ddg.geometry.subspaces.Subspace
subspace2ddg.geometry.subspaces.Subspace
Returns:
ddg.geometry.subspaces.Subspace
Raises:
ValueError

If ambient_dimension of the subspaces does not match.

See also

ddg.geometry.intersection.join

To join an arbitrary number of subspaces and other objects.

ddg.geometry.subspaces.intersect_subspaces(subspace1, subspace2)[source]

Construct the intersection of two linear subspaces.

Parameters:
subspace1ddg.geometry.subspaces.Subspace
subspace2ddg.geometry.subspaces.Subspace
Returns:
ddg.geometry.subspaces.Subspace
Raises:
ValueError

If ambient_dimension of the subspaces does not match.

See also

ddg.geometry.intersection.intersect

To intersect an arbitrary number of subspaces and other objects.

ddg.geometry.subspaces.least_square_subspace(points, k)[source]

Computes the k-dimensional subspace closest to the affine coordinates of N points.

Parameters:
pointssequence of ddg.geometry.subspaces.Point

Points containing homogeneous coordinates.

kint

Dimension of the subspace.

Returns:
subspaceddg.geometry.subspaces.Subspace

k-dimensional projective subspace.

ddg.geometry.subspaces.least_square_subspace_from_affine_points(points, k)[source]

Computes the k-dimensional subspace closest to N affine points. See below for more details.

Parameters:
pointssequence of numpy.ndarray, each of shape (n,)

Affine coordinates of N points.

kint

Dimension of the subspace.

Returns:
subspaceddg.geometry.subspaces.Subspace

k-dimensional projective subspace.

Raises:
ValueError

If k is strictly greater than the ambient projective dimension n.

Notes

The returned subspace is best-fitting k-dimensional subspace to the N given points in the sense that it minimizes the sum of the squares of the Euclidean distances of the points to it.

ddg.geometry.subspaces.reflect_in_hyperplane(subspace, hyperplane)[source]

Reflects a subspace in a hyperplane.

Parameters:
subspaceSubspace

Subspace to reflect in the hyperplane.

hyperplaneSubspace

Hyperplane in n-dimensional ambient space.

Returns:
reflected_hyperplaneSubspace

The reflected subspace.

Raises:
ValueError

if the reflecor is not a hyperplane, if the hyperplane is at infinity, or if the ambient dimensions don’t match.