About the Package ParametrizeCurve

Introduction to the package

Copyright information

Copyright: © 1997 by Steven Wilkinson

What it does

A curve in (ℝ^n)is given implicitly by n - 1equations in n coordinate variables. This package takes such a curve and returns a parametrization for that curve. For instance, given an implicitly defined curve, (Subscript[F, 1])((Subscript[x, 1]),  ... , (Subscript[x, n])) = 0,  ... ,
      (Subscript[F, n - 1])((Subscript[x, 1]),  ... , (Subscript[x, n])) = 0,  the package returns {(Subscript[x, 1])(t),  ... , (Subscript[x, n])(t)} . Moreover, the package will parametrize through nondegenerate singular points, i.e. points on the curve where ∇(Subscript[F, 1])((Subscript[x, 1]),  ... , (Subscript[x, n])),  ... ,
      ∇(Subscript[F, n - 1])((Subscript[x, 1]),  ... , (Subscript[x, n])), the gradients of the generators, form a linearly dependent set. The nondegeneracy assumption is that the gradients must span a vector space of dimension n - 2 and there is an extra assumption on the second derivatives of the generators.

How it works

If (Subscript[F, i]) is a generator for the curve and X(t) is a parametrization of that same curve, then (Subscript[F, i])(X(t)) = 0.  Differentiate this equation to get \(TraditionalForm
      \`∇\(\(F\_i\)(X(t))\)·\(\(X\^′\)(t)\) = 0. \) Therefore, (X^′)(t) is orthogonal to (Subscript[F, i])(X(t)) for i = 1,  ... , n - 1.  This leads to the system of differential equations \(TraditionalForm
      \`\(X\^′\)(t) =
        \(\(λ(t)\) \(\(F\_1\)(X(t))×\) ...
            \)×\(\(F\_\(n - 1\)\)(X(t))\)\) where λ(t) is an arbitrary function whose choice depends on the type of parametrization desired. An initial point of the parametrization provides an initial condition for the system of differential equations.

Parametrizing through nondegenerate singular points is accomplished by working with the second derivatives of the original equation(s), \(TraditionalForm
      \`\(\(\(X\^′\)(t)\)\^T\)
            ∇\^2\(\( F\_i\)(X(t))\)·\(\(X\^′\)(t)\) +
          ∇\(\(F\_i\)(X(t))\)·\(\(X\^″\)(t)\) =
        0. \)

Syntax of the package

Since the package finds the parametrization by solving a system differential equations using NDSolve, the syntax for ParametrizeCurve command is essentially the same as the syntax for NDSolve.

Options for the package

AdjustInitialPoint takes boolean values. If set to True any time the given initial point is not on the curve, the nearest point on the curve to the given point is taken as the initial point. The default value is True.

CheckSingularPoints takes boolean values.If set to False the package doesn't bother to check for singular points. The package runs much faster in this mode than when it does check for singular points. The default value is True.

InitialDirection expresses the general direction in which you wish the parametrization to initially head. The default value is Automatic.

MinNorm expresses the value such that if the norm of the cross product of the gradients of the generators is less than that value the package will automatically assume it needs to switch to the singular point algorithm. The default value is 0.

MaxNorm expresses the value such that if the norm of the cross product of the gradients of the generators is greater than that value the package will automatically assume it need not switch to the singular point algorithm. The default value is Infinity.

ParametrizationSpeed expresses the desired speed for the parametrization. If set to UnitSpeed then the resulting parametrization is a unit speed parametrization. If set to a number the resulting parametrization has constant speed that number. It can also be set to a function, either a pure function or an expression in terms of the parameter. If set to GradientSpeed the parametrization's speed is the same as the norm of the cross product of the gradients of the generators. The default value is UnitSpeed.

VectorNorm expresses the type of vector norm used to measure lengths. It can be Norm[p] which is the standard vector p-norm, or it can be a pure function. The default value is Norm[2].

Any option that NDSolve takes can be used in ParametrizeCurve.

Loading the package

To load the package either open the file ParametrizeCurve.m manually and execute the one cell, or if you place the file ParametrizeCurve.m in the Applications subdirectory of the AddOns directory, then you can load the package by executing the following Needs command.

Needs["ParametrizeCurve`"]

Examples

Plane curves

Hippopede curve (no singular points)

((((x^2) + (y^2)))^2) = (x^2) + 0.9  (y^2)
Initial point (1, 0)

Using the default option CheckSingularPoints->True.

(X[t_] = {x[t], y[t]} /.
            ParametrizeCurve[{(x^2 + y^2)^2 == x^2 + 0.2  y^2, x[0] == 1,
                y[0] == 0}, {x, y}, {t, 0, 6}]) // Timing

ParametricPlot[Evaluate[X[t]], {t, 0, 6}]

Using the option CheckSingularPoints->False. Note the difference in time.

(X[t_] = {x[t], y[t]} /.
            ParametrizeCurve[{(x^2 + y^2)^2 == x^2 + 0.2  y^2, x[0] == 1,
                y[0] == 0}, {x, y}, {t, 0, 6}, CheckSingularPoints -> False])
         // Timing

ParametricPlot[Evaluate[X[t]], {t, 0, 6}]

Lissajous curve (nondegenerate singular point at the origin)

(((1 - 2  (x^2)))^2) + (y^2) = 1

Choose an initial point that is not on the curve. Using the default option AdjustInitialPoint->True.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{(1 - 2  x^2)^2 + y^2 == 1, x[0] == 1,
            y[0] == 1}, {x, y}, {t, 0, 10}]

ParametricPlot[Evaluate[X[t]], {t, 0, 10}]

Same initial point with option AdjustInitialPoint->False produces a parametrization of a slightly different curve.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{(1 - 2  x^2)^2 + y^2 == 1, x[0] == 1,
            y[0] == 1}, {x, y}, {t, 0, 10}, AdjustInitialPoint -> False]

ParametricPlot[Evaluate[X[t]], {t, 0, 10}]

Same initial point with default option CheckSingularPoints->False can give erroneous results.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{(1 - 2  x^2)^2 + y^2 == 1, x[0] == 1,
            y[0] == 1}, {x, y}, {t, 0, 10}, CheckSingularPoints -> False]

ParametricPlot[Evaluate[X[t]], {t, 0, 10}]

Tschirnhausen's curve (nondegenerate singular point at the origin)

(y^2) = (x^2) + (x^3)
Initial point (-1, 0)

Initial direction in the same general direction as the vector (-1, -1).

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{y^2 == x^2 + x^3, x[0] == -1, y[0] == 0}, {x,
            y}, {t, -2, 2}, InitialDirection -> {-1, -1}]

ParametricPlot[Evaluate[X[t]], {t, -2, 2}]

Plot of first component with respect to time.

Plot[Evaluate[First[X[t]]], {t, -2, 2}]

Initial direction in the same general direction as the vector (-1, 1), parametrization speed is  | t | +1.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{y^2 == x^2 + x^3, x[0] == -1, y[0] == 0}, {x,
            y}, {t, -2, 2}, InitialDirection -> {-1, 1},
          ParametrizationSpeed -> (Abs[t] + 1)]

ParametricPlot[Evaluate[X[t]], {t, -2, 2}]

Plot of first component with respect to time.

Plot[Evaluate[First[X[t]]], {t, -2, 2}]

Curves with degenerate singular points at the origin

The algorithm is not built to handle parametrizations through such points. You may or may not get a good parametrization. Generally, the package approximates a curve best around a cusp if you set CheckSingularPoints to False . For other types of degenerate singular points leave the option set to True.

Degenerate singular point at the origin that is not a cusp.
(y^2) = (x^4) + (x^5)
Initial point (-1, 0)

Use default CheckSingularPoints options.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{y^2 == x^4 + x^5, x[0] == -1, y[0] == 0}, {x,
            y}, {t, -2, 2}]

ParametricPlot[Evaluate[X[t]], {t, -2, 2}]

Use  CheckSingularPoints->False.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{y^2 == x^4 + x^5, x[0] == -1, y[0] == 0}, {x,
            y}, {t, -2, 2}, CheckSingularPoints -> False]

ParametricPlot[Evaluate[X[t]], {t, -2, 2}]

Degenerate singular point at the origin that is a cusp.
(y^2) = (x^3)
Initial point (1, -1)

Use default CheckSingularPoints options.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{y^2 == x^3, x[0] == 1, y[0] == 1}, {x, y}, {t,
            -2, 2}]

ParametricPlot[Evaluate[X[t]], {t, -2, 2}]

Use  CheckSingularPoints->False.

X[t_] = {x[t], y[t]} /.
        ParametrizeCurve[{y^2 == x^3, x[0] == 1, y[0] == 1}, {x, y}, {t,
            -2, 2}, CheckSingularPoints -> False]

ParametricPlot[Evaluate[X[t]], {t, -2, 2}]

Space curves

Sine wave on cylinder, no singular points

\(TraditionalForm\`x\^2 + y\^2 = 1,       z = 2 \((x\^2 - y\^2)\)\^2 - 1\)
Initial point (1, 0, 1)

Check for singular points

(X[t_] = {x[t], y[t], z[t]} /.
            ParametrizeCurve[{x^2 + y^2 == 1, z == 2 (x^2 - y^2)^2 - 1,
                x[0] == 1, y[0] == 0, z[0] == 1}, {x, y, z}, {t, 0, 20}])
         // Timing

ParametricPlot3D[Evaluate[X[t]], {t, 0, 20}, PlotPoints -> 500]

Don't check for singular points

(X[t_] = {x[t], y[t], z[t]} /.
            ParametrizeCurve[{x^2 + y^2 == 1, z == 2 (x^2 - y^2)^2 - 1,
                x[0] == 1, y[0] == 0, z[0] == 1}, {x, y, z}, {t, 0, 20},
              CheckSingularPoints -> False]) // Timing

ParametricPlot3D[Evaluate[X[t]], {t, 0, 20}, PlotPoints -> 500]

Intersection of sphere and cylinder (has a singular point at (1,0,0) )

\(TraditionalForm\`x\^2 + y\^2 + z\^2 = 1,       \((2  x - 1)\)\^2 + \((2  y)\)\^2 = 1\)
Initial point (0, 0, 1)

Use default vector 2-norm.

X[t_] = {x[t], y[t], z[t]} /.
        ParametrizeCurve[{x^2 + y^2 + z^2 == 1,
            (2  x - 1)^2 + (2  y)^2 == 1, x[0] == 0, y[0] == 0,
            z[0] == 1}, {x, y, z}, {t, 0, 8}]

ParametricPlot3D[Evaluate[X[t]], {t, 0, 8}]

Plot the first component with respect to t.

Plot[Evaluate[First[X[t]]], {t, 0, 8}]

Use vector infinity-norm.

X[t_] = {x[t], y[t], z[t]} /.
        ParametrizeCurve[{x^2 + y^2 + z^2 == 1,
            (2  x - 1)^2 + (2  y)^2 == 1, x[0] == 0, y[0] == 0,
            z[0] == 1}, {x, y, z}, {t, 0, 8}, VectorNorm -> Norm[Infinity]]

ParametricPlot3D[Evaluate[X[t]], {t, 0, 8}]

Plot the first component with respect to t.

Plot[Evaluate[First[X[t]]], {t, 0, 8}]

Curves in 4-dimensional space

No singular points

\(TraditionalForm\`x\^4 + 2  y\^4 + 3  z\^4 + 4  w\^4 = 10,       w\^3 = x\^3 + y\^3 + z\^3, \ 2  x\ y + z\ w = \(-1\)\)
Initial point (1, -1, 1, 1)

X[t_] = {x[t], y[t], z[t], w[t]} /.
        ParametrizeCurve[{x^4 + 2  y^4 + 3  z^4 + 4  w^4 == 10,
            w^3 == x^3 + y^3 + z^3, 2  x y + z w == -1, x[0] == 1,
            y[0] == -1, z[0] == 1, w[0] == 1}, {x, y, z, w}, {t, 0, 10},
          CheckSingularPoints -> False]

Projected into xyz-space:

ParametricPlot3D[Evaluate[Drop[X[t], {4}]], {t, 0, 10},
      AxesLabel -> {"x", "y", "z"}]

Projected into xyw-space:

ParametricPlot3D[Evaluate[Drop[X[t], {3}]], {t, 0, 10},
      AxesLabel -> {"x", "y", "w"}]

Projected into xzw-space:

ParametricPlot3D[Evaluate[Drop[X[t], {2}]], {t, 0, 10},
      AxesLabel -> {"x", "z", "w"}]

Projected into yzw-space:

ParametricPlot3D[Evaluate[Drop[X[t], {1}]], {t, 0, 10},
      AxesLabel -> {"y", "z", "w"}]

The initial point is a nondegenerate singular point

\(TraditionalForm\`x\^4 + y\^4 + z\^4 + w\^4 = 2,       w\^2 = x\^2 + y\^2 + z\^2, \ \ log(x\^2 + y\^2 + 1) = w - z\)
Initial point (0, 0, 1, 1)

X[t_] = {x[t], y[t], z[t], w[t]} /.
        ParametrizeCurve[{2  x^2 +  y^4  + 2  z^2 + w^4 == 3,
            w^2 == x^2 + y^2 + z^2 - z x, Log[x^2 + y^2 + 1] == w - z,
            x[0] == 0, y[0] == 0, z[0] == 1, w[0] == 1}, {x, y, z, w}, {t, 0,
            10}]

Projected into xyz-space:

ParametricPlot3D[Evaluate[Drop[X[t], {4}]], {t, 0, 10},
      AxesLabel -> {"x", "y", "z"}]

Projected into xyw-space:

ParametricPlot3D[Evaluate[Drop[X[t], {3}]], {t, 0, 10},
      AxesLabel -> {"x", "y", "w"}]

Projected into xzw-space:

ParametricPlot3D[Evaluate[Drop[X[t], {2}]], {t, 0, 10},
      AxesLabel -> {"x", "z", "w"}]

Projected into yzw-space:

ParametricPlot3D[Evaluate[Drop[X[t], {1}]], {t, 0, 10},
      AxesLabel -> {"y", "z", "w"}]

The first  curvature function:

e1[t_] = X'[t];

κ1[t_] = Sqrt[e1'[t] . e1'[t]]

Plot[κ1[t], {t, 0, 10}]

e2[t_] = e1'[t]/κ1[t];

The second curvature function:

κ2 =
      FunctionInterpolation[
        Sqrt[(e2'[t] + κ1[t] e1[t]) .
            (e2'[t] + κ1[t] e1[t])], {t, 0, 10}];

Plot[κ2[t], {t, 0, 10}]

e3[t_] = (e2'[t] + κ1[t] e1[t])/κ2[t];

e4[t_] = Cross[e1[t], e2[t], e3[t]];

κ3 =
      FunctionInterpolation[-First[e4'[t]]/First[e3[t]], {t, 0, 10}];

Plot[κ3[t], {t, 0, 10}]