
    bi]"                         d 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mZmZ dd	eeef   d
edefdZ G d de      Zy)a,  
Copyright 2013 Steven Diamond

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.
    )ListTupleUnionN)AxisAtom)norm1)norm_inf)
Constraint)pow_highpow_midpow_negpkeepdims	max_denomc                     |dk(  rt        | ||      S |t        j                  ddfv rt        | ||      S t	        | ||||      S )a#  Factory function for a mathematical p-norm.

    Parameters
    ----------
    p : numeric type or string
       The type of norm to construct; set this to np.inf or 'inf' to
       construct an infinity norm.

    Returns
    -------
    Atom
       A norm1, norm_inf, or Pnorm object.
       axisr   infInf)r   r   r   r   )r   npr   r   Pnorm)xr   r   r   r   s        L/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/cvxpy/atoms/pnorm.pypnormr      sO     	AvQTH55	
rvvue$	$x88Q!$YOO    c            	            e Zd ZdZdZ	 	 ddedededdf fdZd	 Zd fd
Z	de
eef   fdZdefdZdefdZdefdZdefdZdefdZdefdZdefdZd ZdefdZdee   fdZd Zd Z xZS )r   aG  The vector p-norm, for p not equal to 1 or infinity.

    If given a matrix variable, ``pnorm`` will treat it as a vector, and
    compute the p-norm of the concatenated columns. Only accepts p values
    that are not equal to 1 or infinity; the norm1 and norm_inf classes
    handle those norms.

    For :math:`p > 1`, the p-norm is given by

    .. math::

        \|x\|_p = \left(\sum_i |x_i|^p \right)^{1/p},

    with domain :math:`x \in \mathbf{R}^n`.

    For :math:`p < 1,\ p \neq 0`, the p-norm is given by

    .. math::

        \|x\|_p = \left(\sum_i x_i^p \right)^{1/p},

    with domain :math:`x \in \mathbf{R}^n_+`.

    - Note that the "p-norm" is actually a **norm** only when
      :math:`p > 1`. For these cases, it is convex.
    - The expression is not defined when :math:`p = 0`.
    - Otherwise, when :math:`p < 1`, the expression is
      concave, but it is not a true norm.

    .. note::

        Generally, ``p`` cannot be represented exactly, so a rational,
        i.e., fractional, **approximation** must be made.

        Internally, ``pnorm`` computes a rational approximation
        to the reciprocal :math:`1/p` with a denominator up to ``max_denom``.
        The resulting
        approximation can be found through the attribute ``pnorm.p``.
        The approximation error is given by the attribute ``pnorm.approx_error``.
        Increasing ``max_denom`` can give better approximations.

        When ``p`` is an ``int`` or ``Fraction`` object, the approximation
        is usually **exact**.


    Parameters
    ----------
    x : cvxpy.Variable
        The value to take the norm of.

    p : int, float, or Fraction
        We require that :math:`p > 1`, but :math:`p \neq \infty`. See the
        norm1 and norm_inf classes for these norms, or use the pnorm
        function wrapper to instantiate them.


    max_denom : int
        The maximum denominator considered in forming a rational approximation
        for ``p``.

    axis : 0 or 1
           The axis to apply the norm to.

    Returns
    -------
    Expression
        An Expression representing the norm.
    TNr   r   r   returnc                    |dk  rt        ||      \  | _        }nd|cxk  rdk  rn nt        ||      \  | _        }nl|dkD  rt        ||      \  | _        }nR|dk(  rt	        d      |dk(  s|dk(  s|t
        j                  k(  rt	        d      t	        dj                  |            t        t        | j                  |z
              | _
        || _        t        t        | ;  |||       y )	Nr   r   z.Use the norm1 class to instantiate a one norm.r   r   z7Use the norm_inf class to instantiate an infinity norm.zInvalid p: {}r   )r   r   r   r
   
ValueErrorr   r   formatfloatabsapprox_error
original_psuperr   __init__)selfr   r   r   r   r   _	__class__s          r   r&   zPnorm.__init__y   s    q59-IDFAYQY9-IDFAU I.IDFA!VMNN%Z1:bff . / / _33A677!#dffqj/2eT#AD8#Dr   c                    | j                   't        j                  |d         j                         }nt        j                  |d         }| j                  dk  r)t        j
                  |dk        rt        j                   S | j                  dk  rt        j
                  |dk(        ryt        j                  j                  |t        | j                        | j                   | j                        S )z!Returns the p-norm of x.
        r   r   g        r   )r   r   arrayflattenr   anyr   linalgnormr!   r   r'   valuess     r   numericzPnorm.numeric   s     99XXfQi(002FXXfQi(F66A:"&&!,FF7N66A:"&&1-yy~~feDFFm$))'+}}  6 	6r   c                     t         t        |           | j                  | j                  dk7  rt        d      | j                  dk  r)| j                  d   j                         rt        d      y y )N   z-The axis parameter is only supported for p=2.r   r   z,pnorm(x, p) cannot have x complex for p < 1.)r%   r   validate_argumentsr   r   r   args
is_complex)r'   r)   s    r   r5   zPnorm.validate_arguments   sg    eT-/99 TVVq[?A A66A:$))A,113KLL 4:r   c                      y)zCReturns sign (is positive, is negative) of the expression.
        )TF r'   s    r   sign_from_argszPnorm.sign_from_args   s     r   c                      | j                   dkD  S )zIs the atom convex?
        r   r   r:   s    r   is_atom_convexzPnorm.is_atom_convex        vvzr   c                      | j                   dk  S )zIs the atom concave?
        r   r=   r:   s    r   is_atom_concavezPnorm.is_atom_concave   r?   r   c                      y)z$Is the atom log-log convex?
        Tr9   r:   s    r   is_atom_log_log_convexzPnorm.is_atom_log_log_convex   s     r   c                      y)z%Is the atom log-log concave?
        Fr9   r:   s    r   is_atom_log_log_concavezPnorm.is_atom_log_log_concave        r   c                     | j                   dk  xs. | j                   dkD  xr | j                  d   j                         S )z;Is the composition non-decreasing in argument idx?
        r   r   )r   r6   	is_nonnegr'   idxs     r   is_incrzPnorm.is_incr   s5     vvzFdffqjETYYq\-C-C-EFr   c                 ^    | j                   dkD  xr | j                  d   j                         S )z;Is the composition non-increasing in argument idx?
        r   r   )r   r6   	is_nonposrI   s     r   is_decrzPnorm.is_decr   s(     vvz6diil4466r   c                      y)z&Is the atom piecewise linear?
        Fr9   r:   s    r   is_pwlzPnorm.is_pwl   rF   r   c                 2    | j                   | j                  gS )N)r   r   r:   s    r   get_datazPnorm.get_data   s    		""r   c                     | j                   j                  d| j                  d   j                         d| j                  dS )N(r   z, ))r)   __name__r6   namer   r:   s    r   rW   z
Pnorm.name   s4    #~~66#yy|002#vv' 	'r   c                 h    | j                   dk  r"| j                   dk7  r| j                  d   dk\  gS g S )z?Returns constraints describing the domain of the node.
        r   r   )r   r6   r:   s    r   _domainzPnorm._domain   s4     66A:$&&A+IIaLA%&&Ir   c                 $    | j                  |      S )a+  Gives the (sub/super)gradient of the atom w.r.t. each argument.

        Matrix expressions are vectorized, so the gradient is a matrix.

        Args:
            values: A list of numeric values for the arguments.

        Returns:
            A list of SciPy CSC sparse matrices or None.
        )
_axis_gradr0   s     r   _gradzPnorm._grad   s     v&&r   c                 ,   |j                   }| j                  dk  rt        j                  |dk        ryt	        j
                  |dfd      }t        j                  |      j                  d      }t        j                  j                  |t        | j                              }t        | j                  dz
        }t        j                  ||      }|dk(  r | j                  dkD  r|j                         S y| j                  dkD  r@t        j                  |      t        j                  t        j                  |      |      z  }nt        j                  ||      }t        j                  ||      }t        j                   ||j                   df      S )a  Gives the (sub/super)gradient of the atom w.r.t. a column argument.

        Matrix expressions are vectorized, so the gradient is a matrix.

        Args:
            value: A numeric value for a column.

        Returns:
            A NumPy ndarray or None.
        r   r   Nfloat64)dtypeF)order)sizer   r   r-   sp	csc_arrayasarrayravelr.   r/   r!   powertodensesignr"   dividereshape)r'   valuerowsD_nulldenominatorexp	nominatorfracs           r   _column_gradzPnorm._column_grad   s$    zz66A:"&&!,tQiy9

5!''c'2iinnUE$&&M:DFFQJhh{C0!vvz~~''66A:"&&-)EEI,IyyK0zz$A//r   r4   NFi   )r   N)rV   
__module____qualname____doc___allow_complexintboolr&   r2   r5   r   r;   r>   rA   rC   rE   rK   rN   rP   rR   strrW   r   r	   rY   r\   rs   __classcell__)r)   s   @r   r   r   2   s    CH N+/:>ES EE47ECGE(6 MdDj 1  
 
 
 
Gd G
7d 7
 
#'c '
j) '!0r   r   rt   )rw   typingr   r   r   numpyr   scipy.sparsesparserc   cvxpy.atoms.axis_atomr   cvxpy.atoms.norm1r   cvxpy.atoms.norm_infr   cvxpy.constraints.constraintr	   cvxpy.utilities.power_toolsr
   r   r   ry   r{   rz   r   r   r9   r   r   <module>r      s_    & %   * # ) 3 B BPc3h P$ PSV P,[0H [0r   