a
    Re@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   TZhstackr   ZspluZsolve)HcAbnmZ
kkt_matrixZkkt_vecZluZkkt_solxZlagrange_multipliers r   d/var/www/sunrise/env/lib/python3.9/site-packages/scipy/optimize/_trustregion_constr/qp_subproblem.pyr      s    

r   Fc                 C   s,  t |dkrdS t|rD|r.tj }tj}nd}d}d}|||fS t||}dt| | }t| | |d  }	|| d| |	  }
|
dk rd}dd|fS t|
}|t|| }| d|  }d|	 | }t||g\}}|rd}n8|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   ZdiscriminantZsqrt_discriminantZauxr   r   r   r   A   s@    !



	

r   c                 C   s0  t | } t |}t |}t |}t|dkr8dS |dk}| | || k  sh| | || k rvd}dd|fS t |}| | } || }|| }|| }||  | }||  | }	tt ||	}
tt ||	}|
|krd}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   Zasarrayr   anyZlogical_notr$   minimumr%   maximum)r&   r'   lbubr)   Zzero_dr,   Z
not_zero_dZt_lbZt_ubr*   r+   r   r   r   r	      s<    %



(



r	   c                 C   s   t | ||||\}}}	t| |||\}
}}t||
}t||}|	rX|rX||krXd}nd}|r|
||d}|||	d}|||||fS |||fS d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)r*   r+   r,   N)r	   r   r   r0   r/   )r&   r'   r1   r2   r(   r)   Z
extra_infoZta_bZtb_bZintersect_bZta_sZtb_sZintersect_sr*   r+   r,   Zsphere_infoZbox_infor   r   r   r
      s"    1


r
   c                 C   s   || k  o| |k  S )zCheck if lb <= x <= ub.)allr   r1   r2   r   r   r   r   1  s    r   c                 C   s   t t | ||S )zReturn clipped value of x)r   r/   r0   r4   r   r   r   reinforce_box_boundaries6  s    r5   c                 C   s$  | | }t|||r,t||kr,|}|S | j |}|  |}	t || t |	|	 | }
t|
}|
}||
 }t|||||\}}}|r|||  }n*|}|
}t|||||\}}}|||  }|}|}t|||||\}}}|||  }t|  || t|  || k r|S |S d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.
    N)r!   r   r   r   r   
zeros_liker
   )r   Yr   r(   r1   r2   Znewton_pointr   gZA_gZcauchy_pointZorigin_pointr&   p_alphar,   x1Zx2r   r   r   r   ;  s@    0








&r   c           (   	   C   s  d}t |\}t |\}|| }|| || }||}| }|rV|g}| |}t|d }|t| }|dk rtdn2||k rdddd}|r|| ||d< ||fS |du rttd	t | d
| |}|du rt 	|t j
 }|du rt 	|t j
}|	du r$|| }	t|	|| }	|
du rD|| }
d}d}d}t |}d}t|	D ]}||k rd} qL|d7 }||}|dkrt |rtdnFt|||||dd\}} }!|!r|| |  }t|||}d}d} qL|| } || |  }"t j|"|krht|| | |||\}}#}!|!rN||#|  |  }t|||}d}d} qLt|"||r|d}n|d7 }|dkrt|| | |||\}}#}!|!r||#|  |  }t|||}d}||
kr qL|r||" || |  }$||$}%t|%d }&|&| }'|% |'|  }|"}|%}|%}t|d }| |}qft|||sb|}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)Zniter	stop_condhits_boundaryallvecsNg{Gz?g?Fr   r   z9Negative curvature not allowed for unrestricted problems.)r)      )r   r   r!   r   
ValueErrorappendr$   r%   r"   fullr    r6   ranger   r
   r5   r   r   )(r   r   Zr7   r   r(   r1   r2   ZtolZmax_iterZmax_infeasible_iterZ
return_allZCLOSE_TO_ZEROr   r   r   rr8   r9   r?   ZH_pZrt_gZtr_distanceinfor>   r=   counterZlast_feasible_xkiZpt_H_pr:   r;   r,   Zx_nextthetaZr_nextZg_nextZ	rt_g_nextbetar   r   r   r     s    P

















r   )F)F)FF)__doc__Zscipy.sparser   r   r   mathr   numpyr   Znumpy.linalgr   __all__r   r   r	   r
   r   r5   r   r    r   r   r   r   r   <module>   s*   . 
W 
V  
E`