
    (phC                    R   S SK r S SKJr  S SKrS SKJr  S SKJrJ	r	J
r
JrJrJr  S SKJr  SSKJr  SSKJr  S S	KJr  S S
KJr  S SKJr  / SQrS rS&S jrS rS r " S S5      rS&S jrS r S r!S r"S r#S r$S r%S r&S'S jr'S r(  S(S jr)S)SS.S  jjr*S! r+S" r,S# r-S*S$ jr.S% r/g)+    N)prod)normalize_axis_index)get_lapack_funcsLinAlgErrorcholesky_bandedcho_solve_bandedsolvesolve_banded)minimize_scalar   )_dierckx)_fitpack_impl)	csr_array)poch)combinations)BSplinemake_interp_splinemake_lsq_splinemake_smoothing_splinec                     [         R                  " U [         R                  5      (       a  [         R                  $ [         R                  $ )z>Return np.complex128 for complex dtypes, np.float64 otherwise.)np
issubdtypecomplexfloating
complex128float64dtypes    N/var/www/html/venv/lib/python3.13/site-packages/scipy/interpolate/_bsplines.py
_get_dtyper      s-    	}}UB..//}}zz    c                     [         R                  " U 5      n [        U R                  5      nU R	                  USS9n U(       a4  [         R
                  " U 5      R                  5       (       d  [        S5      eU $ )zwConvert the input into a C contiguous float array.

NB: Upcasts half- and single-precision floats to double precision.
F)copyz$Array must not contain infs or nans.)r   ascontiguousarrayr   r   astypeisfiniteall
ValueError)xcheck_finitedtyps      r   _as_float_arrayr+      s^    
 	QAaggD	E"ABKKN..00?@@Hr    c           	          US:X  a  g[         R                  " [        SUS-   5       Vs/ s H  oCX U-      -
  PM     sn5      $ s  snf )z
Dual polynomial of the B-spline B_{j,k,t} -
polynomial which is associated with B_{j,k,t}:
$p_{j,k}(y) = (y - t_{j+1})(y - t_{j+2})...(y - t_{j+k})$
r   r   )r   r   range)jktyis        r   
_dual_polyr3   *   sA     	Av77E!QUO<Oqq5\O<==<s   Ac                    US:X  a  [        XXB5      $ X1:X  a  [        SU5      $ [        [        [	        U S-   X-   S-   5      U5      5      nSn[	        [        U5      [        US   5      -  5       HP  nU[        R                  " [	        SUS-   5       Vs/ s H  nX-   XWU-     ;  d  M  X$X-      -
  PM     sn5      -  nMR     U$ s  snf )z5
d-th derivative of the dual polynomial $p_{j,k}(y)$
r   r   )r3   r   listr   r-   lenr   r   )	r.   r/   r1   dr0   combresr2   ps	            r   _diff_dual_polyr;   5   s     	Av!%%vAqzU1q5!%!)4a89D
C3t9s47|+,rwwaQ 61E$!t*4 &quX 6 7 	7 - J6s   C*Cc                      ^  \ rS rSrSrSU 4S jjr\SS j5       r\S 5       r	\SS j5       r
\SS j5       rSS jrS	 rSS
 jrSS jrSS jr\SS j5       rSS jrSrU =r$ )r   E   a4  Univariate spline in the B-spline basis.

.. math::

    S(x) = \sum_{j=0}^{n-1} c_j  B_{j, k; t}(x)

where :math:`B_{j, k; t}` are B-spline basis functions of degree `k`
and knots `t`.

Parameters
----------
t : ndarray, shape (n+k+1,)
    knots
c : ndarray, shape (>=n, ...)
    spline coefficients
k : int
    B-spline degree
extrapolate : bool or 'periodic', optional
    whether to extrapolate beyond the base interval, ``t[k] .. t[n]``,
    or to return nans.
    If True, extrapolates the first and last polynomial pieces of b-spline
    functions active on the base interval.
    If 'periodic', periodic extrapolation is used.
    Default is True.
axis : int, optional
    Interpolation axis. Default is zero.

Attributes
----------
t : ndarray
    knot vector
c : ndarray
    spline coefficients
k : int
    spline degree
extrapolate : bool
    If True, extrapolates the first and last polynomial pieces of b-spline
    functions active on the base interval.
axis : int
    Interpolation axis.
tck : tuple
    A read-only equivalent of ``(self.t, self.c, self.k)``

Methods
-------
__call__
basis_element
derivative
antiderivative
integrate
insert_knot
construct_fast
design_matrix
from_power_basis

Notes
-----
B-spline basis elements are defined via

.. math::

    B_{i, 0}(x) = 1, \textrm{if $t_i \le x < t_{i+1}$, otherwise $0$,}

    B_{i, k}(x) = \frac{x - t_i}{t_{i+k} - t_i} B_{i, k-1}(x)
             + \frac{t_{i+k+1} - x}{t_{i+k+1} - t_{i+1}} B_{i+1, k-1}(x)

**Implementation details**

- At least ``k+1`` coefficients are required for a spline of degree `k`,
  so that ``n >= k+1``. Additional coefficients, ``c[j]`` with
  ``j > n``, are ignored.

- B-spline basis elements of degree `k` form a partition of unity on the
  *base interval*, ``t[k] <= x <= t[n]``.


Examples
--------

Translating the recursive definition of B-splines into Python code, we have:

>>> def B(x, k, i, t):
...    if k == 0:
...       return 1.0 if t[i] <= x < t[i+1] else 0.0
...    if t[i+k] == t[i]:
...       c1 = 0.0
...    else:
...       c1 = (x - t[i])/(t[i+k] - t[i]) * B(x, k-1, i, t)
...    if t[i+k+1] == t[i+1]:
...       c2 = 0.0
...    else:
...       c2 = (t[i+k+1] - x)/(t[i+k+1] - t[i+1]) * B(x, k-1, i+1, t)
...    return c1 + c2

>>> def bspline(x, t, c, k):
...    n = len(t) - k - 1
...    assert (n >= k+1) and (len(c) >= n)
...    return sum(c[i] * B(x, k, i, t) for i in range(n))

Note that this is an inefficient (if straightforward) way to
evaluate B-splines --- this spline class does it in an equivalent,
but much more efficient way.

Here we construct a quadratic spline function on the base interval
``2 <= x <= 4`` and compare with the naive way of evaluating the spline:

>>> from scipy.interpolate import BSpline
>>> k = 2
>>> t = [0, 1, 2, 3, 4, 5, 6]
>>> c = [-1, 2, 0, -1]
>>> spl = BSpline(t, c, k)
>>> spl(2.5)
array(1.375)
>>> bspline(2.5, t, c, k)
1.375

Note that outside of the base interval results differ. This is because
`BSpline` extrapolates the first and last polynomial pieces of B-spline
functions active on the base interval.

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> fig, ax = plt.subplots()
>>> xx = np.linspace(1.5, 4.5, 50)
>>> ax.plot(xx, [bspline(x, t, c ,k) for x in xx], 'r-', lw=3, label='naive')
>>> ax.plot(xx, spl(xx), 'b-', lw=4, alpha=0.7, label='BSpline')
>>> ax.grid(True)
>>> ax.legend(loc='best')
>>> plt.show()


References
----------
.. [1] Tom Lyche and Knut Morken, Spline methods,
    http://www.uio.no/studier/emner/matnat/ifi/INF-MAT5340/v05/undervisningsmateriale/
.. [2] Carl de Boor, A practical guide to splines, Springer, 2001.

c                 b  > [         TU ]  5         [        R                  " U5      U l        [
        R                  " U5      U l        [
        R                  " U[
        R                  S9U l
        US:X  a  X@l        O[        U5      U l        U R                  R                  S   U R                  -
  S-
  n[        XPR                  R                  5      nXPl        US:w  a'  [
        R"                  " U R                  US5      U l        US:  a  [%        S5      eU R                  R                  S:w  a  [%        S5      eX`R                  S-   :  a  [%        SSU-  S-   U4-  5      e[
        R&                  " U R                  5      S:  R)                  5       (       a  [%        S	5      e[+        [
        R,                  " U R                  X6S-    5      5      S:  a  [%        S
5      e[
        R.                  " U R                  5      R1                  5       (       d  [%        S5      eU R                  R                  S:  a  [%        S5      eU R                  R                  S   U:  a  [%        S5      e[3        U R                  R4                  5      n[
        R                  " U R                  US9U l        g )Nr   periodicr   r    Spline order cannot be negative.z$Knot vector must be one-dimensional.z$Need at least %d knots for degree %d   z(Knots must be in a non-decreasing order.z!Need at least two internal knots.z#Knots should not have nans or infs.z,Coefficients must be at least 1-dimensional.z0Knots, coefficients and degree are inconsistent.)super__init__operatorindexr/   r   asarraycr#   r   r0   extrapolateboolshaper   ndimaxismoveaxisr'   diffanyr6   uniquer%   r&   r   r   )	selfr0   rG   r/   rH   rL   ndt	__class__s	           r   rC   BSpline.__init__   s    "A%%arzz:*$*#K0DFFLLOdff$q(#D&&++6 	19 [[q1DFq5?@@66;;!CDDvvz>CcAgq\* + +GGDFFOa$$&&GHHryyA#'(1,@AA{{466"&&((BCC66;;?KLL66<<?QOPP%%%dffB7r    c                 r    [         R                  U 5      nXUsUl        Ul        Ul        XFl        XVl        U$ )zConstruct a spline without making checks.

Accepts same parameters as the regular constructor. Input arrays
`t` and `c` must of correct shape and dtype.
)object__new__r0   rG   r/   rH   rL   )clsr0   rG   r/   rH   rL   rQ   s          r   construct_fastBSpline.construct_fast   s6     ~~c"!"q&	r    c                 H    U R                   U R                  U R                  4$ )z@Equivalent to ``(self.t, self.c, self.k)`` (read-only).
        )r0   rG   r/   rQ   s    r   tckBSpline.tck  s     vvtvvtvv%%r    c                     [        U5      S-
  n[        U5      n[        R                  US   S-
  4U-  XS   S-   4U-  4   n[        R                  " U5      nSXC'   U R                  XX25      $ )a  Return a B-spline basis element ``B(x | t[0], ..., t[k+1])``.

Parameters
----------
t : ndarray, shape (k+2,)
    internal knots
extrapolate : bool or 'periodic', optional
    whether to extrapolate beyond the base interval, ``t[0] .. t[k+1]``,
    or to return nans.
    If 'periodic', periodic extrapolation is used.
    Default is True.

Returns
-------
basis_element : callable
    A callable representing a B-spline basis element for the knot
    vector `t`.

Notes
-----
The degree of the B-spline, `k`, is inferred from the length of `t` as
``len(t)-2``. The knot vector is constructed by appending and prepending
``k+1`` elements to internal knots `t`.

Examples
--------

Construct a cubic B-spline:

>>> import numpy as np
>>> from scipy.interpolate import BSpline
>>> b = BSpline.basis_element([0, 1, 2, 3, 4])
>>> k = b.k
>>> b.t[k:-k]
array([ 0.,  1.,  2.,  3.,  4.])
>>> k
3

Construct a quadratic B-spline on ``[0, 1, 1, 2]``, and compare
to its explicit form:

>>> t = [0, 1, 1, 2]
>>> b = BSpline.basis_element(t)
>>> def f(x):
...     return np.where(x < 1, x*x, (2. - x)**2)

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> x = np.linspace(0, 2, 51)
>>> ax.plot(x, b(x), 'g', lw=3)
>>> ax.plot(x, f(x), 'r', lw=8, alpha=0.4)
>>> ax.grid(True)
>>> plt.show()

rA   r   r         ?)r6   r+   r   r_
zeros_likerZ   )rY   r0   rH   r/   rG   s        r   basis_elementBSpline.basis_element  ss    r FQJAEE1Q46)a-rU1WJN23MM!!!!77r    c                     [        US5      n[        US5      nUS:w  a  [        U5      nUS:  a  [        S5      eUR                  S:w  d$  [        R
                  " USS USS :  5      (       a  [        SU S	35      e[        U5      S
U-  S
-   :  a  [        SU S	35      eUS:X  a+  UR                  U-
  S-
  nX#   XU   -
  X%   X#   -
  -  -   nSnOKU(       dD  [        U5      X#   :  d$  [        U5      X"R                  S   U-
  S-
     :  a  [        SU S	35      eUR                  S   nXSS-   -  nU[        R                  " [        R                  5      R                  :  a  [        R                  nO[        R                  n[        R                  " XU[        R                   " U5      U5      u  pn
UR#                  5       nU	R$                  U:w  a  U	R'                  U5      n	[        R(                  " XS-   5      R+                  SUS-   5      nU[        R,                  " US-   US9-   nUR#                  5       n[        R,                  " SUS-   US-   -  US-   US9n[/        XU4UR                  S   UR                  S   U-
  S-
  4S9$ )aL  
Returns a design matrix as a CSR format sparse array.

Parameters
----------
x : array_like, shape (n,)
    Points to evaluate the spline at.
t : array_like, shape (nt,)
    Sorted 1D array of knots.
k : int
    B-spline degree.
extrapolate : bool or 'periodic', optional
    Whether to extrapolate based on the first and last intervals
    or raise an error. If 'periodic', periodic extrapolation is used.
    Default is False.

    .. versionadded:: 1.10.0

Returns
-------
design_matrix : `csr_array` object
    Sparse matrix in CSR format where each row contains all the basis
    elements of the input row (first row = basis elements of x[0],
    ..., last row = basis elements x[-1]).

Examples
--------
Construct a design matrix for a B-spline

>>> from scipy.interpolate import make_interp_spline, BSpline
>>> import numpy as np
>>> x = np.linspace(0, np.pi * 2, 4)
>>> y = np.sin(x)
>>> k = 3
>>> bspl = make_interp_spline(x, y, k=k)
>>> design_matrix = bspl.design_matrix(x, bspl.t, k)
>>> design_matrix.toarray()
[[1.        , 0.        , 0.        , 0.        ],
[0.2962963 , 0.44444444, 0.22222222, 0.03703704],
[0.03703704, 0.22222222, 0.44444444, 0.2962963 ],
[0.        , 0.        , 0.        , 1.        ]]

Construct a design matrix for some vector of knots

>>> k = 2
>>> t = [-1, 0, 1, 2, 3, 4, 5, 6]
>>> x = [1, 2, 3, 4]
>>> design_matrix = BSpline.design_matrix(x, t, k).toarray()
>>> design_matrix
[[0.5, 0.5, 0. , 0. , 0. ],
[0. , 0.5, 0.5, 0. , 0. ],
[0. , 0. , 0.5, 0.5, 0. ],
[0. , 0. , 0. , 0.5, 0.5]]

This result is equivalent to the one created in the sparse format

>>> c = np.eye(len(t) - k - 1)
>>> design_matrix_gh = BSpline(t, c, k)(x)
>>> np.allclose(design_matrix, design_matrix_gh, atol=1e-14)
True

Notes
-----
.. versionadded:: 1.8.0

In each row of the design matrix all the basis elements are evaluated
at the certain point (first row - x[0], ..., last row - x[-1]).

`nt` is a length of the vector of knots: as far as there are
`nt - k - 1` basis elements, `nt` should be not less than `2 * k + 2`
to have at least `k + 1` basis element.

Out of bounds `x` raises a ValueError.
Tr?   r   r@   r   Nra   z2Expect t to be a 1-D sorted array_like, but got t=.rA   zLength t is not enough for k=FOut of bounds w/ x = r   rJ   )r+   rI   r'   rK   r   rO   r6   sizeminmaxrJ   iinfoint32int64r   data_matrix	ones_likeravelr   r$   repeatreshapearanger   )rY   r(   r0   r/   rH   rR   nnz	int_dtypedataoffsets_indicesindptrs                r   design_matrixBSpline.design_matrixS  sn   X At$At$*${+Kq5?@@66Q;"&&123B00  &&'S+ , , q6AEAI<QCqABB*$ 
QAaDQTAD[11AKVad]A771:>A+=)> > 4QCq9:: GGAJq5k"((#'''II $//aa+Vqzz|==I%nnY/G ))GqS)11"ac:BIIac;;--/1q1uQ/QiHF#771:qwwqzA~12
 	
r    c                    Uc  U R                   n[        R                  " U5      nUR                  UR                  pT[        R
                  " UR                  5       [        R                  S9nUS:X  a  U R                  R                  U R                  -
  S-
  nU R                  U R                     XR                  U R                     -
  U R                  U   U R                  U R                     -
  -  -   nSn[        R                  " [        U5      [        U R                  R                  SS 5      4U R                  R                  S9nU R!                  5         U R                  R#                  [$        5      nU R                  R                  S:X  aM  U R                  R                  R&                  S:X  a)  UR)                  U R                  R                  S   S5      n[*        R,                  " U R                  UR)                  UR                  S   S	5      U R                  XX7R#                  [$        5      5        UR)                  X@R                  R                  SS -   5      nU R.                  S:w  aW  [1        [3        UR                  5      5      n	XXPR.                  -    U	SU -   XU R.                  -   S -   n	UR5                  U	5      nU$ )
a
  
Evaluate a spline function.

Parameters
----------
x : array_like
    points to evaluate the spline at.
nu : int, optional
    derivative to evaluate (default is 0).
extrapolate : bool or 'periodic', optional
    whether to extrapolate based on the first and last intervals
    or return nans. If 'periodic', periodic extrapolation is used.
    Default is `self.extrapolate`.

Returns
-------
y : array_like
    Shape is determined by replacing the interpolation axis
    in the coefficient array with the shape of `x`.

Nr   r?   r   FrG   r   rA   ra   )rH   r   rF   rJ   rK   r#   rs   r   r0   rk   r/   emptyr6   r   rG   r   _ensure_c_contiguousviewfloatkindru   r   evaluate_splinerL   r5   r-   	transpose)
rQ   r(   nurH   x_shapex_ndimrR   outccls
             r   __call__BSpline.__call__  s   , **KJJqM''166  "**= *$dff$q(Atvv!ffTVVn"49=:H "I IAKhhATVV\\!"%5 67tvv||L!!# VV[[66;;! 1 1S 8DFFLLOQ/B  BHHQK)D"ffa[((5/	K kk'FFLL$44599>U388_%A		)*QwZ7!499<L<M:NNA--"C
r    c                    U R                   R                  R                  (       d  U R                   R                  5       U l         U R                  R                  R                  (       d   U R                  R                  5       U l        gg)z[
c and t may be modified by the user. The Cython code expects
that they are C contiguous.

N)r0   flagsc_contiguousr"   rG   r]   s    r   r   BSpline._ensure_c_contiguous  sM     vv||((VV[[]DFvv||((VV[[]DF )r    c                    U R                   R                  5       n[        U R                  5      [        U5      -
  nUS:  a:  [        R
                  U[        R                  " U4UR                  SS -   5      4   n[        R                  " U R                  X R                  4U5      nU R                  " X@R                  U R                  S.6$ )zReturn a B-spline representing the derivative.

Parameters
----------
nu : int, optional
    Derivative order.
    Default is 1.

Returns
-------
b : BSpline object
    A new instance representing the derivative.

See Also
--------
splder, splantider

r   r   NrH   rL   )rG   r"   r6   r0   r   rc   zerosrJ   r   splderr/   rZ   rH   rL   )rQ   r   rG   ctr^   s        r   
derivativeBSpline.derivative!  s    & FFKKM[3q6!6a2%!''!"+"5667A""DFFAvv#6;""C5E5E(,		3 	3r    c                    U R                   R                  5       n[        U R                  5      [        U5      -
  nUS:  a:  [        R
                  U[        R                  " U4UR                  SS -   5      4   n[        R                  " U R                  X R                  4U5      nU R                  S:X  a  SnOU R                  nU R                  " XEU R                  S.6$ )a  Return a B-spline representing the antiderivative.

Parameters
----------
nu : int, optional
    Antiderivative order. Default is 1.

Returns
-------
b : BSpline object
    A new instance representing the antiderivative.

Notes
-----
If antiderivative is computed and ``self.extrapolate='periodic'``,
it will be set to False for the returned instance. This is done because
the antiderivative is no longer periodic and its correct evaluation
outside of the initially given x interval is difficult.

See Also
--------
splder, splantider

r   r   Nr?   Fr   )rG   r"   r6   r0   r   rc   r   rJ   r   
splantiderr/   rH   rZ   rL   )rQ   r   rG   r   r^   rH   s         r   antiderivativeBSpline.antiderivative=  s    2 FFKKM[3q6!6a2%!''!"+"5667A&&66':B?z)K**K""C(,		3 	3r    c           	      l	   Uc  U R                   nU R                  5         SnX!:  a  X!p!SnU R                  R                  U R                  -
  S-
  nUS:w  a  U(       d  [        XR                  U R                     5      n[        X R                  U   5      nU R                  R                  S:X  a9  [        R                  " XU R                  5      n[        R                  " Xd-  5      $ [        R                  " S[        U R                  R                   SS 5      4U R                  R"                  S9nU R                  n[%        U R                  5      [%        U5      -
  n	U	S:  a:  [        R&                  U[        R(                  " U	4UR                   SS -   5      4   n[        R*                  " U R                  XR                  4S5      u  pnUS:X  GaT  U R                  U R                     U R                  U   pX-
  nX!-
  n[-        UU5      u  nnUS:  am  [        R                  " X/[        R.                  S9n[0        R2                  " XR5                  UR                   S   S5      UUSSU5        US   US   -
  nUU-  nOK[        R(                  " S[        U R                  R                   SS 5      4U R                  R"                  S9nXU-
  U-  -   nUU-   nX.::  ak  [        R                  " X/[        R.                  S9n[0        R2                  " XR5                  UR                   S   S5      UUSSU5        XgS   US   -
  -  nGO?[        R                  " X/[        R.                  S9n[0        R2                  " XR5                  UR                   S   S5      UUSSU5        XgS   US   -
  -  n[        R                  " XU-   U-
  /[        R.                  S9n[0        R2                  " XR5                  UR                   S   S5      UUSSU5        XgS   US   -
  -  nOf[        R                  " X/[        R.                  S9n[0        R2                  " XR5                  UR                   S   S5      UUSX75        US   US   -
  nXd-  nUR5                  UR                   SS 5      $ )	a  Compute a definite integral of the spline.

Parameters
----------
a : float
    Lower limit of integration.
b : float
    Upper limit of integration.
extrapolate : bool or 'periodic', optional
    whether to extrapolate beyond the base interval,
    ``t[k] .. t[-k-1]``, or take the spline to be zero outside of the
    base interval. If 'periodic', periodic extrapolation is used.
    If None (default), use `self.extrapolate`.

Returns
-------
I : array_like
    Definite integral of the spline over the interval ``[a, b]``.

Examples
--------
Construct the linear spline ``x if x < 1 else 2 - x`` on the base
interval :math:`[0, 2]`, and integrate it

>>> from scipy.interpolate import BSpline
>>> b = BSpline.basis_element([0, 1, 2])
>>> b.integrate(0, 1)
array(0.5)

If the integration limits are outside of the base interval, the result
is controlled by the `extrapolate` parameter

>>> b.integrate(-1, 1)
array(0.0)
>>> b.integrate(-1, 1, extrapolate=False)
array(0.5)

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> ax.grid(True)
>>> ax.axvline(0, c='r', lw=5, alpha=0.5)  # base interval
>>> ax.axvline(2, c='r', lw=5, alpha=0.5)
>>> xx = [-1, 1, 2]
>>> ax.plot(xx, b(xx))
>>> plt.show()

Nr   ra   r?   rA   r   r   F)rH   r   r0   rk   r/   rm   rl   rG   rK   r   splintr^   r   rF   r   r   rJ   r   r6   rc   r   r   divmodr   r   r   ru   )rQ   abrH   signrR   integralr   rG   r   tacakatsteperiodinterval	n_periodsleftr(   s                       r   	integrateBSpline.integratee  s   ` **K 	!!# 5qDFFKK$&& 1$*$[Avvdff~&AAvvay!Avv{{a )//dhh?zz(/22hh4QR 012$&&,,G FF[3q6!6a2%!''!"+"5667A"--tvvq&&.A1E
*$ VVDFF^TVVAYWFuH$Xv6OIt1}JJxrzz:((ZZR-H&(!Qs<q6CF?I%88QTVV\\!"-=(>$?*.&&,,8 "f&&ADA wJJvRZZ8((ZZR-H&(!Qs<FSVO+JJwbjj9((ZZR-H&(!Qs<FSVO+JJFRK0

C((ZZR-H&(!Qs<FSVO+ 

A64A$$RBHHQK)D"$aK>1vAH--r    c                    SSK Jn  [        X5      (       d  [        S[	        U5       S35      eUR
                  nUR                  nUR                  R                  S   S-
  nUR                  S   nUS:X  a  [        XF5      nO8US:X  d  US:X  a  [        XF5      nO US	:X  a  [        XF5      nO[        S
U 35      eUR                  S   Xv-   S-   -
  n	[        R                  " Xy-   UR                  R                  S9n
[        US-   5       H  n[        US-
  5       HN  nX==   [!        US-   U* 5      X[U4   -  [        R"                  " SXk-
  5      -  [%        XXL   X5      -  -  ss'   MP     [        US-
  Xy-   5       HT  nX==   [!        US-   U* 5      X[US-
  4   -  [        R"                  " SXk-
  5      -  [%        XXGS-
     X5      -  -  ss'   MV     M     U R'                  XXaR(                  UR*                  5      $ )am  
Construct a polynomial in the B-spline basis
from a piecewise polynomial in the power basis.

For now, accepts ``CubicSpline`` instances only.

Parameters
----------
pp : CubicSpline
    A piecewise polynomial in the power basis, as created
    by ``CubicSpline``
bc_type : string, optional
    Boundary condition type as in ``CubicSpline``: one of the
    ``not-a-knot``, ``natural``, ``clamped``, or ``periodic``.
    Necessary for construction an instance of ``BSpline`` class.
    Default is ``not-a-knot``.

Returns
-------
b : BSpline object
    A new instance representing the initial polynomial
    in the B-spline basis.

Notes
-----
.. versionadded:: 1.8.0

Accepts only ``CubicSpline`` instances for now.

The algorithm follows from differentiation
the Marsden's identity [1]: each of coefficients of spline
interpolation function in the B-spline basis is computed as follows:

.. math::

    c_j = \sum_{m=0}^{k} \frac{(k-m)!}{k!}
               c_{m,i} (-1)^{k-m} D^m p_{j,k}(x_i)

:math:`c_{m, i}` - a coefficient of CubicSpline,
:math:`D^m p_{j, k}(x_i)` - an m-th defivative of a dual polynomial
in :math:`x_i`.

``k`` always equals 3 for now.

First ``n - 2`` coefficients are computed in :math:`x_i = x_j`, e.g.

.. math::

    c_1 = \sum_{m=0}^{k} \frac{(k-1)!}{k!} c_{m,1} D^m p_{j,3}(x_1)

Last ``nod + 2`` coefficients are computed in ``x[-2]``,
``nod`` - number of derivatives at the ends.

For example, consider :math:`x = [0, 1, 2, 3, 4]`,
:math:`y = [1, 1, 1, 1, 1]` and bc_type = ``natural``

The coefficients of CubicSpline in the power basis:

:math:`[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0],
[0, 0, 0, 0, 0], [1, 1, 1, 1, 1]]`

The knot vector: :math:`t = [0, 0, 0, 0, 1, 2, 3, 4, 4, 4, 4]`

In this case

.. math::

    c_j = \frac{0!}{k!} c_{3, i} k! = c_{3, i} = 1,~j = 0, ..., 6

References
----------
.. [1] Tom Lyche and Knut Morken, Spline Methods, 2005, Section 3.1.2

r   )CubicSplinez3Only CubicSpline objects are accepted for now. Got z	 instead.r   
not-a-knotnaturalclampedr?   Unknown boundary condition: r   rA   ra   )_cubicr   
isinstanceNotImplementedErrortyper(   rG   rJ   _not_a_knot_augknt_periodic_knots	TypeErrorr   r   r   r-   r   powerr;   rZ   rH   rL   )rY   ppbc_typer   r(   coefr/   rR   r0   nodrG   mr2   r.   s                 r   from_power_basisBSpline.from_power_basis  s   X 	("**% )66:2hZy'J K KDDttDDJJqMAGGAJl"A!A	!W	%9A
"%A:7)DEEggajAEAI&HHQWBDDJJ/q1uA1q5\QUQB$!t*4((2qu-.)!a;< < " 1q5!'*QUQB$!a%x.8((2qu-.)!a%!?@ @ +  !!!>>277CCr    c           	          XR                   U R                     :  d   XR                   U R                  * S-
     :  a  [        SU S35      eUS::  a  [        SU< S35      eU R                   R                  5       nU R                  R                  5       n[        U5       H)  n[        XX@R                  U R                  S:H  5      u  p4M+     U R                  X4U R                  U R                  U R                  5      $ )a  Insert a new knot at `x` of multiplicity `m`.

Given the knots and coefficients of a B-spline representation, create a
new B-spline with a knot inserted `m` times at point `x`.

Parameters
----------
x : float
    The position of the new knot
m : int, optional
    The number of times to insert the given knot (its multiplicity).
    Default is 1.

Returns
-------
spl : BSpline object
    A new BSpline object with the new knot inserted.

Notes
-----
Based on algorithms from [1]_ and [2]_.

In case of a periodic spline (``self.extrapolate == "periodic"``)
there must be either at least k interior knots t(j) satisfying
``t(k+1)<t(j)<=x`` or at least k interior knots t(j) satisfying
``x<=t(j)<t(n-k)``.

This routine is functionally equivalent to `scipy.interpolate.insert`.

.. versionadded:: 1.13

References
----------
.. [1] W. Boehm, "Inserting new knots into b-spline curves.",
    Computer Aided Design, 12, p.199-201, 1980.
    :doi:`10.1016/0010-4485(80)90154-2`.
.. [2] P. Dierckx, "Curve and surface fitting with splines, Monographs on
    Numerical Analysis", Oxford University Press, 1993.

See Also
--------
scipy.interpolate.insert

Examples
--------
You can insert knots into a B-spline:

>>> import numpy as np
>>> from scipy.interpolate import BSpline, make_interp_spline
>>> x = np.linspace(0, 10, 5)
>>> y = np.sin(x)
>>> spl = make_interp_spline(x, y, k=3)
>>> spl.t
array([ 0.,  0.,  0.,  0.,  5., 10., 10., 10., 10.])

Insert a single knot

>>> spl_1 = spl.insert_knot(3)
>>> spl_1.t
array([ 0.,  0.,  0.,  0.,  3.,  5., 10., 10., 10., 10.])

Insert a multiple knot

>>> spl_2 = spl.insert_knot(8, m=3)
>>> spl_2.t
array([ 0.,  0.,  0.,  0.,  5.,  8.,  8.,  8., 10., 10., 10., 10.])

r   zCannot insert a knot at rh   r   z`m` must be positive, got m = r?   )
r0   r/   r'   r"   rG   r-   _insertrH   rZ   rL   )rQ   r(   r   ttr   r{   s         r   insert_knotBSpline.insert_knotT  s    J vvdff~VVTVVGAI%6!67s!<==6>!qABBVV[[]VV[[]qAQB0@0@J0NOFB ""246643C3CTYYOOr    )rL   rG   rH   r/   r0   )Tr   )TFr   N)r   N)r   )__name__
__module____qualname____firstlineno____doc__rC   classmethodrZ   propertyr^   re   r~   r   r   r   r   r   r   r   __static_attributes____classcell__)rT   s   @r   r   r   E   s    IV-8^ 
 
 & &
 =8 =8~ D
 D
L:x	#38&3PB.H hD hDTOP OPr    r   c                    [         R                  " X[        U 5      US5      nUS:  a  [        SU  S35      eX   XU-   S-      :X  a  US-  nU(       a3  US-   SU-  ::  a'  US-   UR                  S   SU-  -
  :  a  [        S5      e[
        R                  USUS-    XUS-   S 4   nUR                  S   S-   4UR                  SS -   n[
        R                  " XrR                  S	9nX%S2S
4   XS-   S2S
4'   [        XUU-
  S5       H7  n	XU	   -
  XiU-   S-      Xi   -
  -  n
XU	S
4   -  SU
-
  X)S-
  S
4   -  -   XS
4'   M9     USXS-
  S-   2S
4   USXS-
  S-   2S
4'   U(       a  UR                  S   nX-
  S-
  nUSU-  -
  S-
  nXl   Xc   -
  nX\U-
  :  a  XlU-
  U U-
  USU& XX-   2S
4   USU2S
4'   USU-  S-
  ::  a&  XcS-   US-   U-    U-   XkU-
  S& USU2S
4   XX-   2S
4'   Xh4$ )zInsert a single knot at `xval`.Fr   zCannot insert the knot at rh   r   rA   zNot enough internal knots.Nr   .ra   rb   )
r   find_intervalr   r'   rJ   r   rc   r   r   r-   )xvalr0   rG   r/   r?   r   r   newshaper   r2   facrR   nkn2kTs                  r   r   r     sx   $ %%aE$KEBH!|5dV1=>> 	{a1q())AqLAaChlaggaj1Q36F&F 9:: 
q(1*~txz{^3	4B
Q 17712;.H	(''	*B Y^,Bz{C8aZ,e|Q3q5	BE 121c6]b3hA#s(%;;c6
 -  !(,q.#!56BQHHQKUQY!A#gkFRUNAvQr]Q&BrF[#-.Brr3wKqs1uA#ac!e}q(BstH#%bqb#g;B37{C 6Mr    c                     [         R                  " U 5      n US-  S:X  a  US-   S-  nU R                  5       nOUS-  nU SS U SS -   S-  nX2U*  n[         R                  U S   4US-   -  X0S   4US-   -  4   nU$ )aF  Given data x, construct the knot vector w/ not-a-knot BC.
cf de Boor, XIII(12).

For even k, it's a bit ad hoc: Greville sites + omit 2nd and 2nd-to-last
data points, a la not-a-knot.
This seems to match what Dierckx does, too:
https://github.com/scipy/scipy/blob/maintenance/1.11.x/scipy/interpolate/fitpack/fpcurf.f#L63-L80
rA   r   Nra   r   )r   rF   r"   rc   )r(   r/   k2r0   s       r   r   r     s     	

1A1uz!e\FFH!VqrUQsV^q 	bS	A
qtgqsmQ2!A#./AHr    c                 H    [         R                  U S   4U-  X S   4U-  4   $ )zBConstruct a knot vector appropriate for the order-k interpolation.r   ra   )r   rc   )r(   r/   s     r   r   r     s*    55!A$A"xz)**r    c                     [        U [        5      (       aP  U S:X  a  S[        R                  " U5      4/n U $ U S:X  a  S[        R                  " U5      4/n U $ [	        SU  35      eU $ )Nr   r   r   rA   zUnknown boundary condition : )r   strr   r   r'   )derivtarget_shapes     r   _convert_string_aliasesr     su    %I,/01E
 L	 i,/01E L <UGDEELr    c                     U b   [        U 6 u  pO/ / p![        R                  " X5      $ ! [         a  nSn[        U5      UeS nAff = f)Nz^Derivatives, `bc_type`, should be specified as a pair of iterables of pairs of (order, value).)zipr   r'   r   
atleast_1d)r   ordsvalsemsgs        r   _process_deriv_specr     sW    	)eJD$ d==$$  	);CS/q(	)s   
) 
AAAc                    XDS-  -
  n[        US-
  S-  5      US-   S-  -   nU R                  S   S-   n[        R                  " US-
  U45      n[        R                  " XWS-
  45      n	XSU2SU24'   SU	[        R                  " U5      [        R                  " U5      U-
  4'   X(U* S2U* S24'   SU	[        R                  " U5      U-
  [        R                  " U5      4'   [        Xf4X5      n
[        [        R                  " U5      X-  -   [        R                  " U5      5      n[        Xf4X5      nXXU-  -  -  -
  nU$ )ab  
Solve a cyclic banded linear system with upper right
and lower blocks of size ``(k-1) / 2`` using
the Woodbury formula

Parameters
----------
A : 2-D array, shape(k, n)
    Matrix of diagonals of original matrix (see
    ``solve_banded`` documentation).
ur : 2-D array, shape(bs, bs)
    Upper right block matrix.
ll : 2-D array, shape(bs, bs)
    Lower left block matrix.
b : 1-D array, shape(n,)
    Vector of constant terms of the system of linear equations.
k : int
    B-spline degree.

Returns
-------
c : 1-D array, shape(n,)
    Solution of the original system of linear equations.

Notes
-----
This algorithm works only for systems with banded matrix A plus
a correction term U @ V.T, where the matrix U @ V.T gives upper right
and lower left block of A
The system is solved with the following steps:
    1.  New systems of linear equations are constructed:
        A @ z_i = u_i,
        u_i - column vector of U,
        i = 1, ..., k - 1
    2.  Matrix Z is formed from vectors z_i:
        Z = [ z_1 | z_2 | ... | z_{k - 1} ]
    3.  Matrix H = (1 + V.T @ Z)^{-1}
    4.  The system A' @ y = b is solved
    5.  x = y - Z @ (H @ V.T @ y)
Also, ``n`` should be greater than ``k``, otherwise corner block
elements will intersect with diagonals.

Examples
--------
Consider the case of n = 8, k = 5 (size of blocks - 2 x 2).
The matrix of a system:       U:          V:
  x  x  x  *  *  a  b         a b 0 0     0 0 1 0
  x  x  x  x  *  *  c         0 c 0 0     0 0 0 1
  x  x  x  x  x  *  *         0 0 0 0     0 0 0 0
  *  x  x  x  x  x  *         0 0 0 0     0 0 0 0
  *  *  x  x  x  x  x         0 0 0 0     0 0 0 0
  d  *  *  x  x  x  x         0 0 d 0     1 0 0 0
  e  f  *  *  x  x  x         0 0 e f     0 1 0 0

References
----------
.. [1] William H. Press, Saul A. Teukolsky, William T. Vetterling
       and Brian P. Flannery, Numerical Recipes, 2007, Section 2.7.3

rA   r   N)intrJ   r   r   rv   r
   r	   identity)Aurllr   r/   k_modbsrR   UVTZHr1   rG   s                 r   _woodbury_algorithmr   #  s5   z AIE	a!eq[	QUaK	'B	
QA
!a% A	5a%.	!B crc3B3hK,-Bryy}biimb(() rcdRCDjM,-Bryy}r299R=()bXq$Abkk% 26)2;;u+=>AbXq$A	1fAHr    c                    [         R                  " U 5      n[        U5      nUS-  S:X  a*  [         R                  " U5      nUSS=== USS S-  -  sss& [         R                  " U5      n[         R                  " USU-  -   5      nX%X* & [        SU5       H=  nXQU-
     XFUS-
  -  * S-
     -
  XQU-
  S-
  '   XQ* U-   S-
     XFUS-
  -     -   XQ* U-   '   M?     U$ )z#
returns vector of nodes on circle
rA   r   r   ra   N)r   r"   r6   rN   r   r-   )r(   r/   xcrR   dxr0   r2   s          r   r   r   y  s     
BBA1uzWWR[
1b	RWq[ 		B
QUAaH1a[Qx"AE{^a%7"88a%!)b1fqjMBAE{O3"q&		 
 Hr    c           	         [        [        R                  XU45      u  pnU R                  n[        R                  " XC-   S-
  XC-   S-
  45      n[        US-
  5       Hl  n[        R                  " X#U S   X6S-   5      nXVSUS-   24==   U-  ss'   [        R                  " X#U S   XC-   S-
  US-   5      SS nXVU* S24==   U-  ss'   Mn     [        U5       HT  nX   nXU   :X  a  Un	O[        R                  " X(5      S-
  n	[        R                  " X#X5      nXuXc-   S-
  X-
  U	S-   24'   MV     [        R                  S/US-
  -  U4   n
[        XZ5      nU$ )a  
Returns a solution of a system for B-spline interpolation with periodic
boundary conditions. First ``k - 1`` rows of matrix are conditions of
periodicity (continuity of ``k - 1`` derivatives at the boundary points).
Last ``n`` rows are interpolation conditions.
RHS is ``k - 1`` zeros and ``n`` ordinates in this case.

Parameters
----------
x : 1-D array, shape (n,)
    Values of x - coordinate of a given set of points.
y : 1-D array, shape (n,)
    Values of y - coordinate of a given set of points.
t : 1-D array, shape(n+2*k,)
    Vector of knots.
k : int
    The maximum degree of spline

Returns
-------
c : 1-D array, shape (n+k-1,)
    B-spline coefficients

Notes
-----
``t`` is supposed to be taken on circle.

r   r   Nra   )mapr   rF   rk   r   r-   r   evaluate_all_bsplsearchsortedrc   r	   )r(   r1   r0   r/   rR   matrr2   bbr   r   r   rG   s               r   _make_interp_per_full_matrr    sc   < "**qQi(GA!	A88QUQY	*+D 1q5\''adA1u=!a%ZB''aeQUQYAFsKV	  1XtQ4<D??1+a/D ''d9)+QUQYtAv%&  	qcQUmQAdAHr    c                    [         R                  " X[        U5      US5      n[        UR                  S   5       HO  n	Xi   n
[         R
                  " XX(U
5      n[        US-   5       H  nX-
  U-   nX   X4U-   U-   U	-   U-
  U4'   M      MQ     g)a  Fill in the entries of the colocation matrix corresponding to known
derivatives at `xval`.

The colocation matrix is in the banded storage, as prepared by _coloc.
No error checking.

Parameters
----------
t : ndarray, shape (nt + k + 1,)
    knots
k : integer
    B-spline order
xval : float
    The value at which to evaluate the derivatives at.
ab : ndarray, shape(2*kl + ku + 1, nt), Fortran order
    B-spline colocation matrix.
    This argument is modified *in-place*.
kl : integer
    Number of lower diagonals of ab.
ku : integer
    Number of upper diagonals of ab.
deriv_ords : 1D ndarray
    Orders of derivatives known at xval
offset : integer, optional
    Skip this many rows of the matrix ab.

Fr   r   N)r   r   r   r-   rJ   r  )r0   r/   r   abklku
deriv_ordsoffsetr   rowr   wrkr   clmns                 r   _handle_lhs_derivativesr    s    : !!!dQ>D Z%%a()_((t2> qsA8a<D69fBBw#%,d23  *r    c           
      F   UR                   S   n[        UR                   SS 5      nUR                  XV5      n[        R                  " XS-   S-
  U45      nXS::  a}  [        U5       H  n	[        XSS2U	4   X#5      USS2U	4'   M     [        R                  " UR                  XS-   S-
  4UR                   SS -   5      5      n[        R                  X(USUS9$ [        U5      U-
  S-
  n
[        US-  5      n[        R                  " SU-  S-   U
4[        R                  SS	9n[        R                  " X45      n[        R                  " U5      n[        R                  " U SS
 X#UR                   U5        X* US-   S-  -
  S2SS24   n[        U5       HV  n	U[        R"                  " X* S-
  X24   U	S9-  nU[        R"                  " XU* US-  -
  US-
  SU-  -   U	-
  24   U	* S9-  nMX     USS2X* U-   24   n[        U5       HF  n	[%        XXSS2U	4   SS
 U5      n[        R&                  " UU* S UUSXS-  -    45      USS2U	4'   MH     [        R                  " UR                  XS-   S-
  4UR                   SS -   5      5      n[        R                  X(USUS9$ )a  
Compute the (coefficients of) interpolating B-spline with periodic
boundary conditions.

Parameters
----------
x : array_like, shape (n,)
    Abscissas.
y : array_like, shape (n,)
    Ordinates.
k : int
    B-spline degree.
t : array_like, shape (n + 2 * k,).
    Knots taken on a circle, ``k`` on the left and ``k`` on the right
    of the vector ``x``.

Returns
-------
b : a BSpline object of the degree ``k`` and with knots ``t``.

Notes
-----
The original system is formed by ``n + k - 1`` equations where the first
``k - 1`` of them stand for the ``k - 1`` derivatives continuity on the
edges while the other equations correspond to an interpolating case
(matching all the input points). Due to a special form of knot vector, it
can be proved that in the original system the first and last ``k``
coefficients of a spline function are the same, respectively. It follows
from the fact that all ``k - 1`` derivatives are equal term by term at ends
and that the matrix of the original system of linear equations is
non-degenerate. So, we can reduce the number of equations to ``n - 1``
(first ``k - 1`` equations could be reduced). Another trick of this
implementation is cyclic shift of values of B-splines due to equality of
``k`` unknown coefficients. With this we can receive matrix of the system
with upper right and lower left blocks, and ``k`` diagonals.  It allows
to use Woodbury formula to optimize the computations.

r   r   Nr?   r   rA      Fr   orderra   )r/   )rJ   r   ru   r   r   r-   r  r#   r   rZ   r6   r   r   rd   r   _colocr   diagr   concatenate)r(   r1   r0   r/   rL   rR   extradimy_newrG   r2   ntkulr  r   r   r   r   s                    r   _make_periodic_spliner    s   N 	

AAGGABK HIIa"E
!%!)X&'A 	vxA0!Q$KFAadG !  AEAI<!''!"++E!FG%%aA:D%QQ	Q!aB a!e*C 
1q519b/3	?B 
3*	B	r	B OOAcrFA"$$* 
B!a%1q 	!B
 3Z
bggba(A..
bggbSDAENAEAGOa,???@QBGG  	1c28mA8_ !Q$K,<a@.."cTU)RLSq5[1A!BC!Q$  	QYY	|aggabk'ABCA!!!z!MMr    c                   ^ Ub  US:X  d  US:X  a  Su  pxO[        U[        5      (       a  XDpO Uu  px[        R
                  " U5      n[        XQR                  5      n[        X5      n [        X5      n[        R                  " XS5      nUS:X  a,  [        R                  " US   US   SS	9(       d  [        S
5      eU R                  UR                  S   :w  a&  [        SU R                   SUR                   S35      e[        R                  " U SS U SS :H  5      (       a  [        S5      eU R                  S:w  d$  [        R                  " U SS U SS :  5      (       a  [        S5      eTS:X  a  [        S X7U4 5       5      (       a  [        S5      e[        R                  X S   4   n[        R
                  " U5      n
[        R                  " U
[!        U
R"                  5      S9n
[$        R'                  X:TUS9$ TS:X  a  Uc  Uc  Ub  [        S5      e[        R                  U S   X S   4   n[        R
                  " U5      n
[        R                  " U
[!        U
R"                  5      S9n
[$        R'                  X:TUS9$ [(        R*                  " T5      mUS:X  a  Ub  [-        S5      eUc2  Uc#  Uc   US:X  a  [/        U T5      nO[1        U T5      nO[3        U T5      n[        X65      nTS:  a  [        S5      eUR                  S:w  d$  [        R                  " USS USS :  5      (       a  [        S5      eUR                  U R                  T-   S-   :  a*  [        SUR                  U R                  T-   S-   4-  5      eU S   UT   :  d  U S   UT*    :  a  [        SU  S35      eUS:X  a  [5        XUTU5      $ [7        XqR                  SS 5      n[9        U5      u  pUR                  S   n[7        XR                  SS 5      n[9        U5      u  pUR                  S   n[;        U4S jU 5       5      (       d  [        SU S    S35      e[;        U4S jU 5       5      (       d  [        SU S    S35      eU R                  nUR                  T-
  S-
  nUU-
  UU-   :w  a  [        SUU-
   S U S!U 35      eUR                  S:X  a?  [        R<                  " U4UR                  SS -   [>        S9n
[$        R'                  X:TUS9$ T=nn[        R<                  " S"U-  U-   S-   U4[        R@                  S#S$9n[B        RD                  " XTURF                  U5        US:  a  [I        UTU S   UUUU5        US:  a  [I        UTU S   UUUUUU-
  S%9  [K        UR                  SS 5      n[        RL                  " UU4UR"                  S9nUS:  a  URO                  SU5      USU& URO                  SU5      UUUU-
  & US:  a  URO                  SU5      UUU-
  S& U(       a  [Q        [        RR                  UU45      u  nn[U        S&UU45      u  nU" UUUUS'S'S(9u  nnn
nUS:  a  [W        S)5      eUS:  a  [        S*U* -  5      e[        R                  " U
RO                  U4UR                  SS -   5      5      n
[$        R'                  X:TUS9$ ! [         a  n	[        SU 35      U	eSn	A	ff = f)+av  Compute the (coefficients of) interpolating B-spline.

Parameters
----------
x : array_like, shape (n,)
    Abscissas.
y : array_like, shape (n, ...)
    Ordinates.
k : int, optional
    B-spline degree. Default is cubic, ``k = 3``.
t : array_like, shape (nt + k + 1,), optional.
    Knots.
    The number of knots needs to agree with the number of data points and
    the number of derivatives at the edges. Specifically, ``nt - n`` must
    equal ``len(deriv_l) + len(deriv_r)``.
bc_type : 2-tuple or None
    Boundary conditions.
    Default is None, which means choosing the boundary conditions
    automatically. Otherwise, it must be a length-two tuple where the first
    element (``deriv_l``) sets the boundary conditions at ``x[0]`` and
    the second element (``deriv_r``) sets the boundary conditions at
    ``x[-1]``. Each of these must be an iterable of pairs
    ``(order, value)`` which gives the values of derivatives of specified
    orders at the given edge of the interpolation interval.
    Alternatively, the following string aliases are recognized:

    * ``"clamped"``: The first derivatives at the ends are zero. This is
       equivalent to ``bc_type=([(1, 0.0)], [(1, 0.0)])``.
    * ``"natural"``: The second derivatives at ends are zero. This is
      equivalent to ``bc_type=([(2, 0.0)], [(2, 0.0)])``.
    * ``"not-a-knot"`` (default): The first and second segments are the
      same polynomial. This is equivalent to having ``bc_type=None``.
    * ``"periodic"``: The values and the first ``k-1`` derivatives at the
      ends are equivalent.

axis : int, optional
    Interpolation axis. Default is 0.
check_finite : bool, optional
    Whether to check that the input arrays contain only finite numbers.
    Disabling may give a performance gain, but may result in problems
    (crashes, non-termination) if the inputs do contain infinities or NaNs.
    Default is True.

Returns
-------
b : a BSpline object of the degree ``k`` and with knots ``t``.

See Also
--------
BSpline : base class representing the B-spline objects
CubicSpline : a cubic spline in the polynomial basis
make_lsq_spline : a similar factory function for spline fitting
UnivariateSpline : a wrapper over FITPACK spline fitting routines
splrep : a wrapper over FITPACK spline fitting routines

Examples
--------

Use cubic interpolation on Chebyshev nodes:

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> def cheb_nodes(N):
...     jj = 2.*np.arange(N) + 1
...     x = np.cos(np.pi * jj / 2 / N)[::-1]
...     return x

>>> x = cheb_nodes(20)
>>> y = np.sqrt(1 - x**2)

>>> from scipy.interpolate import BSpline, make_interp_spline
>>> b = make_interp_spline(x, y)
>>> np.allclose(b(x), y)
True

Note that the default is a cubic spline with a not-a-knot boundary condition

>>> b.k
3

Here we use a 'natural' spline, with zero 2nd derivatives at edges:

>>> l, r = [(2, 0.0)], [(2, 0.0)]
>>> b_n = make_interp_spline(x, y, bc_type=(l, r))  # or, bc_type="natural"
>>> np.allclose(b_n(x), y)
True
>>> x0, x1 = x[0], x[-1]
>>> np.allclose([b_n(x0, 2), b_n(x1, 2)], [0, 0])
True

Interpolation of parametric curves is also supported. As an example, we
compute a discretization of a snail curve in polar coordinates

>>> phi = np.linspace(0, 2.*np.pi, 40)
>>> r = 0.3 + np.cos(phi)
>>> x, y = r*np.cos(phi), r*np.sin(phi)  # convert to Cartesian coordinates

Build an interpolating curve, parameterizing it by the angle

>>> spl = make_interp_spline(phi, np.c_[x, y])

Evaluate the interpolant on a finer grid (note that we transpose the result
to unpack it into a pair of x- and y-arrays)

>>> phi_new = np.linspace(0, 2.*np.pi, 100)
>>> x_new, y_new = spl(phi_new).T

Plot the result

>>> plt.plot(x, y, 'o')
>>> plt.plot(x_new, y_new, '-')
>>> plt.show()

Build a B-spline curve with 2 dimensional y

>>> x = np.linspace(0, 2*np.pi, 10)
>>> y = np.array([np.sin(x), np.cos(x)])

Periodic condition is satisfied because y coordinates of points on the ends
are equivalent

>>> ax = plt.axes(projection='3d')
>>> xx = np.linspace(0, 2*np.pi, 100)
>>> bspl = make_interp_spline(x, y, k=5, bc_type='periodic', axis=1)
>>> ax.plot3D(xx, *bspl(xx))
>>> ax.scatter3D(x, *y, color='red')
>>> plt.show()

Nr   r?   NNr   r   ra   gV瞯<)atolzAFirst and last points does not match while periodic case expectedShapes of x  and y  are incompatibler   zExpect x to not have duplicates1Expect x to be a 1D strictly increasing sequence.c              3   (   #    U  H  oS Lv   M
     g 7fr    ).0r{   s     r   	<genexpr>%make_interp_spline.<locals>.<genexpr>  s     <&;}&;s   z6Too much info for k=0: t and bc_type can only be None.r   rL   z0Too much info for k=1: bc_type can only be None.zOFor periodic case t is constructed automatically and can not be passed manuallyExpect non-negative k.z'Expect t to be a 1-D sorted array_like.zGot %d knots, need at least %d.ri   rh   c              3   N   >#    U  H  nS Us=:*  =(       a    T:*  Os  v   M     g7fr   r&  r'  r2   r/   s     r   r(  r)  1       1LqqA{{{{L   "%zBad boundary conditions at c              3   N   >#    U  H  nS Us=:*  =(       a    T:*  Os  v   M     g7fr   r&  r-  s     r   r(  r)  4  r.  r/  zAThe number of derivatives at boundaries does not match: expected z, got +rA   r  r  )r  )gbsvT)overwrite_aboverwrite_bzColocation matrix is singular.z0illegal value in %d-th argument of internal gbsv),r   r   r   r'   r   rF   r   rK   r+   rM   allcloserk   rJ   rO   rc   r#   r   r   r   rZ   rD   rE   r   r   r   r   r  r   r   r&   r   r   r   r   r  r   r  r   r   ru   r  asarray_chkfiniter   r   )r(   r1   r/   r0   r   rL   r)   deriv_lderiv_rr   rG   deriv_l_ordsderiv_l_valsnleftderiv_r_ordsderiv_r_valsnrightrR   r  r	  r
  r  r  rhsr2  lupivinfos     `                         r   r   r   S  s   H '\1W
5J%	GS	!	!"	N&G 	

1Aff-D(A(A
AQA *R[[1qu5%I 2 3 	3vv<yy@QRSS	vvaeq"vo:;;vv{bffQqrUQsV^,,LMM 	Av<q7&;<<< ( ) )EE!rU(OJJqM  *QWW*=>%%aAD%99 	Av!)GOOPPEE!A$R5.!JJqM  *QWW*=>%%aAD%99qA*! #- . 	.
 	y?w*$#Aq)1%1A(A1u122vv{bffQqrUQsV^,,BCCvv
Q:&&!&&1*q.12 3 	3	!qt2A201566*$Q1a66 &gwwqr{;G!4W!=Lq!E%gwwqr{;G!4W!=L"F1L1116qtfA>??1L1116qugQ?@@ 	
A	
!aB	Av ,,.qD6waxI J 	J 	vv{HHbUQWWQR[(6%%aAD%99
 KB	1R4"9q="%RZZs	CBOOA!RTT5)qy1adBBEz1aeRR')&y	2 AGGABK H
((B>
1Cqy"**2x8FUYYr84Cb6kz(00X>BKL b**RI6CYS	2EDBB)-4ABQ ax:;;	KteSTT
QYYuqwwqr{':;<A!!!!55Q  	N;G9EFAM	Ns   [' '
\1\  \qr)methodc          	      	   [        X5      n [        X5      n[        X&5      nUb  [        XF5      nO[        R                  " U 5      n[        R                  " U5      n[        XQR                  5      n[        R                  " XS5      nU R                  S:w  a  [        S5      eU R                  S   US-   :  a  [        S5      eUS:  a  [        S5      eUR                  S:w  d'  [        R                  " USS USS -
  S:  5      (       a  [        S5      eU R                  UR                  S   :w  a&  [        S	U R                   S
UR                   S35      eUS:  a8  [        R                  " XU   :  XU*    :  -  5      (       a  [        SU  S35      eU R                  UR                  :w  a&  [        S	U R                   SUR                   S35      eUS:X  a2  [        R                  " U SS U SS -
  S:*  5      (       a  [        S5      eUS:X  a'  [        U SS U SS -
  S:  5      (       a  [        S5      eUR                  U-
  S-
  nUR                  R                  S:H  n	UR                  [        5      n
U	(       a/  UR                  S:X  a  U
R!                  UR                  S   S5      n
[#        U
R                  SS 5      nU
R!                  SU5      n
UR                  R                  S:H  n	UR                  [        5      n
U	(       a/  UR                  S:X  a  U
R!                  UR                  S   S5      n
[#        U
R                  SS 5      nU
R!                  SU5      n
US:X  a  Sn[        R$                  " US-   U4[        R&                  SS9n[        R$                  " X4[        R&                  S9n[(        R*                  " XUU
UUR,                  U5        U	(       a  UR                  [.        5      nUR!                  U4UR                  SS -   5      n[1        USUUS9n[3        X4USUS9nODUS:X  a.  [5        X
X#U5      u    nnU	(       a  UR                  [.        5      nO[        SU< S35      eUR!                  U4UR                  SS -   5      n[        R6                  " U5      n[8        R;                  UUX5S9$ )a(  Compute the (coefficients of) an LSQ (Least SQuared) based
fitting B-spline.

The result is a linear combination

.. math::

        S(x) = \sum_j c_j B_j(x; t)

of the B-spline basis elements, :math:`B_j(x; t)`, which minimizes

.. math::

    \sum_{j} \left( w_j \times (S(x_j) - y_j) \right)^2

Parameters
----------
x : array_like, shape (m,)
    Abscissas.
y : array_like, shape (m, ...)
    Ordinates.
t : array_like, shape (n + k + 1,).
    Knots.
    Knots and data points must satisfy Schoenberg-Whitney conditions.
k : int, optional
    B-spline degree. Default is cubic, ``k = 3``.
w : array_like, shape (m,), optional
    Weights for spline fitting. Must be positive. If ``None``,
    then weights are all equal.
    Default is ``None``.
axis : int, optional
    Interpolation axis. Default is zero.
check_finite : bool, optional
    Whether to check that the input arrays contain only finite numbers.
    Disabling may give a performance gain, but may result in problems
    (crashes, non-termination) if the inputs do contain infinities or NaNs.
    Default is True.
method : str, optional
    Method for solving the linear LSQ problem. Allowed values are "norm-eq"
    (Explicitly construct and solve the normal system of equations), and
    "qr" (Use the QR factorization of the design matrix).
    Default is "qr".

Returns
-------
b : a BSpline object of the degree ``k`` with knots ``t``.

See Also
--------
BSpline : base class representing the B-spline objects
make_interp_spline : a similar factory function for interpolating splines
LSQUnivariateSpline : a FITPACK-based spline fitting routine
splrep : a FITPACK-based fitting routine

Notes
-----
The number of data points must be larger than the spline degree ``k``.

Knots ``t`` must satisfy the Schoenberg-Whitney conditions,
i.e., there must be a subset of data points ``x[j]`` such that
``t[j] < x[j] < t[j+k+1]``, for ``j=0, 1,...,n-k-2``.

Examples
--------
Generate some noisy data:

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> rng = np.random.default_rng()
>>> x = np.linspace(-3, 3, 50)
>>> y = np.exp(-x**2) + 0.1 * rng.standard_normal(50)

Now fit a smoothing cubic spline with a pre-defined internal knots.
Here we make the knot vector (k+1)-regular by adding boundary knots:

>>> from scipy.interpolate import make_lsq_spline, BSpline
>>> t = [-1, 0, 1]
>>> k = 3
>>> t = np.r_[(x[0],)*(k+1),
...           t,
...           (x[-1],)*(k+1)]
>>> spl = make_lsq_spline(x, y, t, k)

For comparison, we also construct an interpolating spline for the same
set of data:

>>> from scipy.interpolate import make_interp_spline
>>> spl_i = make_interp_spline(x, y)

Plot both:

>>> xs = np.linspace(-3, 3, 100)
>>> plt.plot(x, y, 'ro', ms=5)
>>> plt.plot(xs, spl(xs), 'g-', lw=3, label='LSQ spline')
>>> plt.plot(xs, spl_i(xs), 'b-', lw=3, alpha=0.7, label='interp spline')
>>> plt.legend(loc='best')
>>> plt.show()

**NaN handling**: If the input arrays contain ``nan`` values, the result is
not useful since the underlying spline fitting routines cannot deal with
``nan``. A workaround is to use zero weights for not-a-number data points:

>>> y[8] = np.nan
>>> w = np.isnan(y)
>>> y[w] = 0.
>>> tck = make_lsq_spline(x, y, t, w=~w)

Notice the need to replace a ``nan`` by a numerical value (precise value
does not matter as long as the corresponding weight is zero.)

Nr   r   zExpect x to be a 1-D sequence.zNeed more x points.r+  ra   z1Expect t to be a 1D strictly increasing sequence.r!  r"  r#  ri   rh   z and w znorm-eqr$  rC  z,Expect x to be a 1D non-decreasing sequence.rG   rA   Tr  r  r   )r3  lowerr)   )r4  r)   zUnknown method =r*  )r+   r   rr   rD   rE   r   rK   rM   r'   rJ   rO   rk   r   r   r   r   ru   r   r   r   r   _norm_eq_lsqr   complexr   r   _lsq_solve_qrr#   r   rZ   )r(   r1   r0   r/   wrL   r)   rD  rR   was_complexyyr  rF  r  r?  
cho_decomprG   r{   s                     r   r   r   i  s8   ` 	(A(A(A}A,LLOqAff-D
AQAvv{9::wwqzAaC.//1u122vv{bffQqrUQsV^a/00LMMvv<yy@QRSS1uqTaQB%i01101566vv<yy@QRSSrvvaeafn&9::LMM~#aeafnq011GHH 	

QA 77<<3&K	
Bqvv{ZZ
A& BHHQRL!H	B	!B 77<<3&K	
Bqvv{ZZ
A& BHHQRL!H	B	!B XXqsAhbjj<hh}BJJ7aA  ddC	) ((7#Ckk1$,- %Rd%2>@
j0#4*68	4qQ/1awA ,F:Q/00 	
		1$$%A
QA!!!Q!55r    c                     UR                   S:X  d   eXSS2S4   -  n[        R                  " XX45      u  pgn[        R                  " XgX5        [        R                  " XhU5      n	XeU	4$ )zSolve for the LSQ spline coeffs given x, y and knots.

`y` is always 2D: for 1D data, the shape is ``(m, 1)``.
`w` is always 1D: one weight value per `x` value.

rA   N)rK   r   rq   	qr_reducefpback)
r(   r1   r0   r/   rJ  y_wr   r  ncrG   s
             r   rI  rI  :  sc     66Q;;
4j.C((q4MArq"*s#A19r    c                   ^ ^^^^	^
^ S nS mUU4S jm
T R                   S   nU" T UT 5      m	U" T UT5      mU UU	U
U4S jn[        USU4SS9nUR                  (       a  UR                  $ [	        S	UR
                   35      e)
a  
Returns an optimal regularization parameter from the GCV criteria [1].

Parameters
----------
X : array, shape (5, n)
    5 bands of the design matrix ``X`` stored in LAPACK banded storage.
wE : array, shape (5, n)
    5 bands of the penalty matrix :math:`W^{-1} E` stored in LAPACK banded
    storage.
y : array, shape (n,)
    Ordinates.
w : array, shape (n,)
    Vector of weights.

Returns
-------
lam : float
    An optimal from the GCV criteria point of view regularization
    parameter.

Notes
-----
No checks are performed.

References
----------
.. [1] G. Wahba, "Estimating the smoothing parameter" in Spline models
    for observational data, Philadelphia, Pennsylvania: Society for
    Industrial and Applied Mathematics, 1990, pp. 45-65.
    :doi:`10.1137/1.9781611970128`

c           	         [         R                  " U5      nUS==   U-  ss'   [        S5       H9  nX4SU-
  S24==   USSU-    -  ss'   USU-   SSU-
  24==   USU-   S -  ss'   M;     U R                  S   n[         R                  " SU45      n[        U5       HK  n[        [        XT-
  S5      5       H-  n[        XS2U4   USSU-
  2XG-   4   -  5      Xg* S-
  XG-   4'   M/     MM     U$ )	a  
Assuming that the product :math:`X^T W Y` is symmetric and both ``X``
and ``Y`` are 5-banded, compute the unique bands of the product.

Parameters
----------
X : array, shape (5, n)
    5 bands of the matrix ``X`` stored in LAPACK banded storage.
w : array, shape (n,)
    Array of weights
Y : array, shape (5, n)
    5 bands of the matrix ``Y`` stored in LAPACK banded storage.

Returns
-------
res : array, shape (4, n)
    The result of the product :math:`X^T Y` stored in the banded way.

Notes
-----
As far as the matrices ``X`` and ``Y`` are 5-banded, their product
:math:`X^T W Y` is 7-banded. It is also symmetric, so we can store only
unique diagonals.

rA   Nr  ra   r         )r   r"   r-   rJ   r   rl   sum)XrJ  YW_Yr2   rR   r9   r.   s           r   compute_banded_symmetric_XT_W_YG_compute_optimal_gcv_parameter.<locals>.compute_banded_symmetric_XT_W_Yr  s    6 ggajA!qA1q56	Naaj(NAwQw1QUV9,  GGAJhh1vqA3qsA;'#&qQx#dqsdAEk2B'B#CBqD!%K  (  
r    c           	        ^ U4S jn[        U 5      n[        SS5       H"  nX#* US-
  S24==   USSU* S-   24   -  ss'   M$     SUS   S-  -  nUS==   US   -  ss'   UR                  S   m[        R                  " ST4S	9n[        TS-
  SS5       H1  n[        [        S
TU-
  S-
  5      SS5       H  nU" X6X$U5        M     M3     S/T-  US'   U$ )aY  
Inverse 3 central bands of matrix :math:`A=U^T D^{-1} U` assuming that
``U`` is a unit upper triangular banded matrix using an algorithm
proposed in [1].

Parameters
----------
A : array, shape (4, n)
    Matrix to inverse, stored in LAPACK banded storage.

Returns
-------
B : array, shape (4, n)
    3 unique bands of the symmetric matrix that is an inverse to ``A``.
    The first row is filled with zeros.

Notes
-----
The algorithm is based on the cholesky decomposition and, therefore,
in case matrix ``A`` is close to not positive defined, the function
raises LinalgError.

Both matrices ``A`` and ``B`` are stored in LAPACK banded storage.

References
----------
.. [1] M. F. Hutchinson and F. R. de Hoog, "Smoothing noisy data with
    spline functions," Numerische Mathematik, vol. 47, no. 1,
    pp. 99-106, 1985.
    :doi:`10.1007/BF01389878`

c                 l  > [        ST
U -
  S-
  5      nSnUS:X  a@  [        SUS-   5       H  nXbU* S-
  X-   4   XG* S-
  X-   4   -  -  nM!     XcU    -  nXdSU 4'   g [        SUS-   5       H:  n[        Xq-
  5      nU [        Xq5      -   n	XbU* S-
  X-   4   XH* S-
  X-   4   -  -  nM<     XdU* S-
  X-   4'   g )Nr  r           r   ra   )rl   r-   abs)r2   r.   r   DBrngrng_sumr/   r  indrR   s             r   find_b_inv_elemN_compute_optimal_gcv_parameter.<locals>.compute_b_inv.<locals>.find_b_inv_elem  s    aQ#CGAvq#'*A!a/!BFAEM2BBBG +Q4""a% q#'*Aqu:Dc!i-C!a/!EAIsz4I2JJJG + $+1"q&!%- r    rA   rW  r   Nra   rb   rV  rj   r  r`  r   )r   r-   rJ   r   r   rl   )r   rg  r   r2   rb  rc  r.   rR   s          @r   compute_b_inv5_compute_optimal_gcv_parameter.<locals>.compute_b_inv  s    D	+" Aq!Ab!A#$hK1R1"Q$Y<'K !B%!O	"2GGAJHHAq6"q1ub"%A3q!a%!),b"5aA. 6 & tax!r    c           	      2  > UR                   S   n[        SXU-  -   T5      n[        R                  " U5      nX6-  n[	        U5       HH  n	[	        [        SX-
  S-   5      [        SU	S-   5      5       H  n
Xy==   XU	S-   U
-
  4   -  ss'   M     MJ     [        R                  R                  X-  5      S-  U-  nX U-  -   n T" U5      nX-  nUSS=== S-  sss& S[        [        U5      5      U-  -
  S-  nX-  nU$ ! [         a    [        S	5      ef = f)
aW  
Computes the generalized cross-validation criteria [1].

Parameters
----------
lam : float, (:math:`\lambda \geq 0`)
    Regularization parameter.
X : array, shape (5, n)
    Matrix is stored in LAPACK banded storage.
XtWX : array, shape (4, n)
    Product :math:`X^T W X` stored in LAPACK banded storage.
wE : array, shape (5, n)
    Matrix :math:`W^{-1} E` stored in LAPACK banded storage.
XtE : array, shape (4, n)
    Product :math:`X^T E` stored in LAPACK banded storage.

Returns
-------
res : float
    Value of the GCV criteria with the regularization parameter
    :math:`\lambda`.

Notes
-----
Criteria is computed from the formula (1.3.2) [3]:

.. math:

GCV(\lambda) = \dfrac{1}{n} \sum\limits_{k = 1}^{n} \dfrac{ \left(
y_k - f_{\lambda}(x_k) \right)^2}{\left( 1 - \Tr{A}/n\right)^2}$.
The criteria is discussed in section 1.3 [3].

The numerator is computed using (2.2.4) [3] and the denominator is
computed using an algorithm from [2] (see in the ``compute_b_inv``
function).

References
----------
.. [1] G. Wahba, "Estimating the smoothing parameter" in Spline models
    for observational data, Philadelphia, Pennsylvania: Society for
    Industrial and Applied Mathematics, 1990, pp. 45-65.
    :doi:`10.1137/1.9781611970128`
.. [2] M. F. Hutchinson and F. R. de Hoog, "Smoothing noisy data with
    spline functions," Numerische Mathematik, vol. 47, no. 1,
    pp. 99-106, 1985.
    :doi:`10.1007/BF01389878`
.. [3] E. Zemlyanoy, "Generalized cross-validation smoothing splines",
    BSc thesis, 2022. Might be available (in Russian)
    `here <https://www.hse.ru/ba/am/students/diplomas/620910604>`_

r   rA   rA   r   r  rW  rA   Nra   z#Seems like the problem is ill-posed)rJ   r
   r   r   r-   rm   rl   linalgnormrX  r   r'   )lamrY  XtWXwEXtErR   rG   r9   tmpr2   r.   numerlhsb_bandedtrdenomri  r1   s                   r   _gcv,_compute_optimal_gcv_parameter.<locals>._gcv  s)   j GGAJ2Xq1hhqkfqA3q!%!),c!QUm<#Ql++ =  		sy)1,q0 3Y		D$S)HBsGqLGSW))A-E
 m
  	DBCC	Ds   7D   Dr   c                    > T" U TTTT5      $ r   r&  )ro  rY  rr  rp  ry  rq  s    r   fun+_compute_optimal_gcv_parameter.<locals>.fun3  s    CD"c**r    r   Bounded)boundsrD  z,Unable to find minimum of the GCV function: )rJ   r   successr(   r'   message)rY  rq  r1   rJ  r\  rR   r|  gcv_estrr  rp  ry  ri  s   ```     @@@@r   _compute_optimal_gcv_parameterr  O  s    F'RAFN` 	

A*1a3D
)!Q
3C+ + c1a&CGyy
 "")//!24 5 5r    c                     U R                   S   n[        R                  " U5      n[        U5       H1  nSn[        U5       H  nXS:w  d  M
  X@U   X   -
  -  nM     SU-  X#'   M3     U$ )a  
Returns the coefficients of the divided difference.

Parameters
----------
x : array, shape (n,)
    Array which is used for the computation of divided difference.

Returns
-------
res : array_like, shape (n,)
    Coefficients of the divided difference.

Notes
-----
Vector ``x`` should have unique elements, otherwise an error division by
zero might be raised.

No checks are performed.

r   rb   )rJ   r   r   r-   )r(   rR   r9   r2   r   r/   s         r   _coeff_of_divided_diffr  =  sj    , 	

A
((1+C1XqAvtad{#  b  Jr    c           	         [         R                  " U [        S9n [         R                  " U[        S9n[        U SS U SS -
  S:*  5      (       a  [	        S5      eU R
                  S:w  d0  UR
                  S:w  d   U R                  S   UR                  S   :w  a  [	        S5      eUc   [         R                  " [        U 5      5      nO4[         R                  " U5      n[        US:*  5      (       a  [	        S5      e[         R                  U S   /S	-  X S   /S	-  4   nU R                  S   nUS
::  a  [	        S5      e[        R                  XS	5      n[         R                  " SU45      n[        SS
5       H0  nXhUS
-
  2S	S24   [         R                  " US
-
  5         XxSS24'   M2     US   US'   U S   U S   -   SU S   -  -
  US   -  US   US   -   4USSS24'   U S   U S   -
  US   -  US   4US	SS24'   US   U S   U S   -
  US   -  4USSS24'   US   US   -   SU S   -  U S   -
  U S   -
  US   -  4USSS24'   US   US'   [         R                  " SU45      n	[        U SS	 5      USS	 -  U	SS2S4'   [        U SS
 5      USS
 -  U	SS2S4'   [        SUS-
  5       H8  n
X
S-      X
S-
     -
  [        X
S-
  U
S	-    5      -  X*S-
  U
S	-    -  U	SS2U
4'   M:     [        U SS 5      * USS -  U	SS2S4'   [        U SS 5      USS -  U	SS2S4'   U	S-  n	Uc  [!        XyX5      nOUS:  a  [	        S5      e[#        SXsU	-  -   U5      n[         R                  US   US   US
   -   SUS	   -  -
  -  US   -   US   US   US	   -
  -  US   -   USS US   US   US   -
  -  US   -   US   SUS   -  US   -
  US   -
  -  US   -   4   n[        R%                  XLS	5      $ )a^  
Compute the (coefficients of) smoothing cubic spline function using
``lam`` to control the tradeoff between the amount of smoothness of the
curve and its proximity to the data. In case ``lam`` is None, using the
GCV criteria [1] to find it.

A smoothing spline is found as a solution to the regularized weighted
linear regression problem:

.. math::

    \sum\limits_{i=1}^n w_i\lvert y_i - f(x_i) \rvert^2 +
    \lambda\int\limits_{x_1}^{x_n} (f^{(2)}(u))^2 d u

where :math:`f` is a spline function, :math:`w` is a vector of weights and
:math:`\lambda` is a regularization parameter.

If ``lam`` is None, we use the GCV criteria to find an optimal
regularization parameter, otherwise we solve the regularized weighted
linear regression problem with given parameter. The parameter controls
the tradeoff in the following way: the larger the parameter becomes, the
smoother the function gets.

Parameters
----------
x : array_like, shape (n,)
    Abscissas. `n` must be at least 5.
y : array_like, shape (n,)
    Ordinates. `n` must be at least 5.
w : array_like, shape (n,), optional
    Vector of weights. Default is ``np.ones_like(x)``.
lam : float, (:math:`\lambda \geq 0`), optional
    Regularization parameter. If ``lam`` is None, then it is found from
    the GCV criteria. Default is None.

Returns
-------
func : a BSpline object.
    A callable representing a spline in the B-spline basis
    as a solution of the problem of smoothing splines using
    the GCV criteria [1] in case ``lam`` is None, otherwise using the
    given parameter ``lam``.

Notes
-----
This algorithm is a clean room reimplementation of the algorithm
introduced by Woltring in FORTRAN [2]. The original version cannot be used
in SciPy source code because of the license issues. The details of the
reimplementation are discussed here (available only in Russian) [4].

If the vector of weights ``w`` is None, we assume that all the points are
equal in terms of weights, and vector of weights is vector of ones.

Note that in weighted residual sum of squares, weights are not squared:
:math:`\sum\limits_{i=1}^n w_i\lvert y_i - f(x_i) \rvert^2` while in
``splrep`` the sum is built from the squared weights.

In cases when the initial problem is ill-posed (for example, the product
:math:`X^T W X` where :math:`X` is a design matrix is not a positive
defined matrix) a ValueError is raised.

References
----------
.. [1] G. Wahba, "Estimating the smoothing parameter" in Spline models for
    observational data, Philadelphia, Pennsylvania: Society for Industrial
    and Applied Mathematics, 1990, pp. 45-65.
    :doi:`10.1137/1.9781611970128`
.. [2] H. J. Woltring, A Fortran package for generalized, cross-validatory
    spline smoothing and differentiation, Advances in Engineering
    Software, vol. 8, no. 2, pp. 104-113, 1986.
    :doi:`10.1016/0141-1195(86)90098-7`
.. [3] T. Hastie, J. Friedman, and R. Tisbshirani, "Smoothing Splines" in
    The elements of Statistical Learning: Data Mining, Inference, and
    prediction, New York: Springer, 2017, pp. 241-249.
    :doi:`10.1007/978-0-387-84858-7`
.. [4] E. Zemlyanoy, "Generalized cross-validation smoothing splines",
    BSc thesis, 2022.
    `<https://www.hse.ru/ba/am/students/diplomas/620910604>`_ (in
    Russian)

Examples
--------
Generate some noisy data

>>> import numpy as np
>>> np.random.seed(1234)
>>> n = 200
>>> def func(x):
...    return x**3 + x**2 * np.sin(4 * x)
>>> x = np.sort(np.random.random_sample(n) * 4 - 2)
>>> y = func(x) + np.random.normal(scale=1.5, size=n)

Make a smoothing spline function

>>> from scipy.interpolate import make_smoothing_spline
>>> spl = make_smoothing_spline(x, y)

Plot both

>>> import matplotlib.pyplot as plt
>>> grid = np.linspace(x[0], x[-1], 400)
>>> plt.plot(grid, spl(grid), label='Spline')
>>> plt.plot(grid, func(grid), label='Original function')
>>> plt.scatter(x, y, marker='.')
>>> plt.legend(loc='best')
>>> plt.show()

r   r   Nra   r   z"``x`` should be an ascending arrayz;``x`` and ``y`` should be one dimensional and the same sizezInvalid vector of weightsr  rV  z)``x`` and ``y`` length must be at least 5rW  rA   rU  )r   r   )r   r   )r   rA   rl  )r  r  )rU  rU  )rU  r  )ra   ra   )r  rU     r`  z/Regularization parameter should be non-negativei)r   r#   r   rO   r'   rK   rJ   onesr6   rc   r   r~   r   r-   diag_indicesr  r  r
   rZ   )r(   r1   rJ  ro  r0   rR   X_bsplrY  r2   rq  r.   rG   c_s                r   r   r   ^  s   \ 	Qe,A
Qe,A
1QR51Sb6>Q=>>vv{affkQWWQZ1771:%= & ' 	' 	yGGCFO  #qAv;;899
qtfqj!eWq[()A	
AAvDEE ""1+F 	!QA1a[AXq"u_-booa!e.DEQU(  TlAdG1!q1Q4x'6$<7tvd|+-Aa!eH1!t,fTl;Aa!eH !B%!B%-6&>!ABAafI&.0ae)ae#ae+vf~=?AafIf~AeH 
1a&	B&q!u-"15Bqr1uI&q!u-"15Bqr1uI1a!e_cFQsVO'=a!AaCj'IIsAaC[!1a4  *!BC&11AbcF:BssBwK(2301RS69BssBwK!GB
{,QA9	rJKK 	VQr\1-A	qtqtad{Q1X-.15tqtad{#ad*Bxu""&2.uAbE	AbE)AbE12QrU:	; 
<B !!!++r    c           	      b   [         R                  " U 5      n [         R                  " U5      nU R                  S:w  d  UR                  S:w  a  [        SU < SU< 35      eU R                  S   nUR                  S   nXB-
  S-
  nUS-   Us=::  a  U::  d  O  [        SU< SU< SU< S35      eUS	US-    USUS
-    :  R                  5       (       a  [        SU< S35      eXS	 XS-
  S :  R                  5       (       a  [        SU< S35      eXS-   XB-
   XXB-
  S-
   :*  R                  5       (       a  [        SU< S35      eU S   X   :  d  U S   XU-
  S-
     :  a  [        SU < SU< S35      eSU< SU < S3nU S   XS-      :  d  U S   XU-
  S
-
     ::  a  [        U5      eU R                  S   nUS-   nXB-
  S-
  nUS
:  a  g	[        SUS-   5       HN  n	X   n
US-  nX   n[         R                  " X
:  5      nXS-
  :  a  [        U5      eX   U:  d  ME  [        U5      e   g	)zCheck consistency of the data vector `x` and the knot vector `t`.

Return None if inputs are consistent, raises a ValueError otherwise.
r   z,Expect `x` and `t` be 1D sequences. Got x = z	 and t = r   z Need k+1 <= n-k-1 <= m. Got m = z, n = z	 and k = rh   NrA   z'First k knots must be ordered; got t = ra   z&Last k knots must be ordered; got t = z)Internal knots must be distinct. Got t = zOut of bounds: x = z2Schoenberg-Whitney condition is violated with t = z and x =r  )r   rF   rK   r'   rJ   rO   r-   argmax)r(   r0   r/   r   rR   nk1mesgr   nk3r.   tjtlr2   s                r   fpcheckr  	  ss   . 	

1A


1Avv{affkHA6qfUVV	
A	
A
%!)C ESA<vWvZ1&PQRSS
 	
$1Q3!Aac(!!CqfAFGG	$!E"+""$$BaV1EFF 	
A#ac
a!#a%j %%''EaHII
 	
!qt2Q3q5)/1&
aV1=>> AA6qe1MD	!A#AbEQs1uX-	
A	!A
%!)C
Qw1c!e_T	QTIIaf!8T""42:T""  r    r   )r   )r  NNr   T)r  Nr   Tr  )0rD   mathr   numpyr   scipy._lib._utilr   scipy.linalgr   r   r   r   r	   r
   scipy.optimizer    r   r   scipy.sparser   scipy.specialr   	itertoolsr   __all__r   r+   r3   r;   r   r   r   r   r   r   r   r   r  r  r  r   r   rI  r  r  r   r  r&  r    r   <module>r     s       1/ / +   "  "$
> ^P ^PBCT,+

%Sl(<~(=VYNx >?$(S6lJ6t J6b*k5\By,@Rr    