
    biH                         d Z ddlmZ ddl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ZdZdZ dZ!dZ"dZdZdZ#dZ$ G d d      Z% G d d      Z&y)a2  
Copyright 2020 the CVXPY developers

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.
    )OptionalN)settings)ExpCone)NonNeg)	PowCone3D)PSD)SOC)Zero)Solutionfr0+edeqspp3dp3c                   0    e Zd ZdZed        Zed        Zy)Dualizea
  
    CVXPY represents cone programs as

        (P-Opt) min{ c.T @ x : A @ x + b in K } + d,

    where the corresponding dual is

        (D-Opt) max{ -b @ y : c = A.T @ y, y in K^* } + d.

    For some solvers, it is much easier to specify a problem of the form (D-Opt) than it
    is to specify a problem of the form (P-Opt). The purpose of this reduction is to handle
    mapping between (P-Opt) and (D-Opt) so that a solver interface can pretend the original
    problem was stated in terms (D-Opt).

    Usage
    -----
    Dualize applies to ParamConeProg problems. It accesses (P-Opt) data by calling
    ``c, d, A, b = problem.apply_parameters()``. It assumes the solver interface
    has already executed its ``format_constraints`` function on the ParamConeProg problem.

    A solver interface is responsible for calling both Dualize.apply and Dualize.invert.
    The call to Dualize.apply should be one of the first things that happens, and the
    call to Dualize.invert should be one of the last things that happens.

    The "data" dict returned by Dualize.apply is keyed by s.A, s.B, s.C, and 'K_dir',
    which respectively provide the dual constraint matrix (A.T), the dual constraint
    right-hand-side (c), the dual objective vector (-b), and the dual cones (K^*).
    The solver interface should interpret this data is a new primal problem, just with a
    maximization objective. Given a numerical solution, the solver interface should first
    construct a CVXPY Solution object where :math:`y` is a primal variable, divided into
    several blocks according to the structure of elementary cones appearing in K^*. The only
    dual variable we use is that corresponding to the equality constraint :math:`c = A^T y`.
    No attempt should be made to map unbounded / infeasible status codes for (D-Opt) back
    to unbounded / infeasible status codes for (P-Opt); all such mappings are handled in
    Dualize.invert. Refer to Dualize.invert for detailed documentation.

    Assumptions
    -----------
    The problem has no integer or boolean constraints. This is necessary because strong
    duality does not hold for problems with discrete constraints.

    Dualize.apply assumes "SOLVER.format_constraints()" has already been called. This
    assumption allows flexibility in how a solver interface chooses to vectorize a
    feasible set (e.g. how to order conic constraints, or how to vectorize the PSD cone).

    Additional notes
    ----------------

    Dualize.invert is written in a way which is agnostic to how a solver formats constraints,
    but it also imposes specific requirements on the input. Providing correct input to
    Dualize.invert requires consideration to the effect of ``SOLVER.format_constraints`` and
    the output of ``problem.apply_parameters``.
    c                    | j                         \  }}}}| j                  }t        |j                  t        |j
                  t        |j                  t        |j                  t        |j                  t        |j                  i}t        j                  |j                   t        j"                  |t        j$                  | d|ddi}t        j&                  |d| j(                  d| j*                  j,                  d|ddi}||fS )NK_dirdualizedT
constr_mapx_id)apply_parameters	cone_dimsFREEzeroNONNEGnonnegr	   socr   psdDUAL_EXPexp
DUAL_POW3Dp3dr   ATBC
OBJ_OFFSETr   xid)	problemcdr(   bKpKddatainv_datas	            c/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/cvxpy/reductions/cone2cone/affine2direct.pyapplyzDualize.apply`   s    --/
1a"''BIIbff
 CCCCCC!R
 LL!',,GIILLR
 X~    c                    | j                   }| j                  }d\  }}|t        j                  v rB| j                  |t        j
                     z   }|d   | j                  t        j                     i}t               }| j                  }|d   }d}	|t           D ]X  }
|t           |	|	|
j                  z    }|j                  dkD  r|n|j                         ||
j                  <   |	|
j                  z  }	Z d}	|t           D ]X  }
|t            |	|	|
j                  z    }|j                  dkD  r|n|j                         ||
j                  <   |	|
j                  z  }	Z d}	|t"           D ]G  }
|
j$                  d   }t'        j(                  |t*           |	|	|z          }|||
j                  <   |	|z  }	I t-        |t.                 D ]   \  }	}
|t0           |	   }|||
j                  <   " d}	|t2           D ]9  }
|t4           |	|	|
j                  z    }|||
j                  <   |	|
j                  z  }	; d}	|t6           D ]9  }
|t8           |	|	|
j                  z    }|||
j                  <   |	|
j                  z  }	; n|t        j:                  k(  r"t        j<                  }t&        j>                   }n|t        j@                  k(  r"t        jB                  }t&        j>                   }n|t        j<                  k(  r!t        j:                  }t&        j>                  }nT|t        jB                  k(  r!t        j@                  }t&        j>                  }n t        jD                  }t&        jF                  }tI        |||||      }|S )aB	  
        ``solution`` is a CVXPY Solution object, formatted where

            (D-Opt) max{ -b @ y : c = A.T @ y, y in K^* } + d

        is the primal problem from the solver's perspective. The purpose of this function
        is to map such a solution back to the format

                (P-Opt) min{ c.T @ x : A @ x + b in K } + d.

        This function handles mapping of primal and dual variables, and solver status codes.
        The variable "x" in (P-Opt) is trivially populated from the dual variables to the
        constraint "c = A.T @ y" in (D-Opt). Status codes also map back in a simple way.

        Details on required formatting of solution.primal_vars
        ------------------------------------------------------

        We assume the dict solution.primal_vars is keyed by string-enums FREE ('fr'), NONNEG ('+'),
        SOC ('s'), PSD ('p'), and DUAL_EXP ('de'). The corresponding values are described below.

        solution.primal_vars[FREE] should be a single vector. It corresponds to the (possibly
        concatenated) components of "y" which are subject to no conic constraints. We map these
        variables back to dual variables for equality constraints in (P-Opt).

        solution.primal_vars[NONNEG] should also be a single vector, this time giving the
        possibly concatenated components of "y" which must be >= 0. We map these variables
        back to dual variables for inequality constraints in (P-Opt).

        solution.primal_vars[SOC] is a list of vectors specifying blocks of "y" which belong
        to the second-order-cone under the CVXPY standard ({ z : z[0] >= || z[1:] || }).
        We map these variables back to dual variables for SOC constraints in (P-Opt).

        solution.primal_vars[PSD] is a list of symmetric positive semidefinite matrices
        which result by lifting the vectorized PSD blocks of "y" back into matrix form.
        We assign these as dual variables to PSD constraints appearing in (P-Opt).

        solution.primal_vars[DUAL_EXP] is a vector of concatenated length-3 slices of y, where
        each constituent length-3 slice belongs to dual exponential cone as implied by the CVXPY
        standard of the primal exponential cone (see cvxpy/constraints/exponential.py:ExpCone).
        We map these back to dual variables for exponential cone constraints in (P-Opt).

        )NNr   r   r      )%statusattrr   SOLUTION_PRESENTopt_valr,   	dual_varsEQ_DUALdictprimal_varsZero_objr   sizeitemr.   
NonNeg_objr    SOC_objshapenpconcatenater	   	enumeratePSD_objr   ExpCone_objr$   PowCone_objr&   
INFEASIBLE	UNBOUNDEDinfINFEASIBLE_INACCURATEUNBOUNDED_INACCURATESOLVER_ERRORnanr   )solutionr6   r<   	prob_attrrC   r@   r?   direct_primsr   icondv	block_lensols                 r7   invertzDualize.invert|   s+   X MM	!+YQ'''&&!,,)??G#F+#--aii8:KI#//L!,/JA!(+ !$'!chh,7*,''A+B2779	#&&!SXX A!*- !&)!AL9*,''A+B2779	#&&!SXX A!'* IIaL	^^L$5aI$FG$&	#&&!Y	
 $Jw$78 '3!#&q)$&	#&&!' A!+. !(+Aa#((l;$&	#&&!SXX A!+. !*-aCHH=$&	#&&!SXX q||#[[FvvgGq...++FvvgGq{{"\\FffGq---,,FffG^^FffGvwY	J
r9   N)__name__
__module____qualname____doc__staticmethodr8   r_    r9   r7   r   r   )   s2    4l  6 b br9   r   c            	           e Zd ZdZed        Zededeej                     de
dej                  fd       Zed        Zy	)
Slacksa  
    CVXPY represents mixed-integer cone programs as

        (Aff)   min{ c.T @ x : A @ x + b in K,
                              x[bools] in {0, 1}, x[ints] in Z } + d.

    Some solvers do not accept input in the form (Aff). A general pattern we find
    across solver types is that the feasible set is represented by

        (Dir)   min{ f @ y : G @ y <=_{K_aff} h, y in K_dir
                             y[bools] in {0, 1}, y[ints] in Z } + d,

    where K_aff is built from a list convex cones which includes the zero cone (ZERO),
    and K_dir is built from a list of convex cones which includes the free cone (FREE).

    This reduction handles mapping back and forth between problems stated in terms
    of (Aff) and (Dir), by way of adding slack variables.

    Notes
    -----
    Support for semidefinite constraints has not yet been implemented in this
    reduction.

    If the problem has no integer constraints, then the Dualize reduction should be
    used instead.

    Because this reduction is only intended for mixed-integer problems, this reduction
    makes no attempt to recover dual variables when mapping between (Aff) and (Dir).
    c                 r   | j                         \  }}}}| }| j                  }|j                  r
t               |D ])  }|t        t
        t        t        t        hvs!t                t        |vr|j                  t               t        |j                  t
        |j                  t        t        |j                        t        d|j                  z  t        dt        |j                         z  i}t        dt
        |t           t        |t           |t
           z   t        |t           |t
           z   |t           z   t        |t           |t
           z   |t           z   |t           z   i}	g g }}
g g }}d}t        t
        t        t        t        fD ]  }||   }|dkD  s|	|   }||||z   ddf   }||||z    }||v r#|
j                  |       |j                  |       P||j"                  z  }|j                  |       |j                  |        t$        | j&                  j"                  t
        t
        |v rdn|j                  t        t        |v rg n|j                  t        t        |v rdn|j                  t(        g t*        dt        t        |v rg n|j                   t,        g i}t
        t
        |v r|j                  ndt        t        |v r|j                  ng t        t        |v r|j                  ndt(        g t        |j                  |z   t        t        |v r|j                   ng i}t/               }|rt0        j2                  j5                  t7        |            }t0        j2                  j9                  |      }|
rht0        j2                  j5                  t7        |
      d      }
t0        j2                  j;                  ||g|
dgg      }t=        j>                  ||z         }n6t0        j2                  jA                  ||f      }t=        j>                  |      }t=        j>                  |t=        jB                  |      f      }nN|
rBt0        j2                  j5                  t7        |
      d      }t=        j>                  |      }|}n
tE               ||tF        jH                  <   ||tF        jJ                  <   ||tF        jL                  <   | j&                  jN                  D cg c]  }tQ        |d          c}|tF        jR                  <   | j&                  jT                  D cg c]  }tQ        |d          c}|tF        jV                  <   ||d<   ||d<   |jX                  d   }tZ        j]                  || j^                  t<        j`                         |tF        jb                  <   tZ        j]                  || jd                  t<        j`                        |tF        jf                  <   t/               }| j&                  jh                  |d	<   ||d<   ||d<   ||tF        jj                  <   ||fS c c}w c c}w )
a5  
        "prob" is a ParamConeProg which represents

            (Aff)   min{ c.T @ x : A @ x + b in K,
                                  x[bools] in {0, 1}, x[ints] in Z } + d.

        We return data for an equivalent problem

            (Dir)   min{ f @ y : G @ y <=_{K_aff} h, y in K_dir
                                 y[bools] in {0, 1}, y[ints] in Z } + d,

        where

            (1) K_aff is built from cone types specified in "affine" (a list of strings),
            (2) a primal solution for (Dir) can be mapped back to a primal solution
                for (Aff) by selecting the leading ``c.size`` block of y's components.

        In the returned dict "data", data[s.A] = G, data[s.B] = h, data[s.C] = f,
        data['K_aff'] = K_aff, data['K_dir'] = K_dir, data[s.BOOL_IDX] = bools,
        and data[s.INT_IDX] = ints. The rows of G are ordered according to ZERO, then
        (as applicable) NONNEG, SOC, and EXP. If  "c" is the objective vector in (Aff),
        then ``y[:c.size]`` should contain the optimal solution to (Aff). The columns of
        G correspond first to variables in cones FREE, then NONNEG, then SOC, then EXP.
        The length of the free cone is equal to ``c.size``.

        Assumptions
        -----------
        The function call ``c, d, A, b = prob.apply_parameters()`` returns (A,b) with
        rows formatted first for the zero cone, then for the nonnegative orthant, then
        second order cones, then the exponential cone. Removing this assumption will
        require adding additional data to ParamConeProg objects.
           r   Ncsr)formatr   K_affr;   r   )6r   r   r#   NotImplementedErrorZEROr    EXPr	   POW3Dappendr   r!   sumr"   r%   lenr'   rE   r   r-   r   r$   r&   rB   spsparsevstacktuple	eye_arrayblock_arrayrJ   rK   hstackzeros
ValueErrorr   r(   r*   r+   boolean_idxintBOOL_IDXinteger_idxINT_IDXrI   rg   extend_boundslower_boundsrR   LOWER_BOUNDSupper_boundsUPPER_BOUNDSr.   r,   )probaffiner0   r1   r(   r2   r   val	cone_lensrow_offsetsA_affb_affA_slkb_slktotal_slackco_typeco_dimrA_tempb_tempr   rl   r5   eyeGhftnum_varsr6   s                                 r7   r8   zSlacks.apply  s
   D **,
1aBNN	== &'' 	,C4c599)++	, vMM$ )..I$$Y]]#Y]]"1s9==))
	 !IdO49V#4449V#44y~E9T?Yv%663G)TW.X
 2u2ufc36 	)G w'Fz(1QZ<?+1QZf$LL(LL(6;;.KLL(LL(+	). $&&++6)Ay/?/?sf})--cVma&2imm	
 &(8I$$a#-R#-Q)..;.EVO9==
 vII$$U5\2E))%%k2C		((ue(DII))E3<%*GHNN55=1II$$eS\2NN5)288K#89:A		  ue <Au%AA,QSS	QSS	QSS	/3vv/A/AB!C!IBQZZ.2ff.@.@A3qt9AQYYWW 771:%33Hd>O>ORTRXRXQXYQ^^%33Hd>O>OQSQWQWXQ^^66699!!!"X~! CAs   'X/(X4r   bounds_vector
fill_valuereturnc                     |t        j                  | |      S | |j                  z
  }t        j                  |t         j                         }t        j                  ||g      S )zHExtend the bounds vector to be length num_vars, filling with fill_value.)rJ   fullrE   rR   rK   )r   r   r   new_vars
new_boundss        r7   r   zSlacks.extend_bounds  sU      778Z00m000WWXw/
~~}j9::r9   c                     | j                   t        j                  v r$| j                  }|t           }|t        = |||d   <   | xj
                  |t        j                     z  c_        | S )Nr   )r<   r   r>   rC   r   r?   r,   )rW   r6   	prim_varsr-   s       r7   r_   zSlacks.invert  s]    ??a000 ,,I$A$*+Ihv&'HQ\\22r9   N)r`   ra   rb   rc   rd   r8   r~   r   rJ   ndarrayfloatr   r_   re   r9   r7   rg   rg      sw    < U Un ;;

+; ; 
	; ;  r9   rg   )'rc   typingr   numpyrJ   scipyrt   cvxpyr   r   cvxpy.constraints.exponentialr   rN   cvxpy.constraints.nonposr   rG   cvxpy.constraints.powerr   rO   cvxpy.constraints.psdr   rM   cvxpy.constraints.second_orderr	   rH   cvxpy.constraints.zeror
   rD   cvxpy.reductions.solutionr   r   rn   r    ro   r$   rp   r&   r   rg   re   r9   r7   <module>r      ss        @ 9 < 0 9 3 .
				
v vrM Mr9   