a
    Re0                     @   s.   d dl Zd dlmZ G dd dZdd ZdS )    Nc                   @   sl   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	edd Z
edd Zedd ZdS )CanonicalConstrainta  Canonical constraint to use with trust-constr algorithm.

    It represents the set of constraints of the form::

        f_eq(x) = 0
        f_ineq(x) <= 0

    where ``f_eq`` and ``f_ineq`` are evaluated by a single function, see
    below.

    The class is supposed to be instantiated by factory methods, which
    should prepare the parameters listed below.

    Parameters
    ----------
    n_eq, n_ineq : int
        Number of equality and inequality constraints respectively.
    fun : callable
        Function defining the constraints. The signature is
        ``fun(x) -> c_eq, c_ineq``, where ``c_eq`` is ndarray with `n_eq`
        components and ``c_ineq`` is ndarray with `n_ineq` components.
    jac : callable
        Function to evaluate the Jacobian of the constraint. The signature
        is ``jac(x) -> J_eq, J_ineq``, where ``J_eq`` and ``J_ineq`` are
        either ndarray of csr_matrix of shapes (n_eq, n) and (n_ineq, n),
        respectively.
    hess : callable
        Function to evaluate the Hessian of the constraints multiplied
        by Lagrange multipliers, that is
        ``dot(f_eq, v_eq) + dot(f_ineq, v_ineq)``. The signature is
        ``hess(x, v_eq, v_ineq) -> H``, where ``H`` has an implied
        shape (n, n) and provide a matrix-vector product operation
        ``H.dot(p)``.
    keep_feasible : ndarray, shape (n_ineq,)
        Mask indicating which inequality constraints should be kept feasible.
    c                 C   s(   || _ || _|| _|| _|| _|| _d S N)n_eqn_ineqfunjachesskeep_feasible)selfr   r   r   r   r   r	    r   k/var/www/sunrise/env/lib/python3.9/site-packages/scipy/optimize/_trustregion_constr/canonical_constraint.py__init__*   s    zCanonicalConstraint.__init__c                 C   s   |j \}}|j}|j}t|tj krDt|tjkrD| |jS t|tj krrt|tjkrr| |jS t||kr| ||S t|tj kr| 	|||S t|tjkr| 
|||S | ||||S dS )z5Create an instance from `PreparedConstrained` object.N)boundsr   r	   npallinfemptyn_equal_to_canonical_less_to_canonical_greater_to_canonical_interval_to_canonical)cls
constraintlbubcfunr	   r   r   r   from_PreparedConstraint2   s    
""z+CanonicalConstraint.from_PreparedConstraintc              
      sh   t d t d|ft||f fdd}fdd}fdd}| dd|||t jdt jdS )	zCreate an "empty" instance.

        This "empty" instance is required to allow working with unconstrained
        problems as if they have some constraints.
        r   c                    s     fS r   r   x)	empty_funr   r   r   R   s    z&CanonicalConstraint.empty.<locals>.func                    s     fS r   r   r   )	empty_jacr   r   r   U   s    z&CanonicalConstraint.empty.<locals>.jacc                    s    S r   r   r   v_eqv_ineq)
empty_hessr   r   r   X   s    z'CanonicalConstraint.empty.<locals>.hessZdtype)r   r   sps
csr_matrixZbool_)r   r   r   r   r   r   )r    r%   r!   r   r   G   s    
zCanonicalConstraint.emptyc           	         s    fdd}|rt jntj fdd} fdd}tdd  D }td	d  D }td
d  D }| ||||||S )a  Concatenate multiple `CanonicalConstraint` into one.

        `sparse_jacobian` (bool) determines the Jacobian format of the
        concatenated constraint. Note that items in `canonical_constraints`
        must have their Jacobians in the same format.
        c                    s>   r t  fddD  \}}n
g g  }}t|t|fS )Nc                    s   g | ]}|  qS r   r   .0cr   r   r   
<listcomp>h       z@CanonicalConstraint.concatenate.<locals>.fun.<locals>.<listcomp>)zipr   hstackr   Zeq_allZineq_allcanonical_constraintsr   r   r   e   s    

z,CanonicalConstraint.concatenate.<locals>.func                    s:   r t  fddD  \}}n
g g  }}||fS )Nc                    s   g | ]}|  qS r   r   r*   r   r   r   r-   v   r.   z@CanonicalConstraint.concatenate.<locals>.jac.<locals>.<listcomp>)r/   r1   r3   vstackr   r   r   s   s    

z,CanonicalConstraint.concatenate.<locals>.jacc           
         s   g  d}d}D ]P}||||j   }||||j  } || || ||j 7 }||j7 }q fdd}| jd }	tjj|	|	f|tdS )Nr   c                    s&   t | } D ]}||| 7 }q|S r   )r   
zeros_likedot)presulthZhess_allr   r   matvec   s    
z=CanonicalConstraint.concatenate.<locals>.hess.<locals>.matvecr&   )	r   r   appendr   shaper'   ZlinalgZLinearOperatorfloat)
r   r#   r$   Zindex_eqZ
index_ineqr,   Zvc_eqZvc_ineqr=   r   r2   r<   r   r   |   s    

z-CanonicalConstraint.concatenate.<locals>.hessc                 s   s   | ]}|j V  qd S r   )r   r*   r   r   r   	<genexpr>   r.   z2CanonicalConstraint.concatenate.<locals>.<genexpr>c                 s   s   | ]}|j V  qd S r   )r   r*   r   r   r   rA      r.   c                 S   s   g | ]
}|j qS r   )r	   r*   r   r   r   r-      r.   z3CanonicalConstraint.concatenate.<locals>.<listcomp>)r'   r6   r   sumr0   )	r   r3   sparse_jacobianr   r   r   r   r   r	   r   r5   r   concatenate]   s    		
zCanonicalConstraint.concatenatec           
         s   t d j}jd }d}t jdtd} jrBtd|fnt d|f fdd} fdd} fdd}	t d j} jrtd|fnt d|f| |||||	|S )	Nr   r&   c                    s     |  fS r   r)   r   )r   r    valuer   r   r      s    z4CanonicalConstraint._equal_to_canonical.<locals>.func                    s     | fS r   r4   r   r   r!   r   r   r      s    z4CanonicalConstraint._equal_to_canonical.<locals>.jacc                    s     | |S r   r   r"   r   r   r   r      s    z5CanonicalConstraint._equal_to_canonical.<locals>.hess)r   r   r   r?   boolrC   r'   r(   )
r   r   rE   r   r   r   r	   r   r   r   r   )r   r    r!   rE   r   r      s"    


z'CanonicalConstraint._equal_to_canonicalc           
         s   t d j} jr&td|fnt d|ft jk d}t }t r fdd} fdd} fdd}	nNt 	d | }  fdd} fd	d} fd
d}	| |||||	|S )Nr   c                    s     |  fS r   r)   r   )r   r    r   r   r   r      s    z3CanonicalConstraint._less_to_canonical.<locals>.func                    s     | fS r   r4   r   rF   r   r   r      s    z3CanonicalConstraint._less_to_canonical.<locals>.jacc                    s     | |S r   rG   r"   rH   r   r   r      s    z4CanonicalConstraint._less_to_canonical.<locals>.hessc                    s     |   fS r   r)   r   )r   r    	finite_ubr   r   r   r      s    c                    s     |  fS r   r4   r   )r   r!   rJ   r   r   r      s    c                    s    t  j}||<  | |S r   r   zerosmr   r   r#   r$   v)r   rJ   r   r   r      s    
r   r   r   rC   r'   r(   r   rB   r   nonzero)
r   r   r   r	   r   r   r   r   r   r   r   )r   r    r!   rJ   r   r   r      s&    



z&CanonicalConstraint._less_to_canonicalc           
         s   t d j} jr&td|fnt d|ft j kd}t }t r fdd} fdd} fdd}	nNt 	d | }  fdd} fd	d} fd
d}	| |||||	|S )Nr   c                    s     |  fS r   r)   r   )r   r    r   r   r   r      s    z6CanonicalConstraint._greater_to_canonical.<locals>.func                    s     |  fS r   r4   r   rF   r   r   r      s    z6CanonicalConstraint._greater_to_canonical.<locals>.jacc                    s     | | S r   rG   r"   rH   r   r   r      s    z7CanonicalConstraint._greater_to_canonical.<locals>.hessc                    s     |   fS r   r)   r   )r   r    	finite_lbr   r   r   r      s    c                    s     |   fS r   r4   r   )r   r!   rR   r   r   r      s    c                    s"   t  j}| |<  | |S r   rK   rN   )r   rR   r   r   r      s    
rP   )
r   r   r   r	   r   r   r   r   r   r   r   )r   r    r!   rR   r   r   r      s&    


z)CanonicalConstraint._greater_to_canonicalc              	      s0  t j k}	t jk}	k|| @ || @  | @ | @ t d t d t d t d jd jd jd  d  }jd }t | | | | f} 	fdd}	 fdd}
 f	dd}| |||	|
||S )	Nr      c                    sp     | }|   }|   } |  }|   } |  }|t||||ffS r   )r   r   r0   )r   feqlegeilig)r   equalgreaterintervalr   lessr   r   r   r     s    
z7CanonicalConstraint._interval_to_canonical.<locals>.func                    sj     | }| }| }|  }| }| }t|rPt||||f}nt||||f}||fS r   )r   r'   issparser6   r   )r   JrU   rV   rW   rX   rY   Zineq)r   rZ   r[   r\   r]   r   r   r   (  s    


z7CanonicalConstraint._interval_to_canonical.<locals>.jacc           	         s   d}|||  }|7 }|||  }|7 }|||  }|7 }|||  }t }||< ||< | |< || |<  | |S )Nr   )r   r7   r   )	r   r#   r$   Zn_startZv_lZv_gZv_ilZv_igrO   )	r   rZ   r[   r\   r   r]   	n_greater
n_intervaln_lessr   r   r   5  s    

z8CanonicalConstraint._interval_to_canonical.<locals>.hess)r   r   rQ   r?   r0   )r   r   r   r   r	   lb_infub_infr   r   r   r   r   r   )
r   rZ   r[   r\   r   r]   r`   ra   rb   r   r   r     s0    







	z*CanonicalConstraint._interval_to_canonicalN)__name__
__module____qualname____doc__r   classmethodr   r   rD   r   r   r   r   r   r   r   r   r      s    $


9

'
'r   c                 C   st  g }g }g }g }|D ]}|j j}|j j}	|j\}
}t|
|kr\|||
  ||	 qt|
tj kr|tjk }||| ||   ||	|  qt|tjkr|
tj k}||
| ||   ||	|   q|
tj k}|tjk}|
|k}|| @ }|| @ }| | @ | @ }||| |
|   ||| ||   ||
| ||   ||| ||   ||
| ||   ||	|  ||	|  ||	|   ||	|  ||	|   q|rt|nt	d}|r
t|nt	d}|r0t
j}t
d| f}ntj}t	d| f}|rR||n|}|rd||n|}||||fS )a  Convert initial values of the constraints to the canonical format.

    The purpose to avoid one additional call to the constraints at the initial
    point. It takes saved values in `PreparedConstraint`, modififies and
    concatenates them to the canonical constraint format.
    r   )r   rT   r_   r   r   r   r>   r   r0   r   r'   r6   r(   )r   Zprepared_constraintsrC   Zc_eqZc_ineqZJ_eqZJ_ineqr,   rT   r_   r   r   rJ   rR   rc   rd   rZ   r]   r[   r\   r6   r   r   r   r    initial_constraints_as_canonicalJ  sZ    





rj   )numpyr   Zscipy.sparsesparser'   r   rj   r   r   r   r   <module>   s
     G