
    IR-ef                         d Z ddlZddlZddlZddlZddlmZmZ ddl	m
Z
 ddlmZmZ g dZ G d d	e          Z G d
 dee          Z G d de          Zd ZddZd Zd Z G d d          Zd Zd ZdS )z
This module defines classes that deal with parameters.

It is unlikely users will need to work with these classes directly,
unless they define their own models.
    N)MagUnitQuantity)
isiterable   )array_repr_onelineget_inputs_and_params)	ParameterInputParameterErrorParameterErrorc                       e Zd ZdZdS )r   zDGeneric exception class for all exceptions pertaining to Parameters.N__name__
__module____qualname____doc__     ;lib/python3.11/site-packages/astropy/modeling/parameters.pyr   r      s        NNNNr   r   c                       e Zd ZdZdS )r
   z:Used for incorrect input parameter values and definitions.Nr   r   r   r   r
   r
      s        DDDDr   r
   c                       e Zd ZdZdS )ParameterDefinitionErrorz3Exception in declaration of class-level Parameters.Nr   r   r   r   r   r   "   s        ====r   r   c                    t          |           rS	 t          j        | t                    } n# t          t
          f$ r! t          dt          |            d          w xY wt          | t                    rnt          | t          j
                  r"t          |                                           } nt          | t          j        t          j        f          r%t          | t                    st          |           } nDt          | t                    rt          d          t          dt          |            d          | S )z,Convert a parameter to float or float array.dtypezParameter of z  could not be converted to floatz7Expected parameter to be of numerical type, not booleanz'Don't know how to convert parameter of z	 to float)r   np
asanyarrayfloat	TypeError
ValueErrorr
   type
isinstancer   ndarrayitemnumbersNumbernumberbool)values    r   _tofloatr)   &   sG   % 
	M%u555EE:& 	 	 	 &MUMMM  	 
E8	$	$ 
	E2:	&	& 
ejjll##	EGNBI6	7	7 	

5RV@W@W 	
e	E4	 	  
!E
 
 	
 "Ld5kkLLL
 
 	
 Ls	   . 2A Fc                 J     t          j                    fd            }|S )Nc                     | j         t          | j        | j                   }n| j        }r ||          S  ||          S Nunitr   r(   )selfval
self_valueop	reflecteds      r   wrapperz-_binary_arithmetic_operation.<locals>.wrapperH   sS    9 !$*di88JJJ 	'2c:&&&2j#&&&r   	functoolswraps)r2   r3   r4   s   `` r   _binary_arithmetic_operationr8   G   s>    _R	' 	' 	' 	' 	' 	' Nr   c                 F     t          j                    fd            }|S )Nc                 n    | j         t          | j        | j                   }n| j        } ||          S r,   r-   )r/   r0   r1   r2   s      r   r4   z-_binary_comparison_operation.<locals>.wrapperX   s9    9 !$*di88JJJr*c"""r   r5   r2   r4   s   ` r   _binary_comparison_operationr<   W   s8    _R# # # # # Nr   c                 F     t          j                    fd            }|S )Nc                 l    | j         t          | j        | j                   }n| j        } |          S r,   r-   )r/   r1   r2   s     r   r4   z,_unary_arithmetic_operation.<locals>.wrappere   s5    9 !$*di88JJJr*~~r   r5   r;   s   ` r   _unary_arithmetic_operationr?   d   s8    _R     Nr   c                   t    e Zd ZdZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d6 fd	Zd Zd Zd	 Zd
 Z	d Z
ed             Zed             Zed             Zej        d             Zed             Zej        d             Zd7dZed             Zej        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ej        d             Zed             Zej        d              Zed!             Zej        d"             Zed#             Zej        d$             Zed%             Zej        d&             Zed'             Zej        d(             Zed)             Zej        d*             Zed+             Zd, Z 	 	 	 	 	 	 	 	 	 	 	 	 	 d8d-Z!ed.             Z"e"j        d/             Z"ed0             Z#d1 Z$d9d2Z%d3 Z& e'e(j)                  Z* e'e(j)        d45          Z+ e'e(j,                  Z- e'e(j,        d45          Z. e'e(j/                  Z0 e'e(j/        d45          Z1 e'e(j2                  Z3 e'e(j2        d45          Z4 e'e(j5                  Z6 e'e(j5        d45          Z7 e8e(j9                  Z: e8e(j;                  Z< e8e(j=                  Z> e8e(j?                  Z@ e8e(jA                  ZB e8e(jC                  ZD eEe(jF                  ZG eEe(jH                  ZI xZJS ):r	   a  
    Wraps individual parameters.

    Since 4.0 Parameters are no longer descriptors and are based on a new
    implementation of the Parameter class. Parameters now  (as of 4.0) store
    values locally (as instead previously in the associated model)

    This class represents a model's parameter (in a somewhat broad sense). It
    serves a number of purposes:

    1) A type to be recognized by models and treated specially at class
    initialization (i.e., if it is found that there is a class definition
    of a Parameter, the model initializer makes a copy at the instance level).

    2) Managing the handling of allowable parameter values and once defined,
    ensuring updates are consistent with the Parameter definition. This
    includes the optional use of units and quantities as well as transforming
    values to an internally consistent representation (e.g., from degrees to
    radians through the use of getters and setters).

    3) Holding attributes of parameters relevant to fitting, such as whether
    the parameter may be varied in fitting, or whether there are constraints
    that must be satisfied.



    See :ref:`astropy:modeling-parameters` for more details.

    Parameters
    ----------
    name : str
        parameter name

        .. warning::

            The fact that `Parameter` accepts ``name`` as an argument is an
            implementation detail, and should not be used directly.  When
            defining a new `Model` class, parameter names are always
            automatically defined by the class attribute they're assigned to.
    description : str
        parameter description
    default : float or array
        default value to use for this parameter
    unit : `~astropy.units.Unit`
        if specified, the parameter will be in these units, and when the
        parameter is updated in future, it should be set to a
        :class:`~astropy.units.Quantity` that has equivalent units.
    getter : callable or `None`, optional
        A function that wraps the raw (internal) value of the parameter
        when returning the value through the parameter proxy (e.g., a
        parameter may be stored internally as radians but returned to
        the user as degrees). The internal value is what is used for
        computations while the proxy value is what users will interact
        with (passing and viewing). If ``getter`` is not `None`, then a
        ``setter`` must also be input.
    setter : callable or `None`, optional
        A function that wraps any values assigned to this parameter; should
        be the inverse of ``getter``.  If ``setter`` is not `None`, then a
        ``getter`` must also be input.
    fixed : bool
        if True the parameter is not varied during fitting
    tied : callable or False
        if callable is supplied it provides a way to link the value of this
        parameter to another parameter (or some other arbitrary function)
    min : float
        the lower bound of a parameter
    max : float
        the upper bound of a parameter
    bounds : tuple
        specify min and max as a single tuple--bounds may not be specified
        simultaneously with min or max
    mag : bool
        Specify if the unit of the parameter can be a Magnitude unit or not
    )fixedtiedbounds NFc                 :   t                                                       d | _        d| _        ||||t	          d          |                     |d           | _        |                     |d           | _        || _        |	                                x| _
        | _        t          |t                    r?|/|                    |j                  st!          d| d|           |j        }|j        }|| _        || _        |                     |d           d | _        | j        s| j        | j        | _        nd | _        ||	|
t	          d|           n|	|
f}|| _        || _        || _        d | _        d | _        || _        || _        d | _        d S )NFz$setter and getter must both be inputzparameter default z5 does not have units equivalent to the required unit TforcezXbounds may not be specified simultaneously with min or max when instantiating Parameter )super__init___model_model_requiredr   _create_value_wrapper_setter_getter_namestripr   _descriptionr!   r   is_equivalentr.   r   r(   _default_mag	_set_unit_internal_unit_value_fixed_tied_bounds_order
_validator_prior
_posterior_std)r/   namedescriptiondefaultr.   gettersetterrA   rB   minmaxrC   prior	posteriormag	__class__s                  r   rI   zParameter.__init__   s   " 	$6>6>CDDD11&$??11&$??
+6+<+<+>+>>t( gx(( 	$(:(:7<(H(H.0 0 0)-0 0   <DmG	t4(((
 ## 	#}(!]

"
 #/ ?8<? ?   #2 3ZF
#			r   c                     || _         d S r,   rO   )r/   ownerr`   s      r   __set_name__zParameter.__set_name__  s    


r   c                 D    | j         }|j        dk    rdS |j        d         S )Nr   r   r   )r(   shaper/   r0   s     r   __len__zParameter.__len__  s%    j9??19Q<r   c                 V    | j         }t          |j                  dk    r|g}||         S )Nr   )r(   lenrp   )r/   keyr(   s      r   __getitem__zParameter.__getitem__  s1    
u{q   GESzr   c           
         | j         }t          |t                    rt          ||                   dk    rt	          d| j         d          t          t          |                    t          |                      |          D ]\  }}| 	                    ||           d S 	 |||<   d S # t          $ r) t	          d| d| j        d|j        d                    w xY w)Nr   z7Slice assignment outside the parameter dimensions for ''zInput dimension z invalid for z parameter with dimension )r(   r!   slicert   r
   r`   ziprangeindices__setitem__
IndexErrorrp   )r/   ru   r(   oldvalueidxr0   s         r   r}   zParameter.__setitem__'  s)    :c5!! 	8C=!!Q&&)%	% % %    s{{3t99'='= >FF + +S  c****+ + %   )2s 2 2 2 2!&Q2 2  s   $B+ +3Cc                     d| j          d}|d| j         z  }| j        |d| j         z  }| j        D ]!}t	          | |          }|dvr|d| d| z  }"| j        j         d| dS )	Nrx   z, value=z, unit=)NFNNz, =())rO   r(   r.   constraintsgetattrrj   r   )r/   argsconsr0   s       r   __repr__zParameter.__repr__<  s     4:   '4:'''9 )di)))D$ 	* 	*D$%%C555 )T))C))).)33D3333r   c                     | j         S )zParameter name.rl   r/   s    r   r`   zParameter.nameL  s     zr   c                     | j         S )zParameter default value.)rS   r   s    r   rb   zParameter.defaultQ  s     }r   c                 R   | j         | j        | j        }nM| j        r,|                      | j        | j        | j                  j        }n|                      | j                  }|j        dk    r&t          j	        |
                                          S t          j	        |          S )z.The unadorned value proxied by this parameter.Nr   )rN   rM   rW   internal_unit_internal_valuer.   r(   sizer   float64r#   r/   r(   s     r   r(   zParameter.valueV  s     <DL$8KEE ! ;($*<di   T%9:::??:ejjll+++z%   r   c                    t          |t                    rt          d          | j        't	          j        |t          j                  | _        d S t	          j        |                     |          t          j                  | _        d S )NzThe .value property on parameters should be set to unitless values, not Quantity objects. To seta parameter to a quantity simply set the parameter directly without using .valuer   )	r!   r   r   rM   r   arrayr   rW   r   r   s     r   r(   zParameter.valuen  s|    eX&& 	:   <(5
;;;DKKK#%8DLL,?,?rz#R#R#RD   r   c                     | j         S )z
        The unit attached to this parameter, if any.

        On unbound parameters (i.e. parameters accessed through the
        model class, rather than a model instance) this is the required/
        default unit for the parameter.
        )_unitr   s    r   r.   zParameter.unit|  s     zr   c                 L    | j         t          d          t          d          )NzNCannot attach units to parameters that were not initially specified with unitszYCannot change the unit attribute directly, instead change the parameter to a new quantity)r.   r   )r/   r.   s     r   r.   zParameter.unit  s;    95  
 A  r   c                     |r7t          |t                    r| j        st          d|           || _        d S || _        d S )Nz<This parameter does not support the magnitude units such as )r!   r   rT   r   r   r.   )r/   r.   rG   s      r   rU   zParameter._set_unit  sa     	$((       DJJJDIIIr   c                     | j         S )z\
        Return the internal unit the parameter uses for the internal value stored.
        rV   r   s    r   r   zParameter.internal_unit  s    
 ""r   c                     || _         dS )z{
        Set the unit the parameter will convert the supplied value to the
        representation used internally.
        Nr   )r/   r   s     r   r   zParameter.internal_unit  s     ,r   c                 >    | j         | j         S | j        | j        S dS )zUnit for the input value.N)r   r.   r   s    r   
input_unitzParameter.input_unit  s+     )%%Y"94r   c                 2    | j         dS | j        | j         z  S )zQ
        This parameter, as a :class:`~astropy.units.Quantity` instance.
        N)r.   r(   r   s    r   quantityzParameter.quantity  s     
 94zDI%%r   c                     t          |t                    st          d          |j        | _        |                     |j        d           d S )Nz:The .quantity attribute should be set to a Quantity objectTrF   )r!   r   r   r(   rU   r.   )r/   r   s     r   r   zParameter.quantity  sR    (H-- 	L   ^
x}D11111r   c                 @    | j         | j        j        S | j        j        S )z*The shape of this parameter's value array.)rM   rW   rp   r   r   s    r   rp   zParameter.shape  s#     <;$$#))r   c                     t          | j        t          j                  r|dvrt	          d          d S || j        _        d S )N)r   )r   z-Cannot assign this shape to a scalar quantity)r!   r(   r   genericr   rp   r   s     r   rp   zParameter.shape  sL    dj"*-- 	%J&& !PQQQ '&  %DJr   c                 4    t          j        | j                  S )z)The size of this parameter's value array.)r   r   r(   r   s    r   r   zParameter.size  s     wtz"""r   c                     | j         S )z*Standard deviation, if available from fit.r_   r   s    r   stdzParameter.std  s     yr   c                     || _         d S r,   r   r   s     r   r   zParameter.std  s    			r   c                     | j         S r,   r]   r   s    r   rg   zParameter.prior  s
    {r   c                     || _         d S r,   r   rq   s     r   rg   zParameter.prior  s    r   c                     | j         S r,   r^   r   s    r   rh   zParameter.posterior  s
    r   c                     || _         d S r,   r   rq   s     r   rh   zParameter.posterior  s    r   c                     | j         S )zS
        Boolean indicating if the parameter is kept fixed during fitting.
        )rX   r   s    r   rA   zParameter.fixed  s    
 {r   c                 \    t          |t                    st          d          || _        dS )zFix a parameter.zValue must be booleanN)r!   r'   r   rX   r   s     r   rA   zParameter.fixed  s0     %&& 	64555r   c                     | j         S )z
        Indicates that this parameter is linked to another one.

        A callable which provides the relationship of the two parameters.
        )rY   r   s    r   rB   zParameter.tied  s     zr   c                 X    t          |          s|dvrt          d          || _        dS )zTie a parameter.)FNz/Tied must be a callable or set to False or NoneN)callabler   rY   r   s     r   rB   zParameter.tied  s7      	O5#=#=MNNN


r   c                     | j         S )z9The minimum and maximum values of a parameter as a tuple.)rZ   r   s    r   rC   zParameter.bounds  s     |r   c                    |\  }}|it          |t          j        t          f          st	          d          t          |t                    rt          |j                  }nt          |          }|it          |t          j        t          f          st	          d          t          |t                    rt          |j                  }nt          |          }||f| _        dS )z?Set the minimum and maximum values of a parameter from a tuple.Nz(Min value must be a number or a Quantityz(Max value must be a number or a Quantity)r!   r$   r%   r   r   r   r(   rZ   )r/   r(   _min_maxs       r   rC   zParameter.bounds  s     
ddW^X$>?? L JKKK$)) #TZ((T{{dW^X$>?? L JKKK$)) #TZ((T{{d|r   c                     | j         d         S )z7A value used as a lower bound when fitting a parameter.r   rC   r   s    r   re   zParameter.min0       {1~r   c                 "    || j         f| _        dS )z#Set a minimum value of a parameter.N)rf   rC   r   s     r   re   zParameter.min5  s     dh'r   c                     | j         d         S )z8A value used as an upper bound when fitting a parameter.r   r   r   s    r   rf   zParameter.max:  r   r   c                 "    | j         |f| _        dS )z#Set a maximum value of a parameter.N)re   rC   r   s     r   rf   zParameter.max?  s     x'r   c                     | fd}|S )a2  
        Used as a decorator to set the validator method for a `Parameter`.
        The validator method validates any value set for that parameter.
        It takes two arguments--``self``, which refers to the `Model`
        instance (remember, this is a method defined on a `Model`), and
        the value being set for this parameter.  The validator method's
        return value is ignored, but it may raise an exception if the value
        set on the parameter is invalid (typically an `InputParameterError`
        should be raised, though this is not currently a requirement).

        Note: Using this method as a decorator will cause problems with
        pickling the model. An alternative is to assign the actual validator
        function to ``Parameter._validator`` (see examples in modeling).

        c                 P    t          |           r	| |_        |S t          d          )NzThis decorator method expects a callable.
The use of this method as a direct validator is
deprecated; use the new validate method instead
)r   r\   r   )funcr/   s     r   	validatorz&Parameter.validator.<locals>.validatorV  s4    ~~ "& H  r   r   )r/   r   s     r   r   zParameter.validatorD  s#    $ "& 		 		 		 		 r   c                 `    | j         $| j        |                      | j        |           dS dS dS )z$Run the validator on this parameter.N)r\   rJ   r   s     r   validatezParameter.validatec  s;    ?&4;+BOODK///// '&+B+Br   c                 <   t                                                      }|d= |                                D ]X\  }}|Q|dv rt          | |          rt	          | |          }n&t          | d|z             rt	          | d|z             }|||<   Y | j        di |S )a  
        Make a copy of this `Parameter`, overriding any of its core attributes
        in the process (or an exact copy).

        The arguments to this method are the same as those for the `Parameter`
        initializer.  This simply returns a new `Parameter` instance with any
        or all of the attributes overridden, and so returns the equivalent of:

        .. code:: python

            Parameter(self.name, self.description, ...)

        r/   N)re   rf   _r   )localscopyitemshasattrr   rj   )r/   r`   ra   rb   r.   rc   rd   rA   rB   re   rf   rC   rg   rh   kwargsru   r(   s                    r   r   zParameter.copyh  s    : 6N ,,.. 	$ 	$JC} .((tS)) 9 'c 2 2 sSy11 9 'cCi 8 8#st~'''''r   c                     | j         S )z4Return the model this  parameter is associated with.)rJ   r   s    r   modelzParameter.model  s     {r   c                     || _         |                     | j        |          | _        |                     | j        |          | _        | j        r| j        | j        | _        d S d | _        d S d S r,   )rJ   rL   rM   rN   rK   rS   r(   rW   r   s     r   r   zParameter.model  sp    11$,FF11$,FF 	#}(!]


"		# 	#r   c                 ,    | j         r| j        S | j        S )ac  
        Currently for internal use only.

        Like Parameter.value but does not pass the result through
        Parameter.getter.  By design this should only be used from bound
        parameters.

        This will probably be removed are retweaked at some point in the
        process of rethinking how parameter values are stored/updated.
        )rM   r   r(   r   s    r   
_raw_valuezParameter._raw_value  s     < 	(''zr   c                 d   t          |t          j                  r)|j        dk    rt	          d          t          |          S |dS t          |          \  }}t          |          }|dk    rn@|dk    r+d| _        |!|d         j	        }t          j        |fi ||i}nt	          d          |S )aL  Wraps a getter/setter function to support optionally passing in
        a reference to the model object as the second argument.
        If a model is tied to this parameter and its getter/setter supports
        a second argument then this creates a partial function using the model
        instance as the second argument.
        r   zOA numpy.ufunc used for Parameter getter/setter may only take one input argumentN   TzIParameter getter/setter must be a function of either one or two arguments)r!   r   ufuncninr   _wrap_ufuncr   rt   rK   r`   r6   partial)r/   r4   r   inputsr   nargs	model_args          r   rL   zParameter._create_value_wrapper  s     grx(( 	{a   w'''_4-g66IFAKKEzz!'+$$ !'q	I'/NNIu;MNNG5  
 r   c                 z    t          j        | j        |          }| j        t	          || j        dd          }|S )Nr   FT)r   subok)r   asarrayr(   r.   r   )r/   r   arrs      r   	__array__zParameter.__array__  s=    j51119 3	TBBBC
r   c                 N    t          t          j        | j                            S r,   )r'   r   allr(   r   s    r   __bool__zParameter.__bool__  s    BF4:&&'''r   T)r3   )rD   rD   NNNNFFNNNNNFF)NNNNNNFFNNNNNr,   )Kr   r   r   r   r   rI   rn   rr   rv   r}   r   propertyr`   rb   r(   rd   r.   rU   r   r   r   rp   r   r   rg   rh   rA   rB   rC   re   rf   r   r   r   r   r   rL   r   r   r8   operatoradd__add____radd__sub__sub____rsub__mul__mul____rmul__pow__pow____rpow__truediv__truediv____rtruediv__r<   eq__eq__ne__ne__lt__lt__gt__gt__le__le__ge__ge__r?   neg__neg__abs__abs____classcell__)rj   s   @r   r	   r	   q   sv       I IV .K M M M M M M^           *4 4 4    X   X ! ! X!. \S S \S   X 
[
 
 [
	 	 	 	 # # X# , , ,   X & & X& _2 2 _2 * * X* \% % \% # # X#   X 	Z  Z   X \  \   X      X \  \   X 
[  [   X ]$ $ ]$*   X 	Z( ( Z(   X 	Z( ( Z(   X<0 0 0 -( -( -( -(^   X \# # \#   X& & &P   ( ( ( +*8<88G++HLDIIIH**8<88G++HLDIIIH**8<88G++HLDIIIH**8<88G++HLDIIIH..x/?@@K//0@DQQQL))(+66F))(+66F))(+66F))(+66F))(+66F))(+66F))(,77G))(,77GGGGGr   r	   c                 T    t          | j                  }| j        | d| j        }|S )z
    Like array_repr_oneline but works on `Parameter` objects and supports
    rendering parameters with units like quantities.
    N )r   r(   r.   )paramouts     r   param_repr_oneliner	    s5    
 U[
)
)Cz%%uz%%Jr   c                      d fd	}|S )Nc                 Z    | |           |z  S | | |z            S  |           S )z
        Wrap ufuncs to support passing in units
            raw_unit is the unit of the value
            orig_unit is the value after the ufunc has been applied
            it is assumed ufunc(raw_unit) == orig_unit
        r   )r(   raw_unit	orig_unitr   s      r   _wrapperz_wrap_ufunc.<locals>._wrapper  sG      5<<)++!5)***uU||r   r   r   )r   r  s   ` r   r   r   
  s(          Or   r   )r   r6   r$   r   numpyr   astropy.unitsr   r   astropy.utilsr   utilsr   r   __all__	Exceptionr   r   r
   r   r)   r8   r<   r?   r	   r	  r   r   r   r   <module>r     s              + + + + + + + + $ $ $ $ $ $ < < < < < < < <
@
@
@O O O O OY O O OE E E E E*n E E E> > > > >~ > > >  B    
 
 

 
 
K
8 K
8 K
8 K
8 K
8 K
8 K
8 K
8\      r   