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.DiffMapCurve in a differentiable manifold.
Given a differentiable manifold
, a differentiable curve in
is a differentiable map
where
is an interval of
.INPUT:
parent–DifferentiableCurveSetthe set of curves
to which the curve belongscoord_expression– (default:None) dictionary (possibly empty) of the functions of the curve parameter
expressing 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,namewill be usedis_isomorphism– (default:False) determines whether the constructed object is a diffeomorphism; if set toTrue, then
must have dimension oneis_identity– (default:False) determines whether the constructed object is the identity map; if set toTrue, then
must 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
DiffMapare 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
Xis 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_cartis 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
mappingbelow).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 usedambient_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_rangeand +Infinity bymax_range)include_end_point– (default:(True, True)) determines whether the end points ofprangeare 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_rangeis 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:styleis 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 ofchartshall be added to the graph; can be set toFalseif 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 is1instead
OUTPUT:
- a graphic object, either an instance of
Graphicsfor a 2D plot (i.e. based on 2 coordinates ofchart) or an instance ofGraphics3dfor 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 parametersaandb: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
aandbby 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; ifNonethen (i) ifnameisNoneas well, the primed curve LaTeX symbol (if any) will be used or (ii) ifnameis notNone,namewill 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
