{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {},
  "_ordered_sections": [],
  "item_file": null,
  "item_line": null,
  "item_type": null,
  "aliases": [],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": null,
  "references": null,
  "qa": "tutorial:interpolate:splines_and_polynomials",
  "arbitrary": [
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Target",
          "__tag": 4061,
          "label": "tutorial-interpolate_splines_and_poly"
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "1D interpolation routines "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "discussed in the previous section",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "tutorial:interpolate:1D"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", work by constructing certain "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "piecewise\npolynomials"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ": the interpolation range is split into intervals by the so-called "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "breakpoints"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and there is a certain polynomial on each interval. These polynomial pieces then match at the breakpoints with a predefined smoothness: the second derivatives for cubic splines, the first derivatives for monotone interpolants and so on."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "A polynomial of degree "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " can be thought of as a linear combination of "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k+1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " monomial basis elements, "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "1, x, x^2, \\cdots, x^k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ".  In some applications, it is useful to consider alternative (if formally equivalent) bases. Two popular bases, implemented in "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "scipy.interpolate",
              "reference": {
                "__type": "RefInfo",
                "__tag": 4000,
                "module": "scipy",
                "version": "*",
                "kind": "api",
                "path": "scipy.interpolate"
              },
              "kind": "module"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " are B-splines ("
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ") and Bernstein polynomials ("
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "). B-splines are often used for, for example, non-parametric regression problems, and Bernstein polynomials are used for constructing Bezier curves."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " objects represent piecewise polynomials in the 'usual' power basis. This is the case for "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "CubicSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " instances and monotone interpolants. In general, "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " objects can represent polynomials of  arbitrary orders, not only cubics. For the data array "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", breakpoints are at the data points, and the array of coefficients, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " , define polynomials of degree "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", such that "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c[i, j]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is a coefficient for "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "(x - x[j])**(k-i)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " on the segment between "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x[j]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x[j+1]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " ."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " objects represent B-spline functions --- linear combinations of "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "b-spline basis elements",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "tutorial:interpolate:splines_and_polynomials"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ".  These objects can be instantiated directly or constructed from data with the "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "make_interp_spline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " factory function."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Finally, Bernstein polynomials are represented as instances of the "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " class."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "All these classes implement a (mostly) similar interface, "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " being the most feature-complete. We next consider the main features of this interface and discuss some details of the alternative bases for piecewise polynomials."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Piecewise polynomials and splines"
        }
      ],
      "level": 0,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " objects have convenient methods for constructing derivatives and antiderivatives, computing integrals and root-finding. For example, we tabulate the sine function and find the roots of its derivative."
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> import numpy as np\n>>> from scipy.interpolate import CubicSpline\n>>> x = np.linspace(0, 10, 71)\n>>> y = np.sin(x)\n>>> spl = CubicSpline(x, y)",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Now, differentiate the spline:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> dspl = spl.derivative()",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Here "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "dspl"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " instance which represents a polynomial approximation to the derivative of the original object, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "spl"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " . Evaluating "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "dspl"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " at a fixed argument is equivalent to evaluating the original spline with the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "nu=1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " argument:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> dspl(1.1), spl(1.1, nu=1)\n(0.45361436, 0.45361436)",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Note that the second form above evaluates the derivative in place, while with the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "dspl"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " object, we can find the zeros of the derivative of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "spl"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> dspl.roots() / np.pi\narray([-0.45480801,  0.50000034,  1.50000099,  2.5000016 ,  3.46249993])",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This agrees well with roots "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "\\pi/2 + \\pi\\,n"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " of "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "\\cos(x) = \\sin'(x)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". Note that by default it computed the roots "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "extrapolated"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " to the outside of the interpolation interval "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "0 \\leqslant x \\leqslant 10"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and that the extrapolated results (the first and last values) are much less accurate. We can switch off the extrapolation and limit the root-finding to the interpolation interval:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> dspl.roots(extrapolate=False) / np.pi\narray([0.50000034,  1.50000099,  2.5000016])",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In fact, the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "root"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " method is a special case of a more general "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "solve"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " method which finds for a given constant "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " the solutions of the equation "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "f(x) = y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " , where "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "f(x)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is the piecewise polynomial:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> dspl.solve(0.5, extrapolate=False) / np.pi\narray([0.33332755, 1.66667195, 2.3333271])",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "which agrees well with the expected values of  "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "\\pm\\arccos(1/2) + 2\\pi\\,n"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Integrals of piecewise polynomials can be computed using the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": ".integrate"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " method which accepts the lower and the upper limits of integration. As an example, we compute an approximation to the complete elliptic integral "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "K(m) = \\int_0^{\\pi/2} [1 - m\\sin^2 x]^{-1/2} dx"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> from scipy.special import ellipk\n>>> m = 0.5\n>>> ellipk(m)\n1.8540746773013719",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "To this end, we tabulate the integrand and interpolate it using the monotone PCHIP interpolant (we could as well used a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "CubicSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "):"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> from scipy.interpolate import PchipInterpolator\n>>> x = np.linspace(0, np.pi/2, 70)\n>>> y = (1 - m*np.sin(x)**2)**(-1/2)\n>>> spl = PchipInterpolator(x, y)",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "and integrate"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> spl.integrate(0, np.pi/2)\n1.854074674965991",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "which is indeed close to the value computed by "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "scipy.special.ellipk",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "All piecewise polynomials can be constructed with N-dimensional "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " values. If "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "y.ndim > 1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", it is understood as a stack of 1D "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " values, which are arranged along the interpolation axis (with the default value of 0). The latter is specified via the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "axis"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " argument, and the invariant is that "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "len(x) == y.shape[axis]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". As an example, we extend the elliptic integral example above to compute the approximation for a range of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "m"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " values, using the NumPy broadcasting:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> from scipy.interpolate import PchipInterpolator\n>>> m = np.linspace(0, 0.9, 11)\n>>> x = np.linspace(0, np.pi/2, 70)\n>>> y = 1 / np.sqrt(1 - m[:, None]*np.sin(x)**2)\n\nNow the ``y`` array has the shape ``(11, 70)``, so that the values of ``y``\nfor fixed value of ``m`` are along the second axis of the ``y`` array.\n\n>>> spl = PchipInterpolator(x, y, axis=1)  # the default is axis=0\n>>> import matplotlib.pyplot as plt\n>>> plt.plot(m, spl.integrate(0, np.pi/2), '--')\n\n>>> from scipy.special import ellipk\n>>> plt.plot(m, ellipk(m), 'o')\n>>> plt.legend(['`ellipk`', 'integrated piecewise polynomial'])\n>>> plt.show()",
          "execution_status": null
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Manipulating "
        },
        {
          "__type": "InlineRole",
          "__tag": 4003,
          "value": "PPoly",
          "domain": null,
          "role": null,
          "inventory": null
        },
        {
          "__type": "Text",
          "__tag": 4046,
          "value": " objects"
        }
      ],
      "level": 1,
      "target": "tutorial-interpolate_ppoly"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "A b-spline function --- for instance, constructed from data via a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "make_interp_spline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " call --- is defined by the so-called "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "knots"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and coefficients."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "As an illustration, let us again construct the interpolation of a sine function.  The knots are available as the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "t"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " attribute of a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " instance:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> x = np.linspace(0, 3/2, 7)\n>>> y = np.sin(np.pi*x)\n>>> from scipy.interpolate import make_interp_spline\n>>> bspl = make_interp_spline(x, y, k=3)\n>>> print(bspl.t)\n[0.  0.  0.  0.        0.5  0.75  1.        1.5  1.5  1.5  1.5 ]\n>>> print(x)\n[            0.  0.25  0.5  0.75  1.  1.25  1.5 ]",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "We see that the knot vector by default is constructed from the input array "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ": first, it is made "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "(k+1)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " -regular (it has "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " repeated knots appended and prepended); then, the second and second-to-last points of the input array are removed---this is the so-called "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "not-a-knot"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " boundary condition."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In general, an interpolating spline of degree "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " needs "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "len(t) - len(x) - k - 1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " boundary conditions. For cubic splines with "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "(k+1)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "-regular knot arrays this means two boundary conditions---or removing two values from the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " array. Various boundary conditions can be requested using the optional "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "bc_type"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " argument of "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "make_interp_spline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The b-spline coefficients are accessed via the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " attribute of a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " object:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> len(bspl.c)\n7",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The convention is that for "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "len(t)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " knots there are "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "len(t) - k - 1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " coefficients. Some routines (see the "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "Smoothing splines section",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "tutorial:interpolate:smoothing_splines"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ") zero-pad the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " arrays so that "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "len(c) == len(t)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". These additional coefficients are ignored for evaluation."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "We stress that the coefficients are given in the "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "b-spline basis",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "tutorial:interpolate:splines_and_polynomials"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", not the power basis of "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "1, x, \\cdots, x^k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "B-splines: knots and coefficients"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The b-spline basis is used in a variety of applications which include interpolation, regression and curve representation. B-splines are piecewise polynomials, represented as linear combinations of "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "b-spline basis elements"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " --- which themselves are certain linear combinations of usual monomials, "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x^m"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " with "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "m=0, 1, \\dots, k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The properties of b-splines are well described in the literature (see, for example, references listed in the "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " docstring). For our purposes, it is enough to know that a b-spline function is uniquely defined by an array of coefficients and an array of the so-called "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "knots"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", which may or may not coincide with the data points, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Specifically, a b-spline basis element of degree "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (e.g. "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "k=3"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for cubics) is defined by "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k+2"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " knots and is zero outside of these knots. To illustrate, plot a collection of non-zero basis elements on a certain interval:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> k = 3      # cubic splines\n>>> t = [0., 1.4, 2., 3.1, 5.]   # internal knots\n>>> t = np.r_[[0]*k, t, [5]*k]   # add boundary knots\n\n>>> from scipy.interpolate import BSpline\n>>> import matplotlib.pyplot as plt\n>>> for j in [-2, -1, 0, 1, 2]:\n...     a, b = t[k+j], t[-k+j-1]\n...     xx = np.linspace(a, b, 101)\n...     bspl = BSpline.basis_element(t[k+j:-k+j])\n...     plt.plot(xx, bspl(xx), label=f'j = {j}')\n>>> plt.legend(loc='best')\n>>> plt.show()",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Here "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline.basis_element",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is essentially a shorthand for constructing a spline with only a single non-zero coefficient. For instance, the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "j=2"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " element in the above example is equivalent to"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> c = np.zeros(t.size - k - 1)\n>>> c[-2] = 1\n>>> b = BSpline(t, c, k)\n>>> np.allclose(b(xx), bspl(xx))\nTrue",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "If desired, a b-spline can be converted into a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " object using "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly.from_spline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " method which accepts a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " instance and returns a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " instance. The reverse conversion is performed by the "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline.from_power_basis",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " method. However, conversions between bases is best avoided because it accumulates rounding errors."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "B-spline basis elements"
        }
      ],
      "level": 2,
      "target": "tutorial-interpolate_bspl_basis"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "One common application of b-splines is in non-parametric regression. The reason is that the localized nature of the b-spline basis elements makes linear algebra banded. This is because at most "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k+1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " basis elements are non-zero at a given evaluation point, thus a design matrix built on b-splines has at most "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k+1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " diagonals."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "As an illustration, we consider a toy example. Suppose our data are one-dimensional and are confined to an interval "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "[0, 6]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". We construct a 4-regular knot vector which corresponds to 7 data points and cubic, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "k=3"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", splines:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> t = [0., 0., 0., 0., 2., 3., 4., 6., 6., 6., 6.]",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Next, take 'observations' to be"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> xnew = [1, 2, 3]",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "and construct the design matrix in the sparse CSR format"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> from scipy.interpolate import BSpline\n>>> mat = BSpline.design_matrix(xnew, t, k=3)\n>>> mat\n<Compressed Sparse Row sparse array of dtype 'float64'\n\twith 12 stored elements and shape (3, 7)>",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Here each row of the design matrix corresponds to a value in the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "xnew"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " array, and a row has no more than "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "k+1 = 4"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " non-zero elements; row "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "j"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " contains basis elements evaluated at "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "xnew[j]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> with np.printoptions(precision=3):\n...     print(mat.toarray())\n[[0.125 0.514 0.319 0.042 0.    0.    0.   ]\n [0.    0.111 0.556 0.333 0.    0.    0.   ]\n [0.    0.    0.125 0.75  0.125 0.    0.   ]]",
          "execution_status": null
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Design matrices in the B-spline basis"
        }
      ],
      "level": 2,
      "target": "tutorial-interpolate_bspl_design_matrix"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "t \\in [0, 1]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", Bernstein basis polynomials of degree "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " are defined via"
            }
          ]
        },
        {
          "__type": "Math",
          "__tag": 4058,
          "value": "b(t; k, a) = C_k^a t^a (1-t)^{k - a}"
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "where "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "C_k^a"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is the binomial coefficient, and "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "a=0, 1, \\dots, k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", so that there are "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k+1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " basis polynomials of degree "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "A "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "BPoly"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " object represents a "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "piecewise"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " Bernstein polynomial in terms of breakpoints, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and coefficients, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ": "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c[a, j]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " gives the coefficient for "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "b(t; k, a)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "t"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " on the interval between "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x[j]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x[j+1]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The user interface of "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " objects is very similar to that of "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " objects: both can be evaluated, differentiated and integrated."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "One additional feature of "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " objects is the alternative constructor, "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly.from_derivatives",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", which constructs a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " object from data values and derivatives. Specifically, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "b = BPoly.from_derivatives(x, y)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " returns a callable that interpolates the provided values, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "b(x[i]) == y[i])"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and has the provided derivatives, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "b(x[i], nu=j) == y[i][j]"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This operation is similar to "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "CubicHermiteSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", but it is more flexible in that it can handle varying numbers of derivatives at different data points; i.e., the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " argument can be a list of arrays of different lengths. See "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly.from_derivatives",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for further discussion and examples."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Bernstein polynomials, "
        },
        {
          "__type": "InlineCode",
          "__tag": 4051,
          "value": "BPoly"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In principle, all three bases for piecewise polynomials (the power basis, the Bernstein basis, and b-splines) are equivalent, and a polynomial in one basis can be converted into a different basis. One reason for converting between bases is that not all bases implement all operations. For instance, root-finding is only implemented for "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and therefore to find roots of a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " object, you need to convert to "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " first. See methods "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly.from_bernstein_basis",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PPoly.from_spline",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BPoly.from_power_basis",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "BSpline.from_power_basis",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for details about conversion."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In floating-point arithmetic, though, conversions always incur some precision loss. Whether this is significant is problem-dependent, so it is therefore recommended to exercise caution when converting between bases."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Conversion between bases"
        }
      ],
      "level": 1,
      "target": null
    }
  ],
  "local_refs": []
}