Curves in Manifolds¶
Given a differentiable manifold , a differentiable curve curve in
is a differentiable mapping
where is an interval of
.
Differentiable curves are implemented by DifferentiableCurve
.
AUTHORS:
- Eric Gourgoulhon (2015): initial version
- Travis Scrimshaw (2016): review tweaks
REFERENCES:
- Chap. 1 of [KN1963]
- Chap. 3 of [Lee2013]
-
class
sage.manifolds.differentiable.curve.
DifferentiableCurve
(parent, coord_expression=None, name=None, latex_name=None, is_isomorphism=False, is_identity=False)¶ Bases:
sage.manifolds.differentiable.diff_map.DiffMap
Curve in a differentiable manifold.
Given a differentiable manifold
, a differentiable curve in
is a differentiable map
where
is an interval of
.
INPUT:
parent
–DifferentiableCurveSet
the set of curvesto which the curve belongs
coord_expression
– (default:None
) dictionary (possibly empty) of the functions of the curve parameterexpressing the curve in various charts of
, the keys of the dictionary being the charts and the values being lists or tuples of
symbolic expressions of
, where
is the dimension of
name
– (default:None
) string; symbol given to the curvelatex_name
– (default:None
) string; LaTeX symbol to denote the the curve; if none is provided,name
will be usedis_isomorphism
– (default:False
) determines whether the constructed object is a diffeomorphism; if set toTrue
, thenmust have dimension one
is_identity
– (default:False
) determines whether the constructed object is the identity map; if set toTrue
, thenmust be the interval
EXAMPLES:
The lemniscate of Gerono in the 2-dimensional Euclidean plane:
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: t = var('t') sage: c = M.curve({X: [sin(t), sin(2*t)/2]}, (t, 0, 2*pi), name='c') ; c Curve c in the 2-dimensional differentiable manifold M sage: type(c) <class 'sage.manifolds.differentiable.curve.DifferentiableCurveSet_with_category.element_class'>
Instead of declaring the parameter
as a symbolic variable by means of
var('t')
, it is equivalent to get it as the canonical coordinate of the real number line (seeRealLine
):sage: R.<t> = RealLine() sage: c = M.curve({X: [sin(t), sin(2*t)/2]}, (t, 0, 2*pi), name='c') ; c Curve c in the 2-dimensional differentiable manifold M
A graphical view of the curve is provided by the method
plot()
:sage: c.plot(aspect_ratio=1) Graphics object consisting of 1 graphics primitive
Curves are considered as (manifold) morphisms from real intervals to differentiable manifolds:
sage: c.parent() Set of Morphisms from Real interval (0, 2*pi) to 2-dimensional differentiable manifold M in Join of Category of subobjects of sets and Category of smooth manifolds over Real Field with 53 bits of precision sage: I = R.open_interval(0, 2*pi) sage: c.parent() is Hom(I, M) True sage: c.domain() Real interval (0, 2*pi) sage: c.domain() is I True sage: c.codomain() 2-dimensional differentiable manifold M
Accordingly, all methods of
DiffMap
are available for them. In particular, the methoddisplay()
shows the coordinate representations in various charts of manifoldM
:sage: c.display() c: (0, 2*pi) --> M t |--> (x, y) = (sin(t), 1/2*sin(2*t))
Another map method is using the usual call syntax, which returns the image of a point in the curve’s domain:
sage: t0 = pi/2 sage: I(t0) Point on the Real number line R sage: c(I(t0)) Point on the 2-dimensional differentiable manifold M sage: c(I(t0)).coord(X) (1, 0)
For curves, the value of the parameter, instead of the corresponding point in the real line manifold, can be passed directly:
sage: c(t0) Point c(1/2*pi) on the 2-dimensional differentiable manifold M sage: c(t0).coord(X) (1, 0) sage: c(t0) == c(I(t0)) True
Instead of a dictionary of coordinate expressions, the curve can be defined by a single coordinate expression in a given chart:
sage: c = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), chart=X, name='c') ; c Curve c in the 2-dimensional differentiable manifold M sage: c.display() c: (0, 2*pi) --> M t |--> (x, y) = (sin(t), 1/2*sin(2*t))
Since
X
is the default chart onM
, it can be omitted:sage: c = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c') ; c Curve c in the 2-dimensional differentiable manifold M sage: c.display() c: (0, 2*pi) --> M t |--> (x, y) = (sin(t), 1/2*sin(2*t))
Note that a curve in
can also be created as a differentiable map
:
sage: c1 = I.diff_map(M, coord_functions={X: [sin(t), sin(2*t)/2]}, ....: name='c') ; c1 Curve c in the 2-dimensional differentiable manifold M sage: c1.parent() is c.parent() True sage: c1 == c True
LaTeX symbols representing a curve:
sage: c = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi)) sage: latex(c) \mbox{Curve in the 2-dimensional differentiable manifold M} sage: c = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c') sage: latex(c) c sage: c = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c', ....: latex_name=r'\gamma') sage: latex(c) \gamma
The curve’s tangent vector field (velocity vector):
sage: v = c.tangent_vector_field() ; v Vector field c' along the Real interval (0, 2*pi) with values on the 2-dimensional differentiable manifold M sage: v.display() c' = cos(t) d/dx + (2*cos(t)^2 - 1) d/dy
Plot of the curve and its tangent vector field:
sage: show(c.plot(thickness=2, aspect_ratio=1) + ....: v.plot(chart=X, number_values=17, scale=0.5))
Value of the tangent vector field at
:
sage: v.at(R(pi)) Tangent vector c' at Point on the 2-dimensional differentiable manifold M sage: v.at(R(pi)) in M.tangent_space(c(R(pi))) True sage: v.at(R(pi)).display() c' = -d/dx + d/dy
Curves
can be composed: the operator
is given by
*
:sage: f = R.curve(t^2, (t,-oo,+oo)) sage: g = R.curve(cos(t), (t,-oo,+oo)) sage: s = g*f ; s Differentiable map from the Real number line R to itself sage: s.display() R --> R t |--> cos(t^2) sage: s = f*g ; s Differentiable map from the Real number line R to itself sage: s.display() R --> R t |--> cos(t)^2
-
coord_expr
(chart=None)¶ Return the coordinate functions expressing the curve in a given chart.
INPUT:
chart
– (default:None
) chart on the curve’s codomain; ifNone
, the codomain’s default chart is assumed
OUTPUT:
- symbolic expression representing the curve in the above chart
EXAMPLES:
Cartesian and polar expression of a curve in the Euclidean plane:
sage: M = Manifold(2, 'R^2', r'\RR^2') # the Euclidean plane R^2 sage: c_xy.<x,y> = M.chart() # Cartesian coordinate on R^2 sage: U = M.open_subset('U', coord_def={c_xy: (y!=0, x<0)}) # the complement of the segment y=0 and x>0 sage: c_cart = c_xy.restrict(U) # Cartesian coordinates on U sage: c_spher.<r,ph> = U.chart(r'r:(0,+oo) ph:(0,2*pi):\phi') # spherical coordinates on U sage: # Links between spherical coordinates and Cartesian ones: sage: ch_cart_spher = c_cart.transition_map(c_spher, [sqrt(x*x+y*y), atan2(y,x)]) sage: ch_cart_spher.set_inverse(r*cos(ph), r*sin(ph)) sage: R.<t> = RealLine() sage: c = U.curve({c_spher: (1,t)}, (t, 0, 2*pi), name='c') sage: c.coord_expr(c_spher) (1, t) sage: c.coord_expr(c_cart) (cos(t), sin(t))
Since
c_cart
is the default chart onU
, it can be omitted:sage: c.coord_expr() (cos(t), sin(t))
Cartesian expression of a cardiod:
sage: c = U.curve({c_spher: (2*(1+cos(t)), t)}, (t, 0, 2*pi), name='c') sage: c.coord_expr(c_cart) (2*cos(t)^2 + 2*cos(t), 2*(cos(t) + 1)*sin(t))
-
plot
(chart=None, ambient_coords=None, mapping=None, prange=None, include_end_point=(True, True), end_point_offset=(0.001, 0.001), parameters=None, color='red', style='-', label_axes=True, aspect_ratio='automatic', max_range=8, plot_points=75, thickness=1, **kwds)¶ Plot the current curve in a Cartesian graph based on the coordinates of some ambient chart.
The curve is drawn in terms of two (2D graphics) or three (3D graphics) coordinates of a given chart, called hereafter the ambient chart. The ambient chart’s domain must overlap with the curve’s codomain or with the codomain of the composite curve
, where
is the current curve and
some manifold differential map (argument
mapping
below).INPUT:
chart
– (default:None
) the ambient chart (see above); ifNone
, the default chart of the codomain of the curve (or of the curve composed with) is used
ambient_coords
– (default:None
) tuple containing the 2 or 3 coordinates of the ambient chart in terms of which the plot is performed; ifNone
, all the coordinates of the ambient chart are consideredmapping
– (default:None
) differentiable mapping(instance of
DiffMap
) providing the link between the curve and the ambient chartchart
(cf. above); ifNone
, the ambient chart is supposed to be defined on the codomain of the curve.prange
– (default:None
) range of the curve parameter for the plot; ifNone
, the entire parameter range declared during the curve construction is considered (with -Infinity replaced by-max_range
and +Infinity bymax_range
)include_end_point
– (default:(True, True)
) determines whether the end points ofprange
are included in the plotend_point_offset
– (default:(0.001, 0.001)
) offsets from the end points when they are not included in the plot: ifinclude_end_point[0] == False
, the minimal value of the curve parameter used for the plot isprange[0] + end_point_offset[0]
, while ifinclude_end_point[1] == False
, the maximal value isprange[1] - end_point_offset[1]
.max_range
– (default: 8) numerical value substituted to +Infinity if the latter is the upper bound of the parameter range; similarly-max_range
is the numerical valued substituted for -Infinityparameters
– (default:None
) dictionary giving the numerical values of the parameters that may appear in the coordinate expression of the curvecolor
– (default: ‘red’) color of the drawn curvestyle
– (default: ‘-‘) color of the drawn curve; NB:style
is effective only for 2D plotsthickness
– (default: 1) thickness of the drawn curveplot_points
– (default: 75) number of points to plot the curvelabel_axes
– (default:True
) boolean determining whether the labels of the coordinate axes ofchart
shall be added to the graph; can be set toFalse
if the graph is 3D and must be superposed with another graph.aspect_ratio
– (default:'automatic'
) aspect ratio of the plot; the default value ('automatic'
) applies only for 2D plots; for 3D plots, the default value is1
instead
OUTPUT:
- a graphic object, either an instance of
Graphics
for a 2D plot (i.e. based on 2 coordinates ofchart
) or an instance ofGraphics3d
for a 3D plot (i.e. based on 3 coordinates ofchart
)
EXAMPLES:
Plot of the lemniscate of Gerono:
sage: R2 = Manifold(2, 'R^2') sage: X.<x,y> = R2.chart() sage: R.<t> = RealLine() sage: c = R2.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c') sage: c.plot() # 2D plot Graphics object consisting of 1 graphics primitive
Plot for a subinterval of the curve’s domain:
sage: c.plot(prange=(0,pi)) Graphics object consisting of 1 graphics primitive
Plot with various options:
sage: c.plot(color='green', style=':', thickness=3, aspect_ratio=1) Graphics object consisting of 1 graphics primitive
Plot via a mapping to another manifold: loxodrome of a sphere viewed in
:
sage: S2 = Manifold(2, 'S^2') sage: U = S2.open_subset('U') sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') sage: R3 = Manifold(3, 'R^3') sage: X3.<x,y,z> = R3.chart() sage: F = S2.diff_map(R3, {(XS, X3): [sin(th)*cos(ph), ....: sin(th)*sin(ph), cos(th)]}, name='F') sage: F.display() F: S^2 --> R^3 on U: (th, ph) |--> (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th)) sage: c = S2.curve([2*atan(exp(-t/10)), t], (t, -oo, +oo), name='c') sage: graph_c = c.plot(mapping=F, max_range=40, ....: plot_points=200, thickness=2, label_axes=False) # 3D plot sage: graph_S2 = XS.plot(X3, mapping=F, number_values=11, color='black') # plot of the sphere sage: show(graph_c + graph_S2) # the loxodrome + the sphere
Example of use of the argument
parameters
: we define a curve with some symbolic parametersa
andb
:sage: a, b = var('a b') sage: c = R2.curve([a*cos(t) + b, a*sin(t)], (t, 0, 2*pi), name='c')
To make a plot, we set spectific values for
a
andb
by means of the Python dictionaryparameters
:sage: c.plot(parameters={a: 2, b: -3}, aspect_ratio=1) Graphics object consisting of 1 graphics primitive
-
tangent_vector_field
(name=None, latex_name=None)¶ Return the tangent vector field to the curve (velocity vector).
INPUT:
name
– (default:None
) string; symbol given to the tangent vector field; if none is provided, the primed curve symbol (if any) will be usedlatex_name
– (default:None
) string; LaTeX symbol to denote the tangent vector field; ifNone
then (i) ifname
isNone
as well, the primed curve LaTeX symbol (if any) will be used or (ii) ifname
is notNone
,name
will be used
OUTPUT:
- the tangent vector field, as an instance of
VectorField
EXAMPLES:
Tangent vector field to a circle curve in
:
sage: M = Manifold(2, 'R^2') sage: X.<x,y> = M.chart() sage: R.<t> = RealLine() sage: c = M.curve([cos(t), sin(t)], (t, 0, 2*pi), name='c') sage: v = c.tangent_vector_field() ; v Vector field c' along the Real interval (0, 2*pi) with values on the 2-dimensional differentiable manifold R^2 sage: v.display() c' = -sin(t) d/dx + cos(t) d/dy sage: latex(v) {c'} sage: v.parent() Free module X((0, 2*pi),c) of vector fields along the Real interval (0, 2*pi) mapped into the 2-dimensional differentiable manifold R^2
Value of the tangent vector field for some specific value of the curve parameter (
):
sage: R(pi) in c.domain() # pi in (0, 2*pi) True sage: vp = v.at(R(pi)) ; vp Tangent vector c' at Point on the 2-dimensional differentiable manifold R^2 sage: vp.parent() is M.tangent_space(c(R(pi))) True sage: vp.display() c' = -d/dy
Tangent vector field to a curve in a non-parallelizable manifold (the 2-sphere
): first, we introduce the 2-sphere:
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2 sage: U = M.open_subset('U') # complement of the North pole sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole sage: V = M.open_subset('V') # complement of the South pole sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole sage: M.declare_union(U,V) # S^2 is the union of U and V sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)), ....: intersection_name='W', restrictions1= x^2+y^2!=0, ....: restrictions2= u^2+v^2!=0) sage: uv_to_xy = xy_to_uv.inverse() sage: W = U.intersection(V) sage: A = W.open_subset('A', coord_def={c_xy.restrict(W): (y!=0, x<0)}) sage: c_spher.<th,ph> = A.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') # spherical coordinates sage: spher_to_xy = c_spher.transition_map(c_xy.restrict(A), ....: (sin(th)*cos(ph)/(1-cos(th)), sin(th)*sin(ph)/(1-cos(th))) ) sage: spher_to_xy.set_inverse(2*atan(1/sqrt(x^2+y^2)), atan2(y, x), check=False)
Then we define a curve (a loxodrome) by its expression in terms of spherical coordinates and evaluate the tangent vector field:
sage: R.<t> = RealLine() sage: c = M.curve({c_spher: [2*atan(exp(-t/10)), t]}, (t, -oo, +oo), ....: name='c') ; c Curve c in the 2-dimensional differentiable manifold M sage: vc = c.tangent_vector_field() ; vc Vector field c' along the Real number line R with values on the 2-dimensional differentiable manifold M sage: vc.parent() Module X(R,c) of vector fields along the Real number line R mapped into the 2-dimensional differentiable manifold M sage: vc.display(c_spher.frame().along(c.restrict(R,A))) c' = -1/5*e^(1/10*t)/(e^(1/5*t) + 1) d/dth + d/dph