
    sg@X                         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 Z	 dd	Z	 dd
Z	 	 ddZd Zd Zd Zej&                  ddddddfdZy)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                 H   t        j                  |      \  }t        j                  |      \  }t        t        | |j                  g|dgg            }t        j
                  | | g      }t        j                  |      }|j                  |      }	|	d| }
|	|||z     }|
|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_multiplierss               c/var/www/html/venv/lib/python3.12/site-packages/scipy/optimize/_trustregion_constr/qp_subproblem.pyr   r      s    0 
!BA	!BA
 D1acc(QI!678Jii!aR!G
 
Z	 BhhwGA#AacN?"""    Fc                 f   t        |      dk(  ryt        j                  |      r/|r"t        j                   }t        j                  }nd}d}d}|||fS t        j                  ||      }dt        j                  | |      z  }t        j                  | |       |dz  z
  }	||z  d|z  |	z  z
  }
|
dk  rd}dd|fS t        j
                  |
      }|t        ||      z   }| d|z  z  }d|	z  |z  }t        ||g      \  }}|rd}n+|dk  s|dkD  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auxs                r"   r	   r	   A   s\   B Aw!|	xx&&BBBB	2y  
q!A	BFF1aLA
q!|Q&AQ31Q;La	!Y- h(!,
,C
1B	ABRHFB	 6R!VIBBI QBQBr9r#   c                    t        j                  |       } t        j                  |      }t        j                  |      }t        j                  |      }t        |      dk(  ry|dk(  }| |   ||   k  j                         s| |   ||   kD  j                         rd}dd|fS t        j                  |      }| |   } ||   }||   }||   }|| z
  |z  }|| z
  |z  }	t        t        j                  ||	            }
t        t        j                  ||	            }|
|k  rd}nd}|s)|dk  s|
dkD  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/   minimumr0   maximum)r1   r2   lbubr4   zero_dr7   
not_zero_dt_lbt_ubr5   r6   s               r"   r
   r
      se   J 	

1A


1A	BB	BBAw!| 1fF 	
&	BvJ##%!F)bj*@)E)E)G	!Y'J	*A	*A	JB	JB qDA:DqDA:D	RZZd#	$B	RZZd#	$B 
Rx		6R!VIBB QBQBr9r#   c                     t        | ||||      \  }}}	t        | |||      \  }
}}t        j                  ||
      }t        j                  ||      }|	r
|r||k  rd}nd}|r|
||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)r5   r6   r7   )r
   r	   r   rA   r@   )r1   r2   rB   rC   r3   r4   
extra_infota_btb_bintersect_bta_stb_sintersect_sr5   r6   r7   sphere_infobox_infos                     r"   r   r      s    b 01b"0;=D$21a3?3>@D$ 
D$	B	D$	B{rRx		!KHdE2y+x772y  r#   c                 R    || k  j                         xr | |k  j                         S )zCheck if lb <= x <= ub.)allr    rB   rC   s      r"   r   r   1  s!    !G==?.R}}.r#   c                 V    t        j                  t        j                  | |      |      S )zReturn clipped value of x)r   r@   rA   rT   s      r"   reinforce_box_boundariesrV   6  s    ::bjjB',,r#   c                    |j                  |       }t        |||      rt        |      |k  r|}|S | j                  j                  |      }| j                  |      }	t	        j                   ||       t	        j                   |	|	      z  |z  }
t	        j
                  |
      }|
}||
z
  }t        |||||      \  }}}|r	|||z  z   }n|}|
}t        |||||      \  }}}|||z  z   }|}|}t        |||||      \  }}}|||z  z   }t        | j                  |      |z         t        | j                  |      |z         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   r3   rB   rC   newton_pointr    gA_gcauchy_pointorigin_pointr1   p_alphar7   x1x2s                      r"   r   r   ;  si   ` EE!H9L\2r2- 	

A %%(CFF1aL=266#s#33a7L==.L 	A|#A21aR3?AAuiq[ .q!R/;=5!q[ 	AA*1aR+79KAua	
U1WB AEE"IMT!%%)a-00		r#   c           	         d}t        j                  |      \  }t        j                  |      \  }|j                  |       }|j                  | j                  |      |z         }|j                  |      }| }|r|g}| j                  |      }t        |      dz  }|t        |      z
  }|dk  rt	        d      ||k  r"dddd}|rj                  |       ||d<   ||fS |/t        t        dt        j                  |      z  d	|z        |      }|%t        j                  |t         j                         }|$t        j                  |t         j                        }|	||z
  }	t        |	||z
        }	|
||z
  }
d
}d}d}t        j                  |      }d}t        |	      D ]  }||k  rd} n|dz  }|j                  |      }|dk  rSt        j                  |      rt	        d      t        |||||d      \  }} }!|!r|| |z  z   }t        |||      }d}d} n(||z  } || |z  z   }"t         j                   j                  |"      |k\  r6t        || |z  |||      \  }}#}!|!r||#| z  |z  z   }t        |||      }d}d} nt#        |"||      rd}n|dz  }|dkD  r2t        || |z  |||      \  }}#}!|!r||#| z  |z  z   }t        |||      }d}||
kD  r np|rj                  |"       || |z  z   }$|j                  |$      }%t        |%      dz  }&|&|z  }'|% |'|z  z   }|"}|%}|%}t        |      dz  }| j                  |      } 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allvecsg{Gz?g?Fr&   r(   z9Negative curvature not allowed for unrestricted problems.)r4      )r   r   r,   r   
ValueErrorappendr/   r0   r-   fullr+   rX   ranger*   r   rV   r   r   )(r   r   ZrY   r   r3   rB   rC   tolmax_itermax_infeasible_iter
return_allCLOSE_TO_ZEROr   r   r    rr[   r_   rh   H_prt_gtr_distanceinforg   rf   counterlast_feasible_xkipt_H_pr`   ra   r7   x_nextthetar_nextg_next	rt_g_nextbetas(                                           r"   r   r     s   ` M	!BA	!BA 	
qb	A	aeeAhlA	aA	
A #
%%(C7A:D a(KQIJJ 
}	$TBNN1%DO$w {#dRWWT]*C$J7G	zWWQ 	zWWQQ38QqS!H"cMIGmmA&O	A8_ T#:I	QQ;xx%  "> ? ? '?q"b,D'B#5) E!GA -QB7	 $ vU1W 99>>&!\1":1eAgr2;G#IAui eA% )B3AI M !R0GqLGQ;":1eAgr2;G#IAui"#eEk!m"3 #;?;=r#C((NN6" U3YvL!O	4HtAvAwzeeAhiTl !B+Y*,D!Yd7Nr#   )F)FF)__doc__scipy.sparser   r   r   mathr   numpyr   numpy.linalgr   __all__r   r	   r
   r   r   rV   r   r+   r    r#   r"   <module>r      sz    9 3 3   *#\ &+Sn #(Rl */(-B!J/
-
]@ .0VVTtD!br#   