
    IR-eV                     >   d Z 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mZ ddlmZ g dZd	d
giZ G d de          Z G d d	e          Z G d dej                  Z G d de          Z G d de          Z G d de          Z G d de          ZdS )zSpline models and fitters.    N)
isiterable)AstropyUserWarning   )FittableModelModelDefinitionError)	Parameter)Spline1DSplineInterpolateFitterSplineSmoothingFitterSplineExactKnotsFitterSplineSplrepFitterr	   scipyc                       e Zd ZdZdZdZi Z	 	 	 	 	 	 	 	 d fd	Zed             Z	e
d             Zd Zd Zd	 Z fd
ZddededefdZddedefdZej        d             Zej        dd            ZddZd Zd Zd Z xZS )_SplinezBase class for spline models. Nc	                 
   t                                          ||||           d| _        |                     |           |                                  ||                     |||           d S |t          d          d S )N)n_modelsmodel_set_axisnamemetaFz;If one passes a coeffs vector one needs to also pass knots!)super__init___user_knots	_init_tck_create_optional_inputs_init_spline
ValueError
selfknotscoeffsdegreeboundsr   r   r   r   	__class__s
            7lib/python3.11/site-packages/astropy/modeling/spline.pyr   z_Spline.__init__$   s     	n4d 	 	
 	
 	
 !v 	$$&&&eVV44444M        c                 n    t          t          | j                  t          | j                  z             S )zg
        Coefficient names generated based on the spline's degree and
        number of knots.
        )tuplelist_knot_names_coeff_namesr   s    r%   param_namesz_Spline.param_names@   s-     T$*++d43D.E.EEFFFr&   c                     d|  S )N_r   )args    r%   _optional_argz_Spline._optional_argH   s    3yyr&   c                     | j         D ]K}|                     |          }t          | |          rt          d| d          t	          | |d            Ld S )NzOptional argument z already exists in this class!)optional_inputsr1   hasattrr   setattr)r   r0   	attributes      r%   r   z_Spline._create_optional_inputsL   sz    ' 	/ 	/C**3//ItY'' / LLLL   i....	/ 	/r&   c                     |}| j         D ]X}||v rR|                     |          }t          | |          t          | |||                    ||= Ft	          | d          Y|S )Nz0 has already been set, something has gone wrong!)r3   r1   getattrr5   RuntimeError)r   kwargs
new_kwargsr0   r6   s        r%   _intercept_optional_inputsz"_Spline._intercept_optional_inputsV   s    
' 		 		Cf}} ..s33	4++3D)VC[999"3&PPP    r&   c                     |}| j         D ]l}|                     |          }||v r||         ||<   't          | |          %t          | |          ||<   t          | |d           \| j         |         ||<   m|S )z+Extract the optional kwargs passed to call.N)r3   r1   r8   r5   )r   argsr:   r3   r0   r6   s         r%   evaluatez_Spline.evaluatee   s     ' 	A 	AC**3//If}}'-c{$$y))5'.tY'?'?$i.... (,';C'@$$r&   c                 P     | j         di |} t                      j        |i |S )z:
        Make model callable to model evaluation.
        r   )r<   r   __call__)r   r>   r:   r$   s      r%   rA   z_Spline.__call__x   s9    
 10::6::uww0000r&   Fr   indexattrc                 B   dddt           dt          fd}dddt           dt          fd}t          j        |||          }t          j        |||          }t	          | |          }	t          ||	|         |||          }
| |
_        |	|         |
_        |
| j        |<   d	S )
a  
        Create a spline parameter linked to an attribute array.

        Parameters
        ----------
        name : str
            Name for the parameter
        index : int
            The index of the parameter in the array
        attr : str
            The name for the attribute array
        fixed : optional, bool
            If the parameter should be fixed or not
        modelr   rB   rC   c                 .    t          ||          |         S Nr8   valuerE   rB   rC   s       r%   _getterz*_Spline._create_parameter.<locals>._getter   s    5$''..r&   c                 ,    | t          ||          |<   | S rG   rH   rI   s       r%   _setterz*_Spline._create_parameter.<locals>._setter   s    */GE4  'Lr&   )rB   rC   )r   defaultfixedgettersetterN)	intstr	functoolspartialr8   r   rE   rJ   __dict__)r   r   rB   rC   rO   rK   rM   rP   rQ   rN   params              r%   _create_parameterz_Spline._create_parameter   s    &	/) 	/C 	/s 	/ 	/ 	/ 	/	) 	C 	s 	 	 	 	 "7%dCCC"7%dCCC$%%wu~U6RX
 
 

 en $dr&   	base_namec                     g }t          t          t          | |                              D ]5}| | }|                    |           |                     ||||           6t          |          S )am  
        Create a spline parameters linked to an attribute array for all
        elements in that array.

        Parameters
        ----------
        base_name : str
            Base name for the parameters
        attr : str
            The name for the attribute array
        fixed : optional, bool
            If the parameters should be fixed or not
        )rangelenr8   appendrX   r(   )r   rY   rC   rO   namesrB   r   s          r%   _create_parametersz_Spline._create_parameters   s}     3wtT223344 	= 	=E(((DLL""4e<<<<U||r&   c                      t          d          NzThis needs to be implementedNotImplementedErrorr,   s    r%   _init_parametersz_Spline._init_parameters       !"@AAAr&   c                      t          d          ra   rb   r   r    r!   r#   s       r%   
_init_dataz_Spline._init_data   re   r&   c                     |                      |||           |                                  |                     di            |                                  | j        }d S )Nr   )rh   rd   _initialize_parameters_initialize_slices
parameters)r   r    r!   r#   r/   s        r%   r   z_Spline._init_spline   sa    vv... 	##B+++!!! Or&   c                 0    d | _         d | _        || _        d S rG   )_c_t_degree)r   r"   s     r%   r   z_Spline._init_tck   s    r&   c                 ,    | j         | j        | j        dS )N)tck)ro   rn   rp   r,   s    r%   __getstate__z_Spline.__getstate__   s     
 
 	
r&   c                 V    |                      |d         |d         |d                   S )Nrr   rs   rt   )r    r!   r"   )r   )r   states     r%   __setstate__z_Spline.__setstate__   s&    }}5:eCjs}TTTr&   )NNNNNNNN)FrG   )__name__
__module____qualname____doc__r*   r+   r3   r   propertyr-   staticmethodr1   r   r<   r?   rA   rS   rR   rX   r_   abcabstractmethodrd   rh   r   r   ru   rx   __classcell__r$   s   @r%   r   r      s       ''KLO      8 G G XG   \/ / /    &1 1 1 1 1'$ '$c '$# '$S '$ '$ '$ '$R C s    . 	B B B 	B B B B
 
 
 
  

 
 
U U U U U U Ur&   r   c                       e Zd ZdZdZdZdZddiZ	 	 	 	 	 	 	 	 d  fd	Ze	d	             Z
e
j        d
             Z
e	d             Ze	d             Zej        d             Ze	d             Ze	d             Ze	d             Zej        d             Ze	d             Zej        d             Ze	d             Ze	d             Zej        d             Ze	d             Zd Zd!dZd Zd!dZd!dZ fdZd"dZd"dZ xZS )#r	   a	  
    One dimensional Spline Model.

    Parameters
    ----------
    knots :  optional
        Define the knots for the spline. Can be 1) the number of interior
        knots for the spline, 2) the array of all knots for the spline, or
        3) If both bounds are defined, the interior knots for the spline
    coeffs : optional
        The array of knot coefficients for the spline
    degree : optional
        The degree of the spline. It must be 1 <= degree <= 5, default is 3.
    bounds : optional
        The upper and lower bounds of the spline.

    Notes
    -----
    Much of the functionality of this model is provided by
    `scipy.interpolate.BSpline` which can be directly accessed via the
    bspline property.

    Fitting for this model is provided by wrappers for:
    `scipy.interpolate.UnivariateSpline`,
    `scipy.interpolate.InterpolatedUnivariateSpline`,
    and `scipy.interpolate.LSQUnivariateSpline`.

    If one fails to define any knots/coefficients, no parameters will
    be added to this model until a fitter is called. This is because
    some of the fitters for splines vary the number of parameters and so
    we cannot define the parameter set until after fitting in these cases.

    Since parameters are not necessarily known at model initialization,
    setting model parameters directly via the model interface has been
    disabled.

    Direct constructors are provided for this model which incorporate the
    fitting to data directly into model construction.

    Knot parameters are declared as "fixed" parameters by default to
    enable the use of other `astropy.modeling` fitters to be used to
    fit this model.

    Examples
    --------
    >>> import numpy as np
    >>> from astropy.modeling.models import Spline1D
    >>> from astropy.modeling import fitting
    >>> np.random.seed(42)
    >>> x = np.linspace(-3, 3, 50)
    >>> y = np.exp(-x**2) + 0.1 * np.random.randn(50)
    >>> xs = np.linspace(-3, 3, 1000)

    A 1D interpolating spline can be fit to data:

    >>> fitter = fitting.SplineInterpolateFitter()
    >>> spl = fitter(Spline1D(), x, y)

    Similarly, a smoothing spline can be fit to data:

    >>> fitter = fitting.SplineSmoothingFitter()
    >>> spl = fitter(Spline1D(), x, y, s=0.5)

    Similarly, a spline can be fit to data using an exact set of interior knots:

    >>> t = [-1, 0, 1]
    >>> fitter = fitting.SplineExactKnotsFitter()
    >>> spl = fitter(Spline1D(), x, y, t=t)
    r   Tnur   N   c	           
      Z    t                                          ||||||||           d S )N)r    r!   r"   r#   r   r   r   r   )r   r   r   s
            r%   r   zSpline1D.__init__2  sH     	) 	 		
 		
 		
 		
 		
r&   c                     | j         Jt          j        t          j        | j        dz             t          j        | j        dz             f          S | j         S )z#
        The knots vector.
        Nr   )ro   npconcatenatezerosrp   onesr,   s    r%   rr   z
Spline1D.tH  sR    
 7?>$,*++RWT\A5E-F-FG   7Nr&   c                     | j         t          d          t          |          t          | j                   k    r	|| _         d S t          d          )Nz>The model parameters must be initialized before setting knots.z:There must be exactly as many knots as previously defined.)ro   r   r\   r   rJ   s     r%   rr   z
Spline1D.tT  sY    7?P   ZZ3tw<<''DGGGL  r&   c                 B    | j         | j        dz   | j        dz             S )z%
        The interior knots.
        r   )rr   r"   r,   s    r%   
t_interiorzSpline1D.t_interiora  s%    
 vdkAo$+/(::;;r&   c                 j    | j         &t          j        t          | j                            S | j         S )z*
        The coefficients vector.
        )rn   r   r   r\   rr   r,   s    r%   rs   z
Spline1D.ch  s*    
 7?8CKK(((7Nr&   c                     | j         t          d          t          |          t          | j                   k    r	|| _         d S t          d          )Nz?The model parameters must be initialized before setting coeffs.z;There must be exactly as many coeffs as previously defined.)rn   r   r\   r   s     r%   rs   z
Spline1D.cr  sY    7?Q   ZZ3tw<<''DGGGM  r&   c                     | j         S )z7
        The degree of the spline polynomials.
        )rp   r,   s    r%   r"   zSpline1D.degree  s    
 |r&   c                 &    | j         d uo| j        d uS rG   )ro   rn   r,   s    r%   _initializedzSpline1D._initialized  s    wd":twd'::r&   c                 *    | j         | j        | j        fS )z3
        Scipy 'tck' tuple representation.
        )rr   rs   r"   r,   s    r%   tckzSpline1D.tck  s    
 ,,r&   c                     | j         r;|d         | j        k    rt          d          |d         | _        |d         | _        n"|                     |d         |d                    | j        }d S )N   ztck has incompatible degree!r   r   )r   r"   r   rr   rs   r   rl   )r   rJ   r/   s      r%   r   zSpline1D.tck  sp     	2Qx4;&& !?@@@1XDF1XDFFeAha111 Or&   c                 "    ddl m}  || j         S )z6
        Scipy bspline object representation.
        r   BSpline)scipy.interpolater   r   )r   r   s     r%   bsplinezSpline1D.bspline  s%    
 	.-----w!!r&   c                 \    ddl m} t          ||          r|j        | _        d S || _        d S )Nr   r   )r   r   
isinstancer   )r   rJ   r   s      r%   r   zSpline1D.bspline  s>    ------eW%% 	yDHHHDHHHr&   c                 *      fd j         D             S )z0
        Dictionary of knot parameters.
        c                 0    g | ]}t          |          S r   rH   ).0knotr   s     r%   
<listcomp>z"Spline1D.knots.<locals>.<listcomp>  s#    AAAd##AAAr&   )r*   r,   s   `r%   r    zSpline1D.knots  s#    
 BAAA0@AAAAr&   c                     | j         S )z,If the knots have been supplied by the user.r   r,   s    r%   
user_knotszSpline1D.user_knots  s     r&   c                     || _         d S rG   r   r   s     r%   r   zSpline1D.user_knots  s     r&   c                 *      fd j         D             S )z7
        Dictionary of coefficient parameters.
        c                 0    g | ]}t          |          S r   rH   )r   coeffr   s     r%   r   z#Spline1D.coeffs.<locals>.<listcomp>  s#    DDDe$$DDDr&   )r+   r,   s   `r%   r!   zSpline1D.coeffs  s#    
 EDDD$2CDDDDr&   c                 v    |                      ddd          | _        |                      dd          | _        d S )Nr   rr   T)rO   r   rs   )r_   r*   r+   r,   s    r%   rd   zSpline1D._init_parameters  s=    2263d2KK 33GSAAr&   c                 |   |d d g}|d         t          j        | j        dz             }n&t          j        |d         g| j        dz   z            }|d         t          j        | j        dz             }n&t          j        |d         g| j        dz   z            }|d         |d         
|| _        d}nd}|||fS )Nr   r   TF)r   r   rp   arrayr   bounding_box)r   r#   lowerupper
has_boundss        r%   _init_boundszSpline1D._init_bounds  s    >D\F!9HT\A-..EEHfQi[DL1,<=>>E!9GDL1,--EEHfQi[DL1,<=>>E!9 VAY%: &DJJJ5%''r&   c                 *   t          j        t          |          t           j                  r/t          j        |t          j        |          |f          | _        nt          |          rd| _        |r/t          j        |t          j	        |          |f          | _        nit          |          d| j        dz   z  k     rt          dd| j        dz   z   d          t          j	        |          | _        nt          d| d          | j         d S )NTr   r   zMust have at least z knots.zKnots: z must be iterable or value)r   
issubdtypetypeintegerr   r   ro   r   r   r   r\   rp   r   r   )r   r    r   r   r   s        r%   _init_knotszSpline1D._init_knots  s   =ebj11 	JneRXe__e%DEEDGG 	J#D *.%%%)HIIu::T\A%5 666$Ka1A.BKKK   (5//HuHHHIII 	r&   c                     |,t          j        t          | j                            | _        nt          j        |          | _        | j         d S rG   )r   r   r\   ro   rn   r   r   )r   r!   s     r%   _init_coeffszSpline1D._init_coeffs  s@    >hs47||,,DGGhv&&DG 	r&   c                 r     | j         |g|                     |          R   |                     |           d S rG   )r   r   r   rg   s       r%   rh   zSpline1D._init_data  sE    ;!2!26!:!:;;;;&!!!!!r&   c                      t                      j        |i |}|d         }d|v r.|d         | j        dz   k    rt          d| j        dz               | j        |fi |S )a/  
        Evaluate the spline.

        Parameters
        ----------
        x :
            (positional) The points where the model is evaluating the spline at
        nu : optional
            (kwarg) The derivative of the spline for evaluation, 0 <= nu <= degree + 1.
            Default: 0.
        r   r   r   z2Cannot evaluate a derivative of order higher than )r   r?   r"   r9   r   )r   r>   r:   xr$   s       r%   r?   zSpline1D.evaluate  s     "!42622G6>>d|dkAo--";)-q; ;  
 t|A(((((r&   c                     || j         k    r9| j                            |          }t          |j                  }||_        |S t          d| j                    )z
        Create a spline that is the derivative of this one.

        Parameters
        ----------
        nu : int, optional
            Derivative order, default is 1.
        r   r"   zMust have nu <= )r"   r   
derivativer	   rt   r   )r   r   r   r   s       r%   r   zSpline1D.derivative  sb     l---44G!333J!(J===>>>r&   c                     || j         z   dk    r9| j                            |          }t          |j                  }||_        |S t          d|| j         z              )a  
        Create a spline that is an antiderivative of this one.

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

        Notes
        -----
        Assumes constant of integration is 0
           r   r   zGSupported splines can have max degree 5, antiderivative degree will be )r"   r   antiderivativer	   rt   r   )r   r   r   r   s       r%   r   zSpline1D.antiderivative.  s|     ""l11R188G%WY777N%,N"!!D13dk1AD D  r&   )NNr   NNNNNrG   )r   )ry   rz   r{   r|   n_inputs	n_outputs
_separabler3   r   r}   rr   rQ   r   rs   r"   r   r   r   r    r   r!   rd   r   r   r   rh   r?   r   r   r   r   s   @r%   r	   r	      s       D DL HIJQiO 
 
 
 
 
 
, 	 	 X	 X
 
 X
 < < X<   X X
 
 X
   X ; ; X; - - X- 	Z  Z " " X" ^  ^ B B XB     X  ! ! ! E E XEB B B( ( ( (,  &   " " " ") ) ) ) )0? ? ? ?&       r&   c                   F    e Zd ZdZd Zd Zej        d             ZddZ	dS )_SplineFitterz
    Base Spline Fitter.
    c                     d d d| _         d S )N)residsplinefit_infor,   s    r%   r   z_SplineFitter.__init__N  s    "&$77r&   c                 R    |                                 | j        d<   || j        d<   d S )Nr   r   )get_residualr   r   r   s     r%   _set_fit_infoz_SplineFitter._set_fit_infoQ  s,    !'!4!4!6!6g"(hr&   c                      t          d          )Nz0This has not been implemented for _SplineFitter.rb   )r   rE   r   yr:   s        r%   _fit_methodz_SplineFitter._fit_methodU  s    !"TUUUr&   Nc                     |                                 }t          |t                    r"|t          d           | j        |||fi |}nt          d          |                     |           |S )Nz%1D model can only have 2 data points.z3Only spline models are compatible with this fitter.)copyr   r	   r   r   r   r   )r   rE   r   r   zr:   
model_copyr   s           r%   rA   z_SplineFitter.__call__Y  s    ZZ\\
j(++ 		} !HIII%T%j!QAA&AAFF 'E   	6"""r&   rG   )
ry   rz   r{   r|   r   r   r   r   r   rA   r   r&   r%   r   r   I  sr         8 8 8) ) ) 	V V V     r&   r   c                       e Zd ZdZd ZdS )r
   z&
    Fit an interpolating spline.
    c                    |                     dd           }|                     dd d g          }|j        r!t          j        dt                     d|_        |d d gk    r||_        ddlm}  ||||||j                  }|j	        |_
        |S )NweightsbboxzEThe current user specified knots maybe ignored for interpolating dataFr   )InterpolatedUnivariateSplinewr   rt   )popr   warningswarnr   r   r   r   r"   
_eval_argsr   )	r   rE   r   r   r:   r   r   r   r   s	            r%   r   z#SplineInterpolateFitter._fit_methodp  s    **Y--zz&4,// 	%MW"    %ED$<!%EBBBBBB--qG$%,
 
 
 %	r&   Nry   rz   r{   r|   r   r   r&   r%   r
   r
   k  s-             r&   r
   c                       e Zd ZdZd ZdS )r   z!
    Fit a smoothing spline.
    c                 L   |                     dd           }|                     dd           }|                     dd d g          }|j        r!t          j        dt                     d|_        |d d gk    r||_        ddlm}  ||||||j        |          }	|	j	        |_
        |	S )	Nsr   r   zAThe current user specified knots maybe ignored for smoothing dataFr   )UnivariateSpline)r   r   rt   r   )r   r   r   r   r   r   r   r   r"   r   r   )
r   rE   r   r   r:   r   r   r   r   r   s
             r%   r   z!SplineSmoothingFitter._fit_method  s    JJsD!!**Y--zz&4,// 	%MS"    %ED$<!%E666666!!!Q'PQRRR%	r&   Nr   r   r&   r%   r   r     s-             r&   r   c                       e Zd ZdZd ZdS )r   z6
    Fit a spline using least-squares regression.
    c                    |                     dd           }|                     dd           }|                     dd d g          }|"|j        rt          j        dt                     n|j        r|j        }nt          d          |d d gk    r||_        ddlm	}  |||||||j
                  }	|	j        |_        |	S )	Nrr   r   r   [The current user specified knots will be overwritten for by knots passed into this functionzNo knots have been providedr   )LSQUnivariateSpliner   )r   r   r   r   r   r   r9   r   r   r   r"   r   r   )
r   rE   r   r   r:   rr   r   r   r   r   s
             r%   r   z"SplineExactKnotsFitter._fit_method  s    JJsD!!**Y--zz&4,//= I&    B$"#@AAAD$<!%E999999$$Q1delSSS%	r&   Nr   r   r&   r%   r   r     s-             r&   r   c                   .     e Zd ZdZ fdZd Zd Z xZS )r   zO
    Fit a spline using the `scipy.interpolate.splrep` function interface.
    c                 ^    t                                                       d d d d| _        d S )N)fpiermsg)r   r   r   )r   r$   s    r%   r   zSplineSplrepFitter.__init__  s.    #D>>r&   c                    |                     dd           }|                     dd           }|                     dd          }|                     dd           }|                     dd d g          }	|"|j        rt          j        dt                     n|j        r|j        }|	d d gk    r|	|_        ddlm}
  |
||||	d         |	d	         |j	        |||d	

  
        \  }}}}||_
        |||fS )Nrr   r   taskr   r   r   r   )splrepr   )r   xbxert   r   rr   r   full_output)r   r   r   r   r   r   r   r   r   r"   r   )r   rE   r   r   r:   rr   r   r   r   r   r   r   r   r   r   s                  r%   r   zSplineSplrepFitter._fit_method  s-   JJsD!!JJsD!!zz&!$$**Y--zz&4,//= I&    %$D$<!%E,,,,,,"FAwAwl
 
 
Rc 	3|r&   c                 f    |d         | j         d<   |d         | j         d<   |d         | j         d<   d S )Nr   r   r   r   r   r   r   r   s     r%   r   z SplineSplrepFitter._set_fit_info  s8    $Qid%aye%ayer&   )ry   rz   r{   r|   r   r   r   r   r   s   @r%   r   r     sa         ? ? ? ? ?$ $ $L) ) ) ) ) ) )r&   r   )r|   r   rT   r   numpyr   astropy.utilsr   astropy.utils.exceptionsr   corer   r   rl   r   __all____doctest_requires__r   r	   ABCr   r
   r   r   r   r   r&   r%   <module>r     s   !   


          $ $ $ $ $ $ 7 7 7 7 7 7 5 5 5 5 5 5 5 5 ! ! ! ! ! !   #WI. FU FU FU FU FUm FU FU FURa a a a aw a a aH    CG   D    m   :    M   8    ]   D2) 2) 2) 2) 2) 2) 2) 2) 2) 2)r&   