o
    h1                     @   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/vscode/kcb/lib/python3.10/site-packages/scipy/optimize/_trustregion_constr/canonical_constraint.py__init__*   s   
zCanonicalConstraint.__init__c                 C   s   |j \}}|j}|j}t|tj kr"t|tjkr"| |jS t|tj kr9t|tjkr9| |jS t||krF| ||S t|tj krV| 	|||S t|tjkre| 
|||S | ||||S )z5Create an instance from `PreparedConstrained` object.)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                         fS r   r   x)	empty_funr   r   r   R      z&CanonicalConstraint.empty.<locals>.func                    r   r   r   r   )	empty_jacr   r   r   U   r"   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dtype)r   r   sps
csr_matrix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                       g | ]}|  qS r   r   .0cr   r   r   
<listcomp>h       z@CanonicalConstraint.concatenate.<locals>.fun.<locals>.<listcomp>)zipr   hstackr    eq_all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                    r-   r   r   r/   r   r   r   r2   v   r3   z@CanonicalConstraint.concatenate.<locals>.jac.<locals>.<listcomp>)r4   r6   r:   vstackr   r   r   s   s   

z,CanonicalConstraint.concatenate.<locals>.jacc           
         s   g  d}d}D ](}||||j   }||||j  } || || ||j 7 }||j7 }q fdd}| jd }	tjj|	|	f|tdS )Nr   c                    s*   t j| td} D ]	}||| 7 }q	|S )Nr(   )r   
zeros_likefloatdot)presulthhess_allr   r   matvec   s   z=CanonicalConstraint.concatenate.<locals>.hess.<locals>.matvecr(   )	r   r   appendr   shaper*   linalgLinearOperatorr?   )
r    r%   r&   index_eq
index_ineqr1   vc_eqvc_ineqrF   r   r9   rD   r   r   |   s   

z-CanonicalConstraint.concatenate.<locals>.hessc                 s       | ]}|j V  qd S r   )r   r/   r   r   r   	<genexpr>       z2CanonicalConstraint.concatenate.<locals>.<genexpr>c                 s   rO   r   )r   r/   r   r   r   rP      rQ   c                 S   s   g | ]}|j qS r   )r	   r/   r   r   r   r2      s    z3CanonicalConstraint.concatenate.<locals>.<listcomp>)r*   r=   r   sumr5   )	r   r:   sparse_jacobianr   r   r   r   r   r	   r   r<   r   concatenate]   s   		
zCanonicalConstraint.concatenatec           
         s   t d j}jd }d}t jdtd} jr!td|fnt d|f fdd} fdd} fdd}	t d j} jrPtd|fnt d|f| |||||	|S )	Nr   r(   c                    s     |  fS r   r.   r   )r   r!   valuer   r   r         z4CanonicalConstraint._equal_to_canonical.<locals>.func                    s     | fS r   r;   r   r   r#   r   r   r         z4CanonicalConstraint._equal_to_canonical.<locals>.jacc                    s     | |S r   r   r$   r   r   r   r         z5CanonicalConstraint._equal_to_canonical.<locals>.hess)r   r   r   rH   boolrS   r*   r+   )
r   r   rU   r   r   r   r	   r   r   r   r   )r   r!   r#   rU   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 rA fdd} fdd} fdd}	n't 	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      rV   z3CanonicalConstraint._less_to_canonical.<locals>.func                    s     | fS r   r;   r   rW   r   r   r      rX   z3CanonicalConstraint._less_to_canonical.<locals>.jacc                    s     | |S r   rY   r$   rZ   r   r   r      r[   z4CanonicalConstraint._less_to_canonical.<locals>.hessc                    s     |   fS r   r.   r   )r   r!   	finite_ubr   r   r   r         c                    s     |  fS r   r;   r   )r   r#   r]   r   r   r      rV   c                    s    t  j}||<  | |S r   r   zerosmr   r    r%   r&   v)r   r]   r   r   r      s   
r   r   r   rS   r*   r+   r   rR   r   nonzero)
r   r   r   r	   r   r   r   r   r   r   r   )r   r!   r#   r]   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 rB fdd} fdd} fdd}	n't 	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      rV   z6CanonicalConstraint._greater_to_canonical.<locals>.func                    s     |  fS r   r;   r   rW   r   r   r      s   z6CanonicalConstraint._greater_to_canonical.<locals>.jacc                    s     | | S r   rY   r$   rZ   r   r   r      rX   z7CanonicalConstraint._greater_to_canonical.<locals>.hessc                    s     |   fS r   r.   r   )r   r!   	finite_lbr   r   r   r      r^   c                    s     |   fS r   r;   r   )r   r#   rf   r   r   r      s   c                    s"   t  j}| |<  | |S r   r_   rb   )r   rf   r   r   r      s   
rd   )
r   r   r   r	   r   r   r   r   r   r   r   )r   r!   r#   rf   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   r5   )r    feqlegeilig)r   equalgreaterintervalr   lessr   r   r   r     s   
z7CanonicalConstraint._interval_to_canonical.<locals>.func                    sp     | }| }| }|  }| }| }t|r+t||||f}||fS t||||f}||fS r   )r   r*   issparser=   r   )r    Jri   rj   rk   rl   rm   ineq)r   rn   ro   rp   rq   r   r   r   (  s   


z7CanonicalConstraint._interval_to_canonical.<locals>.jacc           	         s   d}|||  }|7 }|||  }|7 }|||  }|7 }|||  }t }||< ||< | |< || |<  | |S )Nr   )r   r>   r   )	r    r%   r&   n_startv_lv_gv_ilv_igrc   )	r   rn   ro   rp   r   rq   	n_greater
n_intervaln_lessr   r   r   5  s   

z8CanonicalConstraint._interval_to_canonical.<locals>.hess)r   r   re   rH   r5   )r   r   r   r   r	   lb_infub_infr   r   r   r   r   r   )
r   rn   ro   rp   r   rq   rz   r{   r|   r   r   r     s0   







	z*CanonicalConstraint._interval_to_canonicalN)__name__
__module____qualname____doc__r   classmethodr   r   rT   r   r   r   r   r   r   r   r   r      s"    $


9

'
'r   c                 C   sp  g }g }g }g }|D ]}|j j}|j j}	|j\}
}t|
|kr-|||
  ||	 q
t|
tj krN|tjk }||| ||   ||	|  q
t|tjkrp|
tj k}||
| ||   ||	|   q
|
tj k}|tjk}|
|k}|| @ }|| @ }| | @ | @ }||| |
|   ||| ||   ||
| ||   ||| ||   ||
| ||   ||	|  ||	|  ||	|   ||	|  ||	|   q
|rt|nt	d}|rt|nt	d}|rt
j}t
d| f}n
tj}t	d| f}|r'||n|}|r0||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`, modifies and
    concatenates them to the canonical constraint format.
    r   )r   rh   rs   r   r   r   rG   r   r5   r   r*   r=   r+   )r   prepared_constraintsrS   c_eqc_ineqJ_eqJ_ineqr1   rh   rs   r   r   r]   rf   r}   r~   rn   rq   ro   rp   r=   r   r   r   r    initial_constraints_as_canonicalJ  sZ   




r   )numpyr   scipy.sparsesparser*   r   r   r   r   r   r   <module>   s      G