Does my Model have Numerical Issues?#

You can use the following suggestions to identify if a model is facing numerical issues:

  1. Check the model statistics. This Python code reads a model file and prints the summary statistics:

    import gurobipy as gp
    m = gp.read('gurobi.rew')
    m.printStats()
    

    The output will look like:

    Statistics for model (null) :
      Linear constraint matrix    : 25050 Constrs, 15820 Vars, 94874 NZs
      Variable types              : 14836 Continuous, 984 Integer
      Matrix coefficient range    : [ 0.00099, 6e+06 ]
      Objective coefficient range : [ 0.2, 65 ]
      Variable bound range        : [ 1, 5e+07 ]
      RHS coefficient range       : [ 1, 5e+07 ]
    

    The range of numerical coefficients is one indication of potential numerical issues. As a very rough guideline, the ratio of the largest to the smallest coefficient should be less than \(10^9\); ideally less than \(10^6\).

    In this example, the matrix range is

    \[6\cdot10^6 / 0.00099 = 6.0606\cdot10^9.\]
  2. Solve the model and review the log for warning messages. The Python function is:

    m.optimize()
    

    Here are some examples of warning messages that suggest numerical issues:

    Warning: Model contains large matrix coefficient range
             Consider reformulating model or setting NumericFocus parameter
             to avoid numerical issues.
    Warning: Markowitz tolerance tightened to 0.5
    Warning: switch to quad precision
    Numeric error
    Numerical trouble encountered
    Restart crossover...
    Sub-optimal termination
    Warning: ... variables dropped from basis
    Warning: unscaled primal violation = ... and residual = ...
    Warning: unscaled dual violation = ... and residual = ...
    
  3. When the optimize function completes and a solution was found, print solution statistics. The Python function is the following:

    m.printQuality()
    

    which provides a summary of solution quality:

    Solution quality statistics for model Unnamed :
      Maximum violation:
        Bound       : 2.98023224e-08 (X234)
        Constraint  : 9.30786133e-04 (C5)
        Integrality : 0.00000000e+00
    

    Violations that are larger than the tolerances are another indication of numerical issues.

    Additionally, for a pure LP (without integer variables), print the condition number KappaExact which is a model attribute and can be accessed via Python as follows:

    m.KappaExact
    

    The condition number measures the potential for error in linear calculations; a large condition number, such as \(10^{12}\), is another indication of possible numerical issues, see this section for more details.

  4. Re-solve the optimization with different parameter settings, e.g., change the value of Seed or Method. If changing parameters leads to a different optimization status (e.g., Infeasible instead of optimal), or if the optimal objective values changes, this is usually a sign of numerical issues. To further assess this you can tighten tolerances (to the order of \(10^{-8}\) or even \(10^{-9}\)), and see if the behavior of the solver becomes consistent again. Note that tightening tolerances usually comes at the price of more computing time, and should not be considered as a solution for numerical issues.