
    biP5                        d Z ddlmZ ddlZddl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mZ ddlmZ dd	lmZmZ  G d
 d      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.
    )annotationsN)List)canonInterface)TensorRepresentation)NO_OPLinOp)InverseData)replace_quad_formsrestore_quad_formsc                  V    e Zd ZddZd Zd Zd Z	 	 	 	 	 	 	 	 d	dZ	 	 	 	 	 	 	 	 d
dZy)CoeffExtractorc                    |j                   | _        |j                  | _        |j                  | _        |j                  | _        |j
                  | _        |j                  | _        || _        y )N)var_offsetsid_mapx_length
var_shapesparam_shapesparam_to_sizeparam_id_mapcanon_backend)selfinverse_datar   s      Z/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/cvxpy/utilities/coeff_extractor.py__init__zCoeffExtractor.__init__&   s[    "..$--&11(55)77(55*    c           	        t        |t              r|}n|g}t        |D cg c]  }|j                          c}      sJ t	        |D cg c]  }|j
                   c}      }|D cg c]  }|j                  d    }}t        j                  || j                  | j                  | j                  | j                  || j                        S c c}w c c}w c c}w )a  Extract problem data tensor from an expression that is reducible to
        A*x + b.

        Applying the tensor to a flattened parameter vector and reshaping
        will recover A and b (see the helpers in canonInterface).

        Parameters
        ----------
        expr : Expression or list of Expressions.
            The expression(s) to process.

        Returns
        -------
        SciPy CSR matrix
            Problem data tensor, of shape
            (constraint length * (variable length + 1), parameter length + 1)
        r   )
isinstancelistallis_dppsumsizecanonical_formr   get_problem_matrixr   r   r   r   r   )r   expr	expr_listenum_rowsop_lists         r   affinezCoeffExtractor.affine/   s    $ dD!II	21AHHJ2333	212309:11##A&::001515151C1C151B1B19151C1CE 	E 32:s   C	C'Cc                h	   |j                         sJ t        j                  |j                               \  }}}}|j                  d   g}t        j                  |||| j                  | j                  |j                  | j                        }|dgddf   }	|ddddf   j                         }
|j                  d   }i }|j                         D ]  }|j                  |v r|j                  }||   d   j                  d   j                  }||   d   }||   d   }|
|||z   ddf   }||   d   j                  }|j                   J d       t#        j$                  |      r5t'        |t"        j(                        s|j                   j+                         }nt#        j(                  |j                         }|dk(  r|d   dk7  }|j,                  dddf   |dd|f   z  }t/        j0                  |      |   }t3        |j5                  d      t/        j6                  |j8                  t;        |            t/        j6                  |j<                  t;        |            t/        j>                  |t;        |j,                              |j                        }ny|j<                  |j8                  k(  jA                         sJ d	       ||z  }t/        jB                  |      \  }}|||f   }t3        |||jE                         ||j                        }||v r$d
||   v r||   d
   |z   ||   d
<   b|||   d
<   ltG               ||<   |||   d
<   |j                  d   |
j                  d   f}|dk(  rt/        jH                  |      ||   d<   t#        j(                  g g g ff|      ||   d<   ||j                     d   }t/        jJ                  ||j                     tL              }|j                  |v rU|dk(  r(||j                     dxx   |
|||z   ddf   z  cc<   Y||j                     dxx   ||||z   ddf   z  cc<   tG               ||j                  <   |dk(  r |
|||z   ddf   ||j                     d<   ||||z   ddf   ||j                     d<    ||	fS )zn Assumes quadratic forms all have variable arguments.
            Affine expressions can be anything.
        r   N      zFP matrix must be instantiated before calling extract_quadratic_coeffs.F)orderz?Only diagonal P matrices are supported for multiple quad forms.Pq)shapedtype)'r    r	   get_var_offsets	variablesr#   r   r$   r   r   r"   r   toarrayr3   idargsr1   valuespissparser   
coo_matrixtocoodatanparanger   flattentilerowlencolrepeatr   nonzerocopydictzerosprodint)r   affine_expr
quad_formsaffine_id_mapaffine_offsetsr   affine_var_shapesr)   param_coeffsconstantc
num_paramscoeffsvarvar_idorig_id
var_offsetvar_sizec_partr1   nonzero_idxsr@   
param_idxsP_tupscaled_c_partparamx_idx_rowparam_idx_colc_valsr3   s                                r   extract_quadratic_coeffsz'CoeffExtractor.extract_quadratic_coeffsP   s    !!### ''(=(=(?@ 	C~x1B--a01%889A9G9=9K9K9=9J9J9D9I9I9=9K9KM  a("a ((*!''*
 
 ((* W	^C
 vv#$V,Q/44Q7::*6215
(03:j&991<= v&q)++GG'\[\';;q>*Q*FAagg.A q= $*!9>L66!T'?VA|O-DDD!#:!6|!DJ03/s:7s:7		*c!&&k:E EEQUUN//1 ZYZ1 %&JM46JJ}4M1NM#NM$ABF0&&++-%E f$fWo-06w0Du0Lw,/4w, '+fF7O+0F7OC(WWQZ4E!Q/1xxw,/1}}b2r(^SX/Yw, +366215
77#4SVV#<CH66V#!Qsvvs+qJx<O1OQR1R/SS+svvs+|JzRZGZ<Z\]<]/^^+%)VF366N!Q./
:h;N0NPQ0Q.Rsvvs+.::jQYFY;Y[\;\.]svvs+oW	^p xr   c                   t        t        |j                  |gg       }t        |i       }| j	                  |j
                  d   |      \  }}t        |j
                  d   |       t        | j                  j                         t        j                  d            }|j                  d   }g }g }	d}
d}|D ]  \  }}| j                  |   }t        j                  |t              }||v r)d||   v r"||   d   }||j                   j"                  z  }nt%        j&                  ||f      }||v rd||   v r	||   d   }n9|dk(  rt        j(                  ||f      }nt+        j,                  g g g ff||f      }|j/                  |       |	j/                  |       |
|z  }
 |
| j0                  k7  rt3        d      | j5                  ||
|      }| j7                  |	||      }||fS )zKExtract quadratic, linear constant parts of a quadratic objective.
        r   r-   )keyr4   r1   r2   z=Resulting quadratic form does not have appropriate dimensions)r   r   r3   r
   rf   r:   r   sortedr   itemsoperator
itemgetterr   rA   rM   rN   r@   r"   r   empty_with_shaperL   r<   r>   appendr   
ValueErrormerge_P_listmerge_q_list)r   r%   rootrP   rX   rU   offsetsrW   P_listq_listP_height	P_entriesrZ   _r3   r"   r1   r2   s                     r   	quad_formzCoeffExtractor.quad_form   s   
 UDJJ3 (b1
  8819CE 	499Q<4 **,(2E2Ea2HI ^^A&
	  	IFAOOF+E775,DC6&>$96N3'QVV[[(	(994,GC6&>$96N3' ?$
!34ArB8ntZ6HIAMM!MM!H'	* t}}$ 8 9 9 fh
;fh
;!tr   c                0   d}|D ]j  }|j                   \  }}||k(  sJ |j                  |j                  usJ |xj                  |z  c_        |xj                  |z  c_        ||f|_         ||z  }l t        j                  |      }|j                  |      S )aZ  Conceptually we build a block diagonal matrix
           out of all the Ps, then flatten the first two dimensions.
           eg P1
                P2
           We do this by extending each P with zero blocks above and below.

        Args:
            P_list: list of P submatrices as TensorRepresentation objects.
            P_entries: number of entries in the merged P matrix.
            P_height: number of rows in the merged P matrix.
            num_params: number of parameters in the problem.
        
        Returns:
            A CSC sparse representation of the merged P matrix.
        r   )r3   rE   rG   r   combineflatten_tensor)	r   rt   rv   rW   offsetr1   mncombineds	            r   rp   zCoeffExtractor.merge_P_list  s    ,  
	A77DAq6M655%%% EEVOEEEVOE*AGaKF
	 (//7&&z22r   c                   |dk(  rOt        j                  |      }t        j                  ||j                         g      }t        j                  |      S t        j                  ||gz         }t        j                  |      S )af  Stack q with constant offset as last row.

        Args:
            q_list: list of q submatrices as SciPy sparse matrices or NumPy arrays.
            constant: The constant offset as a CSC sparse matrix.
            num_params: number of parameters in the problem.

        Returns:
            A CSR sparse representation of the merged q matrix.
        r-   )rA   vstackr8   r<   	csr_array)r   ru   rU   rW   r2   s        r   rq   zCoeffExtractor.merge_q_list2  sf    " ?		&!A		1h..012A<<?"		&H:-.A<<?"r   N)r   z
str | NonereturnNone)rt   zList[TensorRepresentation]rv   rN   rW   rN   r   sp.csc_array)ru   zList[sp.spmatrix | np.ndarray]rU   r   rW   rN   r   zsp.csr_array)	__name__
__module____qualname__r   r*   rf   ry   rp   rq    r   r   r   r   $   sr    +EB@ D7r%3.%3 %3 	%3
 %3N#.# # 	#
 
#r   r   )__doc__
__future__r   rk   typingr   numpyrA   scipy.sparsesparser<   cvxpy.cvxcore.pythonr   cvxpy.lin_ops.canon_backendr   cvxpy.lin_ops.lin_opr   r   cvxpy.reductions.inverse_datar	   "cvxpy.utilities.replace_quad_formsr
   r   r   r   r   r   <module>r      s8     #     / < - 5e# e#r   