o
    ñh@X  ã                   @   s¤   d Z ddlmZmZmZ ddlmZ ddlZddl	m
Z
 g d¢Zdd„ Z		dd
d„Z		ddd„Z				ddd„Zdd„ Zdd„ Zdd„ Zejdddddd	fdd„ZdS )z3Equality-constrained quadratic programming solvers.é    )ÚlinalgÚbmatÚ
csc_matrix)ÚcopysignN)Únorm)Úeqp_kktfactÚsphere_intersectionsÚbox_intersectionsÚbox_sphere_intersectionsÚinside_box_boundariesÚmodified_doglegÚprojected_cgc                 C   s~   t  |¡\}t  |¡\}tt| |jg|dggƒƒ}t  | | g¡}t |¡}| |¡}	|	d|… }
|	||| …  }|
|fS )aÍ  Solve equality-constrained quadratic programming (EQP) problem.

    Solve ``min 1/2 x.T H x + x.t c`` subject to ``A x + b = 0``
    using direct factorization of the KKT system.

    Parameters
    ----------
    H : sparse matrix, shape (n, n)
        Hessian matrix of the EQP problem.
    c : array_like, shape (n,)
        Gradient of the quadratic objective function.
    A : sparse matrix
        Jacobian matrix of the EQP problem.
    b : array_like, shape (m,)
        Right-hand side of the constraint equation.

    Returns
    -------
    x : array_like, shape (n,)
        Solution of the KKT problem.
    lagrange_multipliers : ndarray, shape (m,)
        Lagrange multipliers of the KKT problem.
    N)	ÚnpÚshaper   r   ÚTÚhstackr   ÚspluÚsolve)ÚHÚcÚAÚbÚnÚmÚ
kkt_matrixÚkkt_vecÚluÚkkt_solÚxÚlagrange_multipliers© r    úd/var/www/vscode/kcb/lib/python3.10/site-packages/scipy/optimize/_trustregion_constr/qp_subproblem.pyr      s   

r   Fc                 C   s*  t |ƒdkrdS t |¡r"|rtj }tj}nd}d}d}|||fS t ||¡}dt | |¡ }t | | ¡|d  }	|| d| |	  }
|
dk rOd}dd|fS t |
¡}|t||ƒ }| d|  }d|	 | }t||gƒ\}}|rud}n|dk s}|dkr„d}d}d}nd}td|ƒ}t	d|ƒ}|||fS )	aH  Find the intersection between segment (or line) and spherical constraints.

    Find the intersection between the segment (or line) defined by the
    parametric  equation ``x(t) = z + t*d`` and the ball
    ``||x|| <= trust_radius``.

    Parameters
    ----------
    z : array_like, shape (n,)
        Initial point.
    d : array_like, shape (n,)
        Direction.
    trust_radius : float
        Ball radius.
    entire_line : bool, optional
        When ``True``, the function returns the intersection between the line
        ``x(t) = z + t*d`` (``t`` can assume any value) and the ball
        ``||x|| <= trust_radius``. When ``False``, the function returns the intersection
        between the segment ``x(t) = z + t*d``, ``0 <= t <= 1``, and the ball.

    Returns
    -------
    ta, tb : float
        The line/segment ``x(t) = z + t*d`` is inside the ball for
        for ``ta <= t <= tb``.
    intersect : bool
        When ``True``, there is a intersection between the line/segment
        and the sphere. On the other hand, when ``False``, there is no
        intersection.
    r   ©r   r   Fé   Té   é   Féþÿÿÿ)
r   r   ÚisinfÚinfÚdotÚsqrtr   ÚsortedÚmaxÚmin)ÚzÚdÚtrust_radiusÚentire_lineÚtaÚtbÚ	intersectÚar   r   ÚdiscriminantÚsqrt_discriminantÚauxr    r    r!   r   A   s@   !



	


r   c                 C   s*  t  | ¡} t  |¡}t  |¡}t  |¡}t|ƒdkrdS |dk}| | || k  ¡ s4| | || k ¡ r;d}dd|fS t  |¡}| | } || }|| }|| }||  | }||  | }	tt  ||	¡ƒ}
tt  ||	¡ƒ}|
|krsd}nd}|s|dk s|
dkr†d}d}
d}n
td|
ƒ}
td|ƒ}|
||fS )a5  Find the intersection between segment (or line) and box constraints.

    Find the intersection between the segment (or line) defined by the
    parametric  equation ``x(t) = z + t*d`` and the rectangular box
    ``lb <= x <= ub``.

    Parameters
    ----------
    z : array_like, shape (n,)
        Initial point.
    d : array_like, shape (n,)
        Direction.
    lb : array_like, shape (n,)
        Lower bounds to each one of the components of ``x``. Used
        to delimit the rectangular box.
    ub : array_like, shape (n, )
        Upper bounds to each one of the components of ``x``. Used
        to delimit the rectangular box.
    entire_line : bool, optional
        When ``True``, the function returns the intersection between the line
        ``x(t) = z + t*d`` (``t`` can assume any value) and the rectangular
        box. When ``False``, the function returns the intersection between the segment
        ``x(t) = z + t*d``, ``0 <= t <= 1``, and the rectangular box.

    Returns
    -------
    ta, tb : float
        The line/segment ``x(t) = z + t*d`` is inside the box for
        for ``ta <= t <= tb``.
    intersect : bool
        When ``True``, there is a intersection between the line (or segment)
        and the rectangular box. On the other hand, when ``False``, there is no
        intersection.
    r   r"   FTr#   )	r   Úasarrayr   ÚanyÚlogical_notr,   Úminimumr-   Úmaximum)r.   r/   ÚlbÚubr1   Úzero_dr4   Ú
not_zero_dÚt_lbÚt_ubr2   r3   r    r    r!   r	   —   s<   
%


(




r	   c                 C   s   t | ||||ƒ\}}}	t| |||ƒ\}
}}t ||
¡}t ||¡}|	r,|r,||kr,d}nd}|rC|
||dœ}|||	dœ}|||||fS |||fS )aý  Find the intersection between segment (or line) and box/sphere constraints.

    Find the intersection between the segment (or line) defined by the
    parametric  equation ``x(t) = z + t*d``, the rectangular box
    ``lb <= x <= ub`` and the ball ``||x|| <= trust_radius``.

    Parameters
    ----------
    z : array_like, shape (n,)
        Initial point.
    d : array_like, shape (n,)
        Direction.
    lb : array_like, shape (n,)
        Lower bounds to each one of the components of ``x``. Used
        to delimit the rectangular box.
    ub : array_like, shape (n, )
        Upper bounds to each one of the components of ``x``. Used
        to delimit the rectangular box.
    trust_radius : float
        Ball radius.
    entire_line : bool, optional
        When ``True``, the function returns the intersection between the line
        ``x(t) = z + t*d`` (``t`` can assume any value) and the constraints.
        When ``False``, the function returns the intersection between the segment
        ``x(t) = z + t*d``, ``0 <= t <= 1`` and the constraints.
    extra_info : bool, optional
        When ``True``, the function returns ``intersect_sphere`` and ``intersect_box``.

    Returns
    -------
    ta, tb : float
        The line/segment ``x(t) = z + t*d`` is inside the rectangular box and
        inside the ball for ``ta <= t <= tb``.
    intersect : bool
        When ``True``, there is a intersection between the line (or segment)
        and both constraints. On the other hand, when ``False``, there is no
        intersection.
    sphere_info : dict, optional
        Dictionary ``{ta, tb, intersect}`` containing the interval ``[ta, tb]``
        for which the line intercepts the ball. And a boolean value indicating
        whether the sphere is intersected by the line.
    box_info : dict, optional
        Dictionary ``{ta, tb, intersect}`` containing the interval ``[ta, tb]``
        for which the line intercepts the box. And a boolean value indicating
        whether the box is intersected by the line.
    TF)r2   r3   r4   )r	   r   r   r=   r<   )r.   r/   r>   r?   r0   r1   Ú
extra_infoÚta_bÚtb_bÚintersect_bÚta_sÚtb_sÚintersect_sr2   r3   r4   Úsphere_infoÚbox_infor    r    r!   r
   ì   s"   
1
ÿ
þ
r
   c                 C   s   || k  ¡ o| |k  ¡ S )zCheck if lb <= x <= ub.)Úall©r   r>   r?   r    r    r!   r   1  s   r   c                 C   s   t  t  | |¡|¡S )zReturn clipped value of x)r   r<   r=   rN   r    r    r!   Úreinforce_box_boundaries6  s   rO   c                 C   s  |  |¡ }t|||ƒrt|ƒ|kr|}|S | j  |¡}|   |¡}	t  ||¡ t  |	|	¡ | }
t |
¡}|
}||
 }t|||||ƒ\}}}|rO|||  }n|}|
}t|||||ƒ\}}}|||  }|}|}t|||||ƒ\}}}|||  }t|   |¡| ƒt|   |¡| ƒk r|S |S )aA  Approximately  minimize ``1/2*|| A x + b ||^2`` inside trust-region.

    Approximately solve the problem of minimizing ``1/2*|| A x + b ||^2``
    subject to ``||x|| < Delta`` and ``lb <= x <= ub`` using a modification
    of the classical dogleg approach.

    Parameters
    ----------
    A : LinearOperator (or sparse matrix or ndarray), shape (m, n)
        Matrix ``A`` in the minimization problem. It should have
        dimension ``(m, n)`` such that ``m < n``.
    Y : LinearOperator (or sparse matrix or ndarray), shape (n, m)
        LinearOperator that apply the projection matrix
        ``Q = A.T inv(A A.T)`` to the vector. The obtained vector
        ``y = Q x`` being the minimum norm solution of ``A y = x``.
    b : array_like, shape (m,)
        Vector ``b``in the minimization problem.
    trust_radius: float
        Trust radius to be considered. Delimits a sphere boundary
        to the problem.
    lb : array_like, shape (n,)
        Lower bounds to each one of the components of ``x``.
        It is expected that ``lb <= 0``, otherwise the algorithm
        may fail. If ``lb[i] = -Inf``, the lower
        bound for the ith component is just ignored.
    ub : array_like, shape (n, )
        Upper bounds to each one of the components of ``x``.
        It is expected that ``ub >= 0``, otherwise the algorithm
        may fail. If ``ub[i] = Inf``, the upper bound for the ith
        component is just ignored.

    Returns
    -------
    x : array_like, shape (n,)
        Solution to the problem.

    Notes
    -----
    Based on implementations described in pp. 885-886 from [1]_.

    References
    ----------
    .. [1] Byrd, Richard H., Mary E. Hribar, and Jorge Nocedal.
           "An interior point algorithm for large-scale nonlinear
           programming." SIAM Journal on Optimization 9.4 (1999): 877-900.
    )r)   r   r   r   r   Ú
zeros_liker
   )r   ÚYr   r0   r>   r?   Únewton_pointr   ÚgÚA_gÚcauchy_pointÚorigin_pointr.   ÚpÚ_Úalphar4   Úx1Úx2r    r    r!   r   ;  s>   0



ÿ

ÿ

ÿ$r   c           (   	   C   sf  d}t  |¡\}t  |¡\}| | ¡}| |  |¡| ¡}| |¡}| }|r+|g}|  |¡}t|ƒd }|t|ƒ }|dk rDtdƒ‚||k r]ddddœ}|rY| |¡ ||d< ||fS |du rpttd	t  |¡ d
| ƒ|ƒ}|du r|t  	|t j
 ¡}|du r‡t  	|t j
¡}|	du r|| }	t|	|| ƒ}	|
du rž|| }
d}d}d}t  |¡}d}t|	ƒD ]ç}||k r¹d} nÞ|d7 }| |¡}|dkrðt  |¡rÏtdƒ‚t|||||dd\}} }!|!rä|| |  }t|||ƒ}d}d} n§|| } || |  }"t j |"¡|kr't|| | |||ƒ\}}#}!|!r||#|  |  }t|||ƒ}d}d} npt|"||ƒr1d}n|d7 }|dkrZt|| | |||ƒ\}}#}!|!rZ||#|  |  }t|||ƒ}d}||
kra n6|ri| |"¡ || |  }$| |$¡}%t|%ƒd }&|&| }'|% |'|  }|"}|%}|%}t|ƒd }|  |¡}q¯t|||ƒs¢|}d}|||dœ}|r¯||d< ||fS )a¨  Solve EQP problem with projected CG method.

    Solve equality-constrained quadratic programming problem
    ``min 1/2 x.T H x + x.t c``  subject to ``A x + b = 0`` and,
    possibly, to trust region constraints ``||x|| < trust_radius``
    and box constraints ``lb <= x <= ub``.

    Parameters
    ----------
    H : LinearOperator (or sparse matrix or ndarray), shape (n, n)
        Operator for computing ``H v``.
    c : array_like, shape (n,)
        Gradient of the quadratic objective function.
    Z : LinearOperator (or sparse matrix or ndarray), shape (n, n)
        Operator for projecting ``x`` into the null space of A.
    Y : LinearOperator,  sparse matrix, ndarray, shape (n, m)
        Operator that, for a given a vector ``b``, compute smallest
        norm solution of ``A x + b = 0``.
    b : array_like, shape (m,)
        Right-hand side of the constraint equation.
    trust_radius : float, optional
        Trust radius to be considered. By default, uses ``trust_radius=inf``,
        which means no trust radius at all.
    lb : array_like, shape (n,), optional
        Lower bounds to each one of the components of ``x``.
        If ``lb[i] = -Inf`` the lower bound for the i-th
        component is just ignored (default).
    ub : array_like, shape (n, ), optional
        Upper bounds to each one of the components of ``x``.
        If ``ub[i] = Inf`` the upper bound for the i-th
        component is just ignored (default).
    tol : float, optional
        Tolerance used to interrupt the algorithm.
    max_iter : int, optional
        Maximum algorithm iterations. Where ``max_inter <= n-m``.
        By default, uses ``max_iter = n-m``.
    max_infeasible_iter : int, optional
        Maximum infeasible (regarding box constraints) iterations the
        algorithm is allowed to take.
        By default, uses ``max_infeasible_iter = n-m``.
    return_all : bool, optional
        When ``true``, return the list of all vectors through the iterations.

    Returns
    -------
    x : array_like, shape (n,)
        Solution of the EQP problem.
    info : Dict
        Dictionary containing the following:

            - niter : Number of iterations.
            - stop_cond : Reason for algorithm termination:
                1. Iteration limit was reached;
                2. Reached the trust-region boundary;
                3. Negative curvature detected;
                4. Tolerance was satisfied.
            - allvecs : List containing all intermediary vectors (optional).
            - hits_boundary : True if the proposed step is on the boundary
              of the trust region.

    Notes
    -----
    Implementation of Algorithm 6.2 on [1]_.

    In the absence of spherical and box constraints, for sufficient
    iterations, the method returns a truly optimal result.
    In the presence of those constraints, the value returned is only
    a inexpensive approximation of the optimal value.

    References
    ----------
    .. [1] Gould, Nicholas IM, Mary E. Hribar, and Jorge Nocedal.
           "On the solution of equality constrained quadratic
            programming problems arising in optimization."
            SIAM Journal on Scientific Computing 23.4 (2001): 1376-1395.
    gÙ}ÚõÐò¾:r$   r   z.Trust region problem does not have a solution.T)ÚniterÚ	stop_condÚhits_boundaryÚallvecsNg{®Gáz„?gš™™™™™¹?Fr#   r%   z9Negative curvature not allowed for unrestricted problems.)r1   é   )r   r   r)   r   Ú
ValueErrorÚappendr,   r-   r*   Úfullr(   rP   Úranger'   r
   rO   r   r   )(r   r   ÚZrQ   r   r0   r>   r?   ÚtolÚmax_iterÚmax_infeasible_iterÚ
return_allÚCLOSE_TO_ZEROr   r   r   ÚrrS   rW   r_   ÚH_pÚrt_gÚtr_distanceÚinfor^   r]   ÚcounterÚlast_feasible_xÚkÚiÚpt_H_prX   rY   r4   Úx_nextÚthetaÚr_nextÚg_nextÚ	rt_g_nextÚbetar    r    r!   r   ›  sÌ   P





ÿ
ÿ

ÿÿ


ÿr   )F)FF)Ú__doc__Úscipy.sparser   r   r   Úmathr   Únumpyr   Únumpy.linalgr   Ú__all__r   r   r	   r
   r   rO   r   r(   r   r    r    r    r!   Ú<module>   s,    .
ÿW
ÿV
þE`ý