U
    e»{j‚&  ã                   @   sŒ   d Z ddlZddlmZmZmZ ddlmZ ddgZ	dd„ Z
d	d„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZeeeeeeedœZdS )aÉ  
Functions to determine if a model is separable, i.e.
if the model outputs are independent.

It analyzes ``n_inputs``, ``n_outputs`` and the operators
in a compound model by stepping through the transforms
and creating a ``coord_matrix`` of shape (``n_outputs``, ``n_inputs``).


Each modeling operator is represented by a function which
takes two simple models (or two ``coord_matrix`` arrays) and
returns an array of shape (``n_outputs``, ``n_inputs``).

é    Né   )ÚCompoundModelÚModelÚModelDefinitionError)ÚMappingÚis_separableÚseparability_matrixc                 C   sT   | j dkr,| jdkr,t dg| j ¡j}|S t| ƒ}| d¡}t |dkdd¡}|S )a¸  
    A separability test for the outputs of a transform.

    Parameters
    ----------
    transform : `~astropy.modeling.core.Model`
        A (compound) model.

    Returns
    -------
    is_separable : ndarray
        A boolean array with size ``transform.n_outputs`` where
        each element indicates whether the output is independent
        and the result of a separable transform.

    Examples
    --------
    >>> from astropy.modeling.models import Shift, Scale, Rotation2D, Polynomial2D
    >>> is_separable(Shift(1) & Shift(2) | Scale(1) & Scale(2))
        array([ True,  True]...)
    >>> is_separable(Shift(1) & Shift(2) | Rotation2D(2))
        array([False, False]...)
    >>> is_separable(Shift(1) & Shift(2) | Mapping([0, 1, 0, 1]) |         Polynomial2D(1) & Polynomial2D(2))
        array([False, False]...)
    >>> is_separable(Shift(1) & Shift(2) | Mapping([0, 1, 0, 1]))
        array([ True,  True,  True,  True]...)

    r   FT)Ún_inputsÚ	n_outputsÚnpÚarrayÚTÚ
_separableÚsumÚwhere)Ú	transformr   Úseparable_matrix© r   úY/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/modeling/separable.pyr      s    
c                 C   sJ   | j dkr,| jdkr,tj| j| j ftjd�S t| ƒ}t |dkdd¡}|S )at  
    Compute the correlation between outputs and inputs.

    Parameters
    ----------
    transform : `~astropy.modeling.core.Model`
        A (compound) model.

    Returns
    -------
    separable_matrix : ndarray
        A boolean correlation matrix of shape (n_outputs, n_inputs).
        Indicates the dependence of outputs on inputs. For completely
        independent outputs, the diagonal elements are True and
        off-diagonal elements are False.

    Examples
    --------
    >>> from astropy.modeling.models import Shift, Scale, Rotation2D, Polynomial2D
    >>> separability_matrix(Shift(1) & Shift(2) | Scale(1) & Scale(2))
        array([[ True, False], [False,  True]]...)
    >>> separability_matrix(Shift(1) & Shift(2) | Rotation2D(2))
        array([[ True,  True], [ True,  True]]...)
    >>> separability_matrix(Shift(1) & Shift(2) | Mapping([0, 1, 0, 1]) |         Polynomial2D(1) & Polynomial2D(2))
        array([[ True,  True], [ True,  True]]...)
    >>> separability_matrix(Shift(1) & Shift(2) | Mapping([0, 1, 0, 1]))
        array([[ True, False], [False,  True], [ True, False], [False,  True]]...)

    r   )Zdtyper   TF)r	   r
   r   ÚonesZbool_r   r   )r   r   r   r   r   r   A   s
    c                 C   sD   t | tƒr| j}n
| jd }t |tƒr.|j}n
|jd }|| }|S )aB  
    Compute the number of outputs of two models.

    The two models are the left and right model to an operation in
    the expression tree of a compound model.

    Parameters
    ----------
    left, right : `astropy.modeling.Model` or ndarray
        If input is of an array, it is the output of `coord_matrix`.

    r   )Ú
isinstancer   r
   Úshape)ÚleftÚrightZlnoutZrnoutÚnoutpr   r   r   Ú_compute_n_outputsg   s    



r   c              
   C   sd   dd„ }|| ƒ\}}||ƒ\}}||ks0||krRt d|› d|› d|› d|› d�	ƒ‚t ||f¡}|S )a€  
    Function corresponding to one of the arithmetic operators
    ['+', '-'. '*', '/', '**'].

    This always returns a nonseparable output.


    Parameters
    ----------
    left, right : `astropy.modeling.Model` or ndarray
        If input is of an array, it is the output of `coord_matrix`.

    Returns
    -------
    result : ndarray
        Result from this operation.
    c                 S   s,   t | tƒr| j| j }}n
| j\}}||fS )N)r   r   r
   r	   r   )Úinputr
   r	   r   r   r   Ú_n_inputs_outputs“   s    

z&_arith_oper.<locals>._n_inputs_outputsz=Unsupported operands for arithmetic operator: left (n_inputs=z, n_outputs=z) and right (n_inputs=zO); models must have the same n_inputs and the same n_outputs for this operator.)r   r   r   )r   r   r   Zleft_inputsZleft_outputsZright_inputsZright_outputsÚresultr   r   r   Ú_arith_oper€   s    ÿr   c                 C   s:  t | tƒr–g }| jD ]$}t | jf¡}d||< | |¡ qt |¡}t || jf¡}|dkrv||d| j…d| j…f< n||| j d…| j d…f< |S | j	sìt || jf¡}|dkrÎd|d| j…d| j…f< nd|| j d…| j d…f< nJt || jf¡}t
| jƒD ]}d|||f< �q|dk�r6t ||| j ¡}|S )aµ  
    Create an array representing inputs and outputs of a simple model.

    The array has a shape (noutp, model.n_inputs).

    Parameters
    ----------
    model : `astropy.modeling.Model`
        model
    pos : str
        Position of this model in the expression tree.
        One of ['left', 'right'].
    noutp : int
        Number of outputs of the compound model of which the input model
        is a left or right child.

    r   r   Nr   )r   r   Úmappingr   Úzerosr	   ÚappendZvstackr
   Z	separableÚrangeZroll)ÚmodelÚposr   ZaxesÚiZaxisÚmZmatr   r   r   Ú_coord_matrix©   s.    



r(   c                 C   s´   t | |ƒ}t| tƒr"t| d|ƒ}n4t || jd f¡}| |d| jd …d| jd …f< t|tƒrnt|d|ƒ}n8t ||jd f¡}|||jd  d…|jd  d…f< t ||g¡S )a  
    Function corresponding to '&' operation.

    Parameters
    ----------
    left, right : `astropy.modeling.Model` or ndarray
        If input is of an array, it is the output of `coord_matrix`.

    Returns
    -------
    result : ndarray
        Result from this operation.

    r   r   Nr   r   )r   r   r   r(   r   r!   r   Zhstack)r   r   r   ÚcleftÚcrightr   r   r   Ú_cstackÙ   s    

 
$r+   c                 C   sd   ||  } }dd„ }|| dƒ}||dƒ}zt  ||¡}W n( tk
r^   td|› d|› �ƒ‚Y nX |S )a  
    Function corresponding to "|" operation.

    Parameters
    ----------
    left, right : `astropy.modeling.Model` or ndarray
        If input is of an array, it is the output of `coord_matrix`.

    Returns
    -------
    result : ndarray
        Result from this operation.
    c                 S   s"   t | tƒrt| || jƒ}n| }|S )zQ
        Return ``n_inputs``, ``n_outputs`` for a model or coord_matrix.
        )r   r   r(   r
   )r   ÚpositionZcoordsr   r   r   r   	  s    
z _cdot.<locals>._n_inputs_outputsr   r   zFModels cannot be combined with the "|" operator; left coord_matrix is z, right coord_matrix is )r   ÚdotÚ
ValueErrorr   )r   r   r   r)   r*   r   r   r   r   Ú_cdotø   s    



ÿ
r/   c                 C   s^   |   ¡  }tk	r|S t| tƒrBt| jƒ}t| jƒ}t| j ||ƒS t| t	ƒrZt
| d| jƒS dS )aq  
    Calculate the separability of outputs.

    Parameters
    ----------
    transform : `astropy.modeling.Model`
        A transform (usually a compound model).

    Returns :
    is_separable : ndarray of dtype np.bool
        An array of shape (transform.n_outputs,) of boolean type
        Each element represents the separablity of the corresponding output.
    r   N)Z_calculate_separability_matrixÚNotImplementedr   r   r   r   r   Ú
_operatorsÚopr   r(   r
   )r   Ztransform_matrixZsepleftZseprightr   r   r   r      s    
þ



r   )ú&ú|ú+ú-Ú*ú/z**)Ú__doc__Únumpyr   Úcorer   r   r   Zmappingsr   Ú__all__r   r   r   r   r(   r+   r/   r   r1   r   r   r   r   Ú<module>   s(   '&)0(ù