
    biE                     
   d dl Z d dlZd dlZd dlZd dlmZ d dlmZ ddl	m
Z
 d dlmc mZ d dlmZ d dlmZmZ ddlmZmZ d	gZd
 Z edddg       G d d	             Zd Zej6                  fdZdej6                  ddZy)    N)prod)GenericAlias   )_dierckx)	csr_array)array_namespacexp_capabilities)_not_a_knotBSpline	NdBSplinec                     t        j                  | t         j                        rt         j                  S t         j                  S )z>Return np.complex128 for complex dtypes, np.float64 otherwise.)np
issubdtypecomplexfloating
complex128float64dtypes    W/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/scipy/interpolate/_ndbspline.py
_get_dtyper      s*    	}}UB../}}zz    TF)z
dask.arrayz7https://github.com/data-apis/array-api-extra/issues/488)cpu_onlyjax_jitskip_backendsc                       e Zd ZdZ ee      ZdddZed        Z	ed        Z
ed        Zdddd	Zedd
       ZddZd Zy)r   a  Tensor product spline object.

    The value at point ``xp = (x1, x2, ..., xN)`` is evaluated as a linear
    combination of products of one-dimensional b-splines in each of the ``N``
    dimensions::

       c[i1, i2, ..., iN] * B(x1; i1, t1) * B(x2; i2, t2) * ... * B(xN; iN, tN)


    Here ``B(x; i, t)`` is the ``i``-th b-spline defined by the knot vector
    ``t`` evaluated at ``x``.

    Parameters
    ----------
    t : tuple of 1D ndarrays
        knot vectors in directions 1, 2, ... N,
        ``len(t[i]) == n[i] + k + 1``
    c : ndarray, shape (n1, n2, ..., nN, ...)
        b-spline coefficients
    k : int or length-d tuple of integers
        spline degrees.
        A single integer is interpreted as having this degree for
        all dimensions.
    extrapolate : bool, optional
        Whether to extrapolate out-of-bounds inputs, or return `nan`.
        Default is to extrapolate.

    Attributes
    ----------
    t : tuple of ndarrays
        Knots vectors.
    c : ndarray
        Coefficients of the tensor-product spline.
    k : tuple of integers
        Degrees for each dimension.
    extrapolate : bool, optional
        Whether to extrapolate or return nans for out-of-bounds inputs.
        Defaults to true.

    Methods
    -------
    __call__
    derivative
    design_matrix

    See Also
    --------
    BSpline : a one-dimensional B-spline object
    NdPPoly : an N-dimensional piecewise tensor product polynomial

    Nextrapolatec                $   t        ||      \  | _        | _        \  | _        | _        t        |g| j                  | _        |d}t        |      | _	        t        j                  |      | _        | j                  j                  d   }| j                  j                  |k  rt        d| d      t        |      D ]  }| j                   |   }| j"                  |   }|j                  d   |z
  dz
  }	| j                  j                  |   |	k7  sSt        d| d| j                  j                  |    dt%        |       d	|	 d
| d       t'        | j                  j(                        }
t        j*                  | j                  |
      | _        y )NTr   zCoefficients must be at least z-dimensional.r   z,Knots, coefficients and degree in dimension z are inconsistent: got z coefficients for z knots, need at least z for k=.r   )_preprocess_inputs_k_indices_k1d_t_len_tr   asarray_asarrayboolr   r   _cshapendim
ValueErrorrangetklenr   r   ascontiguousarray)selfr-   cr.   r   r*   dtdkdndts              r   __init__zNdBSpline.__init__[   su   =OPQST=U:"$:TWdk'.A.66K,**Q-ww}}Q77<<$=dV=QRRt 
	-ABBb 1$Aww}}Q1$  $%%&C ())-q)9(: ;%%(WI-CA3 G''(c	", - -
	- &&&twwb9r   c                 ,    t        | j                        S N)tupler!   r1   s    r   r.   zNdBSpline.ky   s    TWW~r   c                 l     t         fdt         j                  j                  d         D              S )Nc              3   |   K   | ]3  }j                  j                  |d j                  |   f          5 y wr:   )r&   r#   r$   ).0r3   r1   s     r   	<genexpr>zNdBSpline.t.<locals>.<genexpr>   s9      
;<DMM$''!_dkk!n_"456
s   9<r   )r;   r,   r#   r)   r<   s   `r   r-   zNdBSpline.t}   s2      
@EdggmmTUFV@W
 
 	
r   c                 8    | j                  | j                        S r:   )r&   r(   r<   s    r   r2   zNdBSpline.c   s    }}TWW%%r   )nur   c                   | j                   j                  d   }|| j                  }t        |      }|'t	        j
                  |ft        j                        }nt	        j                  |t        j                        }|j                  dk7  s|j                  d   |k7  r%t        d|dt        | j                         d      t        |dk        rt        d|      t	        j                  |t              }|j                  }|j                  d	|d	         }t	        j                  |      }|d	   |k7  rt        d
| d|       | j                   j"                  j$                  dk(  }| j                   }|r(| j                   j                  |k(  r| j                   d   }|j'                  t              }|j                  |j                  d| dz         }|j)                         }	t	        j                  |j*                  D 
cg c]  }
|
|j"                  j,                  z   c}
t        j                        }|j                  d	   }t/        j0                  || j                   | j2                  | j4                  |||	||| j6                  
      }|j'                  | j                   j"                        }|j                  |dd	 | j                   j                  |d z         }| j9                  |      S c c}
w )aB  Evaluate the tensor product b-spline at ``xi``.

        Parameters
        ----------
        xi : array_like, shape(..., ndim)
            The coordinates to evaluate the interpolator at.
            This can be a list or tuple of ndim-dimensional points
            or an array with the shape (num_points, ndim).
        nu : sequence of length ``ndim``, optional
            Orders of derivatives to evaluate. Each must be non-negative.
            Defaults to the zeroth derivivative.
        extrapolate : bool, optional
            Whether to exrapolate based on first and last intervals in each
            dimension, or return `nan`. Default is to ``self.extrapolate``.

        Returns
        -------
        values : ndarray, shape ``xi.shape[:-1] + self.c.shape[ndim:]``
            Interpolated values at ``xi``
        r   Nr   r   )invalid number of derivative orders nu =  for ndim = r   z'derivatives must be positive, got nu = zShapes: xi.shape=z
 and ndim=r2   ).N)rF   )r#   r)   r   r'   r   zerosint64r%   r*   r+   r/   r-   anyfloatreshaper0   r(   r   kindviewravelstridesitemsizer   evaluate_ndbspliner$   r!   r"   r&   )r1   xirB   r   r*   xi_shapewas_complexccc1c1rs_strides_c1num_c_trouts                 r   __call__zNdBSpline.__call__   s   * ww}}Q**K;':4'2BBbhh/Bww!|rxx{d2 @2' B!$&&k]!-. . 26{ #KbW!MNN ZZ%(88ZZHRL)!!"%B<40
*TFKLL ggmm((C/WW477<<4/ #BWWU^ ZZ$%/0hhj jj+-::"7&' #$rxx'8'8"8 "7>@hhH 88B<))"!%!%!%!#!,!$!)!,!%!2!2

 hhtww}}%kk(3B-$''--*>>?}}S!!#"7s   	 K9c                    t        j                  |t              }|j                  d   }t	        |      |k7  rt        dt	        |       d|d      t        |      \  }\  }t        fdt        |      D              }|dd d	z   }	t        j                  |	ddd   t         j                        ddd   j                         }
t        j                  ||||
      \  }}}t        |||f      S )
a  Construct the design matrix as a CSR format sparse array.

        Parameters
        ----------
        xvals :  ndarray, shape(npts, ndim)
            Data points. ``xvals[j, :]`` gives the ``j``-th data point as an
            ``ndim``-dimensional array.
        t : tuple of 1D ndarrays, length-ndim
            Knot vectors in directions 1, 2, ... ndim,
        k : int
            B-spline degree.
        extrapolate : bool, optional
            Whether to extrapolate out-of-bounds values of raise a `ValueError`

        Returns
        -------
        design_matrix : a CSR array
            Each row of the design matrix corresponds to a value in `xvals` and
            contains values of b-spline basis elements which are non-zero
            at this value.

        r   rF   z*Data and knots are inconsistent: len(t) = z for  ndim = r   c              3   :   K   | ]  }|   |   z
  d z
    ywr   N )r?   r3   r.   len_ts     r   r@   z*NdBSpline.design_matrix.<locals>.<genexpr>   s"     Aa1Q4!+As   r   Nr   )r   r%   rJ   r)   r/   r+   r    r;   r,   cumprodrH   copyr   	_coloc_ndr   )clsxvalsr-   r.   r   r*   r"   r#   c_shapecscstridesdataindicesindptrra   s      `          @r   design_matrixzNdBSpline.design_matrix   s    0 

5.{{2q6T><SVH E9A  (:!Q'?$<"e
 AU4[AA QR[4::b2hbhh7"=BBD !) 2 25E1lH!6gv $011r   c           	      
   t        j                  ||d      }|j                  d   }|j                  dd  }|j                  |d      }g }	d }
t	        |j                  d         D ]  }||k\  rgt        j                  ||d d |f   |      }|j                  |      }|j                  d t        |j                        |j                  z
  dz
   |_        n6t        j                  |t        j                  t        |      dz
        d      }|
|j                  }
|	j                  |j                          t        j                  |	d      j                  t        |	d         f|z         }t        j                  |d|      }||
fS )Nr   r   rF   )axis)r   moveaxisr)   rK   r,   r   construct_fast
derivativer2   r/   r-   r.   rG   appendstack)r1   r2   r-   r.   rp   rB   r6   trailing_shapec_flat
new_c_listnew_tibdbnew_cs                  r   _bspline_derivative_along_axisz(NdBSpline._bspline_derivative_along_axis  sR   KK4#GGAJ1b!
v||A' 	$ABw**1fQTlA>\\"%tt1SY-12++ArxxA
/CQG}bdd#	$ !,44A!N24E1d+e|r   c                 d    t        j                  |t         j                        }t         j                        }|j
                  dk7  s|j                  d   |k7  r%t        d|dt         j                         d      t        |dk        rt        d|      t         j                  j                  d         D cg c]"  } j                  |d j                  |   f   $ }}t         j                        } j                  j                         }t!        |      D ]B  \  }}	|	dk(  r j#                  |||   ||   ||		      \  }||<   t%        ||   |	z
  d      ||<   D t'        t)         fd
|D               j+                  |      t)        |       j,                        S c c}w )a{  
        Construct a new NdBSpline representing the partial derivative.

        Parameters
        ----------
        nu : array_like of shape (ndim,)
            Orders of the partial derivatives to compute along each dimension.

        Returns
        -------
        NdBSpline
            A new NdBSpline representing the partial derivative of the original spline.

        r   r   r   rD   rE   r   z-derivative orders must be positive, got nu = N)rB   c              3   @   K   | ]  }j                  |        y wr:   )r&   )r?   r-   r1   s     r   r@   z'NdBSpline.derivative.<locals>.<genexpr>Q  s     ?At}}Q/?s   r   )r   r%   rH   r/   r-   r*   r)   r+   rI   r,   r#   r$   listr.   r(   rd   	enumerater~   maxr   r;   r&   r   )
r1   rB   nu_arrr*   r3   t_newk_newc_newrp   r6   s
   `         r   rs   zNdBSpline.derivative)  s    Bbhh/466{;;!v||A$6<rg >dff+a)* * vz?MwOPP 7<DGGMM!<L6MNOT[[^O+,NNTVV ( 	2GD!Av!%!D!DuT{E$K! "E "E5; eDkAoq1E$K	2 ???u-u%)%5%5
 	
 Os   'F-)Trb   )__name__
__module____qualname____doc__classmethodr   __class_getitem__r8   propertyr.   r-   r2   r\   rn   r~   rs   r`   r   r   r   r      s    2j $L1/3 :<   
 
 & & "&4 N"` 02 02d<,
r   c           
         t        |t              st        d| d      t        |      }	 t        |        t        j                  | D cg c]  }t        j                  |       c}t
        j                        } t        |       |k7  r$t        dt        |       dt        |       d      t        |      }t        |      D ]'  }t        j                  ||         }| |   }|j                  d   |z
  dz
  }|dk  rt        d	| d
      |j                  dk7  rt        d| d      ||dz   k  rt        dd|z  dz    d| d| d      t        j                  |      dk  j                         rt        d| d      t        t        j                  |||dz                dk  rt        d| d      t        j                   |      j#                         rt        d| d       t        d | D              }t        j$                  t        j&                  t)        |            |      }	t        j                  |	t
        j                        j*                  j-                         }
|D cg c]  }t        j                  |       }}t        |      }|D cg c]  }t        |       }}t        j.                  |t1        |      ft2              }|j5                  t
        j6                         t        |      D ]  }||   ||dt        ||         f<    t        j                  |t
        j                        }| |
||ffS # t        $ r
 | f|z  } Y *w xY wc c}w c c}w c c}w )zHelpers: validate and preprocess NdBSpline inputs.

       Parameters
       ----------
       k : int or tuple
          Spline orders
       t_tpl : tuple or array-likes
          Knots.
    z-Expect `t` to be a tuple of array-likes. Got z	 instead.r   z	len(t) = z != len(k) = r   r   r   zSpline degree in dimension z cannot be negative.zKnot vector in dimension z must be one-dimensional.zNeed at least    z knots for degree z in dimension zKnots in dimension z# must be in a non-decreasing order.z.Need at least two internal knots in dimension z should not have nans or infs.c              3   &   K   | ]	  }|d z     ywr_   r`   )r?   r5   s     r   r@   z%_preprocess_inputs.<locals>.<genexpr>  s     %R"q&%s   N)
isinstancer;   r+   r/   	TypeErrorr   r%   operatorindexrH   r,   r)   r*   diffrI   uniqueisfiniteallunravel_indexaranger   Trd   emptyr   rJ   fillnan)r.   t_tplr*   kir3   r4   r5   r6   r)   rl   r"   r-   tira   r#   s                  r   r    r    W  sU    eU#   %wi1 
 	

 u:DA
 	

32HNN2&3288DA
1v~9SZLSVKqABB u:D4[ 0ZZa!qTHHQK"q 6:1# >* + , ,77a<8 <1 2 3 3rAv:~adQhZ 8!!#N1#Q8 9 9GGBK!O  "21# 66 7 8 8ryyBq1u&'!+  ++,#Q0 1 1{{2""$21# 6. / 0 0)02 %1%%Eryye5u=G::gRXX688==?L %**qRZZ]*E*u:D$%SW%E%	4U$E	2BGGBFFO4[ ) %a1ns58}n)JJuBHH-ElRK''m  DI 4R +%s#   M 
M%5M*"M/M"!M"c           
      .   t        j                  |j                  t         j                        r8t	        | |j
                  |fi |}t	        | |j                  |fi |}|d|z  z   S |j                  dk(  r{|j                  d   dk7  rit        j                  |      }t        |j                  d         D ]7  } || |d d |f   fi |\  |d d |f<   }|dk7  s$t        d|d|d| d       |S  || |fi |\  }}|dk7  rt        d|d	|d      |S )
Ny              ?r   r   r   z	solver = z returns info =z for column r   z returns info = )r   r   r   r   _iter_solverealimagr*   r)   
empty_liker,   r+   )	ar{   solversolver_argsr   r   resjinfos	            r   r   r     s-   
 
}}QWWb0011afff<<1afff<<bg~vv{qwwqzA~mmAqwwqz" 	RA$Q!Q$?;?OC1Itqy IF;.>x|A3a!PQQ	R 
1a/;/	T19	{*;D9A>??
r   r   c                    t               }t        d  D              }	 t               t               D ]L  \  }}t        t	        j
                  |            }	|	|   k  s-t        d|	 d| d|    d|   dz    d	       t         fdt        |      D              }
t	        j                  t        j                    D cg c]  }| c}t        	      }t        j                  ||
      }d
   dk\  r|j                          |j                  }t!        |d|       t!        ||d       f}|j#                  |      }|t$        j&                  k7  r$t)        j*                  t,        |      }d|vrd|d<    |||fi |}|j#                  |||d z         }t        |
|      S # t        $ r
 f|z  Y w xY wc c}w )a  Construct an interpolating NdBspline.

    Parameters
    ----------
    points : tuple of ndarrays of float, with shapes (m1,), ... (mN,)
        The points defining the regular grid in N dimensions. The points in
        each dimension (i.e. every element of the `points` tuple) must be
        strictly ascending or descending.
    values : ndarray of float, shape (m1, ..., mN, ...)
        The data on the regular grid in n dimensions.
    k : int, optional
        The spline degree. Must be odd. Default is cubic, k=3
    solver : a `scipy.sparse.linalg` solver (iterative or direct), optional.
        An iterative solver from `scipy.sparse.linalg` or a direct one,
        `sparse.sparse.linalg.spsolve`.
        Used to solve the sparse linear system
        ``design_matrix @ coefficients = rhs`` for the coefficients.
        Default is `scipy.sparse.linalg.gcrotmk`
    solver_args : dict, optional
        Additional arguments for the solver. The call signature is
        ``solver(csr_array, rhs_vector, **solver_args)``

    Returns
    -------
    spl : NdBSpline object

    Notes
    -----
    Boundary conditions are not-a-knot in all dimensions.
    c              3   2   K   | ]  }t        |        y wr:   )r/   )r?   xs     r   r@   zmake_ndbspl.<locals>.<genexpr>  s     ,SV,s   z
There are z points in dimension z, but order z requires at least  r   z points per dimension.c              3   t   K   | ]/  }t        t        j                  |   t               |          1 yw)r   N)r
   r   r%   rJ   )r?   r3   r.   pointss     r   r@   zmake_ndbspl.<locals>.<genexpr>  s3      $ "**VAYe<adC $s   58r   r      Nr   atolgư>)r/   r;   r   r   r   
atleast_1dr+   r,   r%   	itertoolsproductrJ   r   rn   eliminate_zerosr)   r   rK   sslspsolve	functoolspartialr   )r   valuesr.   r   r   r*   rS   r3   pointnumptsr-   xvrg   matrv_shape
vals_shapevalscoefs   ` `               r   make_ndbsplr     s   > v;D,V,,HA
 f% A5R]]5)*QqT>z&1Fqc J++,Q4& 1!!"1a(>@ A AA 	 $T{$ 	$AJJY%6%6%?@r@NE ""5!Q/D 	tqy
 llGwu~&WTU^(<=J>>*%D"";v>$"&K$,,D<<745>12DQa  M  DI As   F* 	G *F=<F=)r   )r   r   r   numpyr   mathr   typesr    r   scipy.sparse.linalgsparselinalgr   scipy.sparser   scipy._lib._array_apir   r	   	_bsplinesr
   r   __all__r   r   r    gcrotmkr   r   r`   r   r   <module>r      s           ! ! " B +- 5	Dr
 r
r
h	J(Z ![[ 0J!s{{ J!r   