o
    EbA                     @   s   d Z ddlZddlZddlmZmZmZ ddlm	Z	 ddl
mZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& ddl'm(Z(m)Z)m*Z* d	d
 Z+dd Z,						dddZ-dS )ar  HiGHS Linear Optimization Methods

Interface to HiGHS linear optimization software.
https://www.maths.ed.ac.uk/hall/HiGHS/

.. versionadded:: 1.5.0

References
----------
.. [1] Q. Huangfu and J.A.J. Hall. "Parallelizing the dual revised simplex
           method." Mathematical Programming Computation, 10 (1), 119-142,
           2018. DOI: 10.1007/s12532-017-0130-5

    N   )_check_unknown_optionsOptimizeWarningOptimizeResult)warn)_highs_wrapper)CONST_I_INF	CONST_INFMESSAGE_LEVEL_MINIMALMODEL_STATUS_NOTSETMODEL_STATUS_LOAD_ERRORMODEL_STATUS_MODEL_ERRORMODEL_STATUS_PRESOLVE_ERRORMODEL_STATUS_SOLVE_ERRORMODEL_STATUS_POSTSOLVE_ERRORMODEL_STATUS_MODEL_EMPTYMODEL_STATUS_PRIMAL_INFEASIBLEMODEL_STATUS_PRIMAL_UNBOUNDEDMODEL_STATUS_OPTIMAL5MODEL_STATUS_REACHED_DUAL_OBJECTIVE_VALUE_UPPER_BOUNDMODEL_STATUS_REACHED_TIME_LIMIT$MODEL_STATUS_REACHED_ITERATION_LIMIT#MODEL_STATUS_PRIMAL_DUAL_INFEASIBLEMODEL_STATUS_DUAL_INFEASIBLEHIGHS_SIMPLEX_STRATEGY_CHOOSEHIGHS_SIMPLEX_STRATEGY_DUAL HIGHS_SIMPLEX_CRASH_STRATEGY_OFF.HIGHS_SIMPLEX_DUAL_EDGE_WEIGHT_STRATEGY_CHOOSE/HIGHS_SIMPLEX_DUAL_EDGE_WEIGHT_STRATEGY_DANTZIG-HIGHS_SIMPLEX_DUAL_EDGE_WEIGHT_STRATEGY_DEVEX5HIGHS_SIMPLEX_DUAL_EDGE_WEIGHT_STRATEGY_STEEPEST_EDGE)
csc_matrixvstackissparsec                 C   s$   t | }t | | t | |< | S )N)npZisinfsignr	   )xZinfs r'   ?/usr/lib/python3/dist-packages/scipy/optimize/_linprog_highs.py_replace_inf8   s   
r)   c                 C   s   z||    W S  ty   ||   Y S  tyC   tt}|j| j}td| d|  dt	|
  d| d	tdd ||  Y S w )NzOption z is z, but only values in z are allowed. Using default: .   )
stacklevel)lowerAttributeErrorKeyErrorinspectZ	signature_linprog_highsZ
parametersdefaultr   setkeysr   )optionZ
option_strchoicesZsigZdefault_strr'   r'   r(   _convert_to_highs_enum?   s    

r7   TFc
           -      K   s2  t |
 t|	dttttddd}tdtdtdt	dt
d	td
tdtdtdtdtdtdtdtdtdi}| \}}}}}}}|j \}}t| tj }|}|}|}t||f}t||f}t|sft|rmt||f}nt||f}t|}|d||t| ||||tt ||d}t!|}t!|}t!|}t!|}t"||j#|j$|j%|||||	}d|v r|d }t&|t'|d } t&|dt'| }nd\}} d|v r|d }!t&|!dt'| }"t&|!t'|d }#t&|d dddf }$t&|d dddf }%nd\}"}#d\}$}%dddd}&|d tkr6|d |d kr6||d  \}'}(d d!|( d"})}*n||d  \})}*d#|v rJt&|d# nd}+|+|| t(||"d$t(| |#d$t(|+du rcdn|+| |%d$t(|+du rrdn||+ |$d$|)d%|)|d tk|*|)d&dp|)d'd|)d(d)},|,S )*a  
    Solve the following linear programming problem using one of the HiGHS
    solvers:

    User-facing documentation is in _linprog_doc.py.

    Parameters
    ----------
    lp :  _LPProblem
        A ``scipy.optimize._linprog_util._LPProblem`` ``namedtuple``.
    solver : "ipm" or "simplex" or None
        Which HiGHS solver to use.  If ``None``, "simplex" will be used.

    Options
    -------
    maxiter : int
        The maximum number of iterations to perform in either phase. For
        ``solver='ipm'``, this does not include the number of crossover
        iterations.  Default is the largest possible value for an ``int``
        on the platform.
    disp : bool
        Set to ``True`` if indicators of optimization status are to be printed
        to the console each iteration; default ``False``.
    time_limit : float
        The maximum time in seconds allotted to solve the problem; default is
        the largest possible value for a ``double`` on the platform.
    presolve : bool
        Presolve attempts to identify trivial infeasibilities,
        identify trivial unboundedness, and simplify the problem before
        sending it to the main solver. It is generally recommended
        to keep the default setting ``True``; set to ``False`` if presolve is
        to be disabled.
    dual_feasibility_tolerance : double
        Dual feasibility tolerance.  Default is 1e-07.
        The minimum of this and ``primal_feasibility_tolerance``
        is used for the feasibility tolerance when ``solver='ipm'``.
    primal_feasibility_tolerance : double
        Primal feasibility tolerance.  Default is 1e-07.
        The minimum of this and ``dual_feasibility_tolerance``
        is used for the feasibility tolerance when ``solver='ipm'``.
    ipm_optimality_tolerance : double
        Optimality tolerance for ``solver='ipm'``.  Default is 1e-08.
        Minimum possible value is 1e-12 and must be smaller than the largest
        possible value for a ``double`` on the platform.
    simplex_dual_edge_weight_strategy : str (default: None)
        Strategy for simplex dual edge weights. The default, ``None``,
        automatically selects one of the following.

        ``'dantzig'`` uses Dantzig's original strategy of choosing the most
        negative reduced cost.

        ``'devex'`` uses the strategy described in [15]_.

        ``steepest`` uses the exact steepest edge strategy as described in
        [16]_.

        ``'steepest-devex'`` begins with the exact steepest edge strategy
        until the computation is too costly or inexact and then switches to
        the devex method.

        Curently, using ``None`` always selects ``'steepest-devex'``, but this
        may change as new options become available.

    unknown_options : dict
        Optional arguments not used by this particular solver. If
        ``unknown_options`` is non-empty, a warning is issued listing all
        unused options.

    Returns
    -------
    sol : dict
        A dictionary consisting of the fields:

            x : 1D array
                The values of the decision variables that minimizes the
                objective function while satisfying the constraints.
            fun : float
                The optimal value of the objective function ``c @ x``.
            slack : 1D array
                The (nominally positive) values of the slack,
                ``b_ub - A_ub @ x``.
            con : 1D array
                The (nominally zero) residuals of the equality constraints,
                ``b_eq - A_eq @ x``.
            success : bool
                ``True`` when the algorithm succeeds in finding an optimal
                solution.
            status : int
                An integer representing the exit status of the algorithm.

                ``0`` : Optimization terminated successfully.

                ``1`` : Iteration or time limit reached.

                ``2`` : Problem appears to be infeasible.

                ``3`` : Problem appears to be unbounded.

                ``4`` : The HiGHS solver ran into a problem.

            message : str
                A string descriptor of the exit status of the algorithm.
            nit : int
                The total number of iterations performed.
                For ``solver='simplex'``, this includes iterations in all
                phases. For ``solver='ipm'``, this does not include
                crossover iterations.
            crossover_nit : int
                The number of primal/dual pushes performed during the
                crossover routine for ``solver='ipm'``.  This is ``0``
                for ``solver='simplex'``.
            ineqlin : OptimizeResult
                Solution and sensitivity information corresponding to the
                inequality constraints, `b_ub`. A dictionary consisting of the
                fields:

                residual : np.ndnarray
                    The (nominally positive) values of the slack variables,
                    ``b_ub - A_ub @ x``.  This quantity is also commonly
                    referred to as "slack".

                marginals : np.ndarray
                    The sensitivity (partial derivative) of the objective
                    function with respect to the right-hand side of the
                    inequality constraints, `b_ub`.

            eqlin : OptimizeResult
                Solution and sensitivity information corresponding to the
                equality constraints, `b_eq`.  A dictionary consisting of the
                fields:

                residual : np.ndarray
                    The (nominally zero) residuals of the equality constraints,
                    ``b_eq - A_eq @ x``.

                marginals : np.ndarray
                    The sensitivity (partial derivative) of the objective
                    function with respect to the right-hand side of the
                    equality constraints, `b_eq`.

            lower, upper : OptimizeResult
                Solution and sensitivity information corresponding to the
                lower and upper bounds on decision variables, `bounds`.

                residual : np.ndarray
                    The (nominally positive) values of the quantity
                    ``x - lb`` (lower) or ``ub - x`` (upper).

                marginals : np.ndarray
                    The sensitivity (partial derivative) of the objective
                    function with respect to the lower and upper
                    `bounds`.

    Notes
    -----
    The result fields `ineqlin`, `eqlin`, `lower`, and `upper` all contain
    `marginals`, or partial derivatives of the objective function with respect
    to the right-hand side of each constraint. These partial derivatives are
    also referred to as "Lagrange multipliers", "dual values", and
    "shadow prices". The sign convention of `marginals` is opposite that
    of Lagrange multipliers produced by many nonlinear solvers.

    References
    ----------
    .. [15] Harris, Paula MJ. "Pivot selection methods of the Devex LP code."
            Mathematical programming 5.1 (1973): 1-28.
    .. [16] Goldfarb, Donald, and John Ker Reid. "A practicable steepest-edge
            simplex algorithm." Mathematical Programming 12.1 (1977): 361-371.
    !simplex_dual_edge_weight_strategyN)ZdantzigZdevexzsteepest-devexZsteepestN)r6   )   z+HiGHS Status Code 0: HighsModelStatusNOTSET)r9   z/HiGHS Status Code 1: HighsModelStatusLOAD_ERROR)   z0HiGHS Status Code 2: HighsModelStatusMODEL_ERROR)r9   z3HiGHS Status Code 4: HighsModelStatusPRESOLVE_ERROR)r9   z0HiGHS Status Code 5: HighsModelStatusSOLVE_ERROR)r9   z4HiGHS Status Code 6: HighsModelStatusPOSTSOLVE_ERROR)r9   z0HiGHS Status Code 3: HighsModelStatusMODEL_EMPTY)r9   zNHiGHS Status Code 10: HighsModelStatusREACHED_DUAL_OBJECTIVE_VALUE_UPPER_BOUND)r:   zThe problem is infeasible.)r+   zThe problem is unbounded.)r   z%Optimization terminated successfully.)r   zTime limit reached.)r   zIteration limit reached.)r:   z&The problem is primal/dual infeasible.)r:   zThe problem is dual infeasible.r   )presolveZsensesolver
time_limitZmessage_leveldual_feasibility_toleranceipm_optimality_toleranceprimal_feasibility_tolerancer8   Zsimplex_strategyZsimplex_crash_strategyZipm_iteration_limitZsimplex_iteration_limitslack)NNlambdaZ	marg_bndsr   z	highs-ipmzhighs-ds)ZipmZsimplexNstatusZunscaled_statusr9   z:An optimal solution to the scaled model was found but was zN in the unscaled model. For more information run with the option `disp: True`.r&   )ZresidualZ	marginalsfunZsimplex_nitZipm_nitcrossover_nit)r&   rA   conZineqlinZeqlinr-   upperrD   rC   ZsuccessmessageZnitrE   )*r   r7   r   r   r   r    r   r   r   r   r   r   r   MODEL_STATUS_RDOVUBr   r   r   r   r   r   r   Tcopyr$   Z	ones_likeinfZconcatenater#   r"   r!   r
   r   r   r)   r   ZindptrindicesdataZarraylenr   get)-Zlpr<   r=   r;   Zdispmaxiterr>   r@   r?   r8   Zunknown_optionsZ&simplex_dual_edge_weight_strategy_enumZstatusescZA_ubZb_ubZA_eqZb_eqZboundsZx0ZlbZubZlhs_ubZrhs_ubZlhs_eqZrhs_eqZlhsZrhsAoptionsresrA   rF   ZlamdaZmarg_ineqlinZ
marg_eqlinZ
marg_upperZ
marg_lowerZsolversZ_unscaled_statusZunscaled_messagerC   rH   r&   Zsolr'   r'   r(   r1   P   s    2@

r1   )NTFNNNNN).__doc__r0   Znumpyr$   	_optimizer   r   r   warningsr   Z_highs._highs_wrapperr   Z_highs._highs_constantsr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   rI   r   r   r   r   r   r   r   r   r   r   r    Zscipy.sparser!   r"   r#   r)   r7   r1   r'   r'   r'   r(   <module>   s"    l 