"""Parametrizations for curves"""
import numpy as np
import ddg
from ddg.math.functions import K, cn, dn, sn
[docs]def circle(t, center, radius=1, normals=None):
"""
Parametrization map of a circle with a given center, radius and list of
normals. The dimensions of the normals must match the dimension of the
center and both must be >= 2.
Parameters
----------
t: float
Parameter for the parametrization.
center: numpy.ndarray of shape (d,)
Center of the circle.
radius: float (default=1)
Radius of the circle.
normals: numpy.ndarray of shape (n,d) (default=None)
Normals of the circle that determine the orthogonal complement of the
subspace containing the circle. If None are given the orthogonal
complement will be determined by the dimension of the center and its
normals consist of unit normal vectors.
These vectors must be linearly independent(!)
Returns
-------
float
Value of a point on the circle at parameter t.
Raises
------
ValueError
If the shapes of center and normals do not match.
If the number of normals is not smaller than the dimension
of the circle center minus 2.
Examples
--------
>>> import numpy as np
>>> from ddg.math.parametrizations import circle
>>> circle(0, (0, 0, 0), radius=1, normals=None)
array([1., 0., 0.])
"""
center = np.array(center)
dim = center.shape[0]
if normals is None:
normals = [ddg.math.linalg.e(i, dim) for i in range(2, dim)]
elif np.ndim(normals) == 1:
normals = np.array([normals])
if not len(normals) < dim - 1:
raise ValueError(
"The number of normals must be smaller than the dimension of the "
"circle center minus 2. The given circle center has dimension "
f"{dim} but {len(normals)} normals were given."
)
v = np.concatenate((np.zeros(dim - 2), [np.cos(t), np.sin(t)]))
v *= radius
if dim > 2:
if np.shape(normals)[1] != dim:
raise ValueError(
"Shapes of center and normal mismatch. The center has "
f"dimension {dim} and the normals have shape "
f"{np.shape(normals)}, which should be (*, {dim})."
)
rot = ddg.math.euclidean.extend_to_onb(normals, index=0)
v = rot @ v
return v + center
[docs]def elliptic_curve_jacobi(u, k):
"""Parametrization for an elliptic curve [cn, sn, dn] for a parameter k."""
return np.array([cn(u, k), sn(u, k), dn(u, k)])
[docs]def elliptic_curve_jacobi_domain(k):
# inf if k == 1
KK = K(k)
if KK < np.inf:
domain = [[-2 * KK, 2 * KK, True]]
else:
domain = [[-KK, KK]]
return domain