
    bio%                        d Z ddlmZ ddlmZmZmZ ddlZddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddl!m"Z"m#Z#m$Z$ ddl%m&Z& ddl'm(Z(  edg d      Z)d Z* G d de      Z+y)a+  
Copyright, the CVXPY authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain
a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
    )
namedtuple)AnyListTupleN)problems)maximum)minimum)max)min)
Inequality)	Parameter)Variable)Minimize)Canonicalization)CANON_METHODS)inversesetstighten)InverseData)SolutionBisectionData)feas_problemparamtighten_lowertighten_upperc                 |    g }g }| D ]0  }t        |      r|j                  |        |j                  |       2 ||fS N)callableappend)constraintslazy_constraintsreal_constraintscs       ]/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/cvxpy/reductions/dqcp2dcp/dqcp2dcp.py_get_lazy_and_real_constraintsr%   5   sN     'A;##A&##A&	'
 ---    c                   f     e Zd ZdZd
d fdZd Zd Zd Zd Zde	e
e   e
e   f   fdZd	 Z xZS )Dqcp2Dcpa  Reduce DQCP problems to a parameterized DCP problem.

    This reduction takes as input a DQCP problem and returns a parameterized
    DCP problem that can be solved by bisection. Some of the constraints might
    be lazy, i.e., callables that return a constraint when called. The problem
    will only be DCP once the lazy constraints are replaced with actual
    constraints.

    Problems emitted by this reduction can be solved with the `cp.bisect`
    function.
   returnc                 F    t         t        |   t        |       d | _        y )N)canon_methodsproblem)superr(   __init__r   _bisection_data)selfr,   	__class__s     r$   r.   zDqcp2Dcp.__init__L   s$    h&' 	' 	:#r&   c                 ^    t        |j                        t        k(  xr |j                         S )z>A problem is accepted if it is (a minimization) DQCP.
        )type	objectiver   is_dqcp)r0   r,   s     r$   acceptszDqcp2Dcp.acceptsQ   s&     G%%&(2Hw7HHr&   c                    |j                   D ci c]   }||j                  v r||j                  |   " }}|j                   D ]  }||vsd||<    t        |j                  |j                  |i |j
                        S c c}w )Ng        )id_mapprimal_varsr   statusopt_valattr)r0   solutioninverse_datavidpvarss        r$   invertzDqcp2Dcp.invertV   s    ;G;N;N 1C8/// h**3// 1 1&& 	!C% c
	! )9)95" ' 	'1s   %A>c                    g }|j                   D ]  }|| j                  |      z  } t        |      \  }}t        j                  j                  t        d      |      }||_        |j                  j                  }|j                         rt        d      }n'|j                         rt        d      }n
t               }|| j                  ||k        z  }t        |      \  }}t        j                  j                  t        d      |      }	||	_        t        ||gt        j                  |       |	_        |	t#        |      fS )zERecursively canonicalize the objective and every constraint.
        r   T)nonneg)nonpos)r    _canonicalize_constraintr%   r   r,   Problemr   _lazy_constraintsr4   expr	is_nonnegr   	is_nonposr   r   tighten_fnsr/   r   )
r0   r,   r    constrlazyrealr   r4   tparam_problems
             r$   applyzDqcp2Dcp.apply`   s+    )) 	AF488@@K	A3K@
d''//TB)-&%%**	 &A  "&AAt44Y!^DD3K@
d ((00!dC*.'(5!)>%11)<)>%k'222r&   c                 j    | j                  |      \  }}| j                  ||d      \  }}||z  }||fS )NFcanonicalize_params)_canon_argscanonicalize_expr)r0   rH   
canon_argsconstrs
canon_exprr#   s         r$   _canonicalize_treezDqcp2Dcp._canonicalize_treez   sG    "..t4
G..tZUZ.[
A17""r&   c                    g }g }|j                   D ]p  }| j                  |      \  }}t        |t              r?|j	                         rd|j
                  d<   n|j                         rd|j
                  d<   ||gz  }||z  }r ||fS )zxCanonicalize arguments of an expression.

        Like Canonicalization.canonicalize_tree, but preserves signs.
        TrC   rD   )argsrZ   
isinstancer   rI   
attributesrJ   )r0   rH   rW   rX   arg	canon_argr#   s          r$   rU   zDqcp2Dcp._canon_args   s    
 
99 	C2237LIq)X.==?59I((2]]_59I((29+%JqLG	 7""r&   c                    |j                         r| j                  |d      \  }}|g|z   S |j                  d   }|j                  d   }t        |t              rt        j                  |j                        }t        j                  |j                        }t        j                  |t
        j                   k(        s&t        j                  |t
        j                  k(        rdgS t        j                  |t
        j                  k(        s't        j                  |t
        j                   k(        rdgS t        |t              sJ |j                         r| j                  d|k        S |j                         r| j                  |dk        S |j                         rP|j                         s?|j                         sJ |       t!        j"                  |      r t!        j                   |      |      }|j%                         d   }|j                  |   }	|j'                  |      r| j                  |	|k        S |j)                  |      sJ | j                  |	|k\        S t        |t*        t,        f      r5|j                  D 
cg c]  }
| j                  |
|k        D ]  }|  c}}
S | j/                  |      \  }}t1        j2                  |j5                  |      |      }||z   S |j7                         sJ |j                         sJ t!        j"                  |      r t!        j                   |      |      }|j%                         d   }|j                  |   }	|j'                  |      r| j                  ||	k        S |j)                  |      sJ | j                  ||	k\        S t        |t8        t:        f      r5|j                  D 
cg c]  }
| j                  ||
k        D ]  }|  c}}
S | j/                  |      \  }}t1        j<                  |j5                  |      |      }||z   S c c}}
w c c}}
w )ah  Recursively canonicalize a constraint.

        The DQCP grammar has expresions of the form

            INCR* QCVX DCP

        and

            DECR* QCCV DCP

        ie, zero or more real/scalar increasing (or decreasing) atoms, composed
        with a quasiconvex (or quasiconcave) atom, composed with DCP
        expressions.

        The monotone functions are inverted by applying their inverses to
        both sides of a constraint. The QCVX (QCCV) atom is lowered by
        replacing it with its sublevel (superlevel) set. The DCP
        expressions are canonicalized via graph implementations.
        FrS   r      T)rO   )is_dcpcanonicalize_treer\   r]   r   nparrayvalueallinfanyis_zerorE   is_quasiconvex	is_convexis_constantr   
invertible_non_const_idxis_incris_decrr   max_atomrU   r   sublevelcopyis_quasiconcaver	   min_atom
superlevel)r0   rL   canon_constr
aux_constrlhsrhslhs_valrhs_validxrH   r_   r#   rW   aux_args_constrsublevel_setsuperlevel_sets                   r$   rE   z!Dqcp2Dcp._canonicalize_constraint   s   ( ==?'+'='=fZ_'='`$L* >J..kk!nkk!nfj)hhsyy)Ghhsyy)Gvvg"&&()RVVGrvv4E-Fv266)*bffW5G.Hw &*--- ;;=00c::;;=00::??$)c)$!!#&*gooc*3/((*1-xx};;s#88EE{{3'''44TS[AAC'8!45%(XX Lc!%!>!>scz!JL  L L L /3.>.>s.C+
O#}}SXXj-ASI#o55 ""$$$   c"&'//#&s+C$$&q)C88C=D{{344SD[AA;;s###00==gx01!$ H#!::3#:FH  HA H H +/*:*:3*?'J!__SXXj-ASIN!O339L,Hs   "Q "Qr   )r)   N)__name__
__module____qualname____doc__r.   r6   rA   rQ   rZ   r   r   r   rU   rE   __classcell__)r1   s   @r$   r(   r(   @   sF    
$
I
'34##5cDI)=#> #$Z4r&   r(   ),r   collectionsr   typingr   r   r   numpyre   cvxpyr   cvxpy.atoms.elementwise.maximumr   cvxpy.atoms.elementwise.minimumr	   cvxpy.atoms.maxr
   rs   cvxpy.atoms.minr   rw   cvxpy.constraintsr   %cvxpy.expressions.constants.parameterr   cvxpy.expressions.variabler   cvxpy.problems.objectiver   !cvxpy.reductions.canonicalizationr   (cvxpy.reductions.dcp2cone.canonicalizersr   cvxpy.reductions.dqcp2dcpr   r   r   cvxpy.reductions.inverse_datar   cvxpy.reductions.solutionr   r   r%   r(    r&   r$   <module>r      sl    # # #   3 3 + + ( ; / - > B < < 5 . ?A
.l4 l4r&   