embotech/ecos

NUMERICAL PROBLEMS / Slacks/multipliers leaving the cone

Closed this issue · 3 comments

Hello,
I have the following program:

#!/usr/bin/env python

import cvxpy as cp
from cvxpy.settings import OPTIMAL, OPTIMAL_INACCURATE
from math import sqrt
from typing import *


Vbase = 231
Sbase = 1e6
Zbase = Vbase**2 / Sbase

buses: List[dict] = [
    {'id':1, 'pc':0,    'pg':0,    'qc':0,        'sg':0},
    {'id':2, 'pc':5e03, 'pg':3e03,  'qc':5e03,      'sg':10e03},
    {'id':3, 'pc':4e03,  'pg':3e03,  'qc':6.113e03, 'sg':10e03},
    {'id':4, 'pc':10e03, 'pg':3e03,  'qc':0e03,      'sg':10e03},
]

lines = [
    {'r':0.09323, 'x':0.05585},
    {'r':0.19495, 'x':0.0812},
    {'r':0.11738, 'x':0.02925},
]


V0=231.0
epsilon=0.05

##############################################################################

V0 = V0/Vbase

r = [line['r']/Zbase for line in lines]
x = [line['x']/Zbase for line in lines]

Q = cp.Variable((len(buses)))
P = cp.Variable((len(buses)))
U = cp.Variable((len(buses)))

pc = [bus['pc']/Sbase for bus in buses]
qc = [bus['qc']/Sbase for bus in buses]

qg = [cp.Parameter(value=0), cp.Variable(), cp.Variable(), cp.Variable()]
pg = [bus['pg']/Sbase for bus in buses]

sg = [bus['sg']/Sbase for bus in buses]
s_h = [sqrt(sg[j]**2 - pg[j]**2) for j in range(len(buses))]

constraints = []

for j in range(len(buses)-1):
    jp1 = j+1
    constraints.extend((
        P[jp1] == (P[j] - pc[jp1] + pg[jp1]),
        Q[jp1] == (Q[j] - qc[jp1] + qg[jp1]),
        U[jp1] == (U[j] - 2 * (r[j] * P[j] + x[j] * Q[j])),
    ))
constraints.extend((
    P[len(buses)-1] == 0,
    Q[len(buses)-1] == 0,
    U[0] == 0,
))

for j in range(1, len(buses)):
    constraints.extend((
        V0**2 * (epsilon**2 - 2*epsilon) <= U[j],
                                            U[j] <= V0**2 * (epsilon**2 + 2*epsilon),
        cp.abs(qg[j]) <= s_h[j],
    ))

prob = cp.Problem(
    cp.Minimize(
        cp.sum(
            cp.multiply(
                r,
                (P[:-1]**2 + Q[:-1]**2) / V0**2
            )
        )
    ),
    constraints
)

z=cp.sum(
            cp.multiply(
                r,
                (P[:-1]**2 + Q[:-1]**2) / V0**2
            )
        )

prob.solve(verbose=True, solver=cp.ECOS)

if not prob.status in (OPTIMAL, OPTIMAL_INACCURATE):
    raise Exception(prob.status)

assert 6600 < qg[1].value * Sbase < 6900
assert 7600 < qg[2].value * Sbase < 7800
assert 2200 < qg[3].value * Sbase < 2500

running under the following environment:

pyenv install 3.6.7
pyenv virtualenv 3.6.7 foo
pyenv activate foo
pip --no-cache-dir install cvxpy

Which fails with

ECOS 2.0.7 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS

It     pcost       dcost      gap   pres   dres    k/t    mu     step   sigma     IR    |   BT
 0  +3.888e-04  -3.519e+03  +2e-201  inf  0e+00  7e-01  8e-203    ---    ---Slacks/multipliers leaving the cone, recovering best iterate (0) and stopping.

NUMERICAL PROBLEMS (reached feastol=inf, reltol=-nan, abstol=1.7e-201).Traceback (most recent call last):
  File "/home/user/.pyenv/versions/3.6.7/envs/foo/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 635, in unpack_results
    self.unpack(solution)
  File "/home/user/.pyenv/versions/3.6.7/envs/foo/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 610, in unpack
    raise ValueError("Cannot unpack invalid solution.")
ValueError: Cannot unpack invalid solution.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./bcos.py", line 65, in <module>
    prob.solve(verbose=True, solver=cp.ECOS)
  File "/home/user/.pyenv/versions/3.6.7/envs/foo/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 271, in solve
    return solve_func(self, *args, **kwargs)
  File "/home/user/.pyenv/versions/3.6.7/envs/foo/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 506, in _solve
    self.unpack_results(solution, full_chain, inverse_data)
  File "/home/user/.pyenv/versions/3.6.7/envs/foo/lib/python3.6/site-packages/cvxpy/problems/problem.py", line 639, in unpack_results
    "Try another solver or solve with verbose=True for more "
cvxpy.error.SolverError: Solver 'ECOS' failed. Try another solver or solve with verbose=True for more information. Try recentering the problem data around 0 and rescaling to reduce the dynamic range.

In a different environment (with python 3.7.x) I was getting different results every time I executed it (either failure like above or very bad results).

I have a colleague for whom it seems to be working, but I have not dug into the differences between the systems yet (I know the python, ecos and cvxpy versions are the same).

It works okay with OSQP. Are you perhaps able to reproduce this?

I just noticed the superfluous block

z=cp.sum(
            cp.multiply(
                r,
                (P[:-1]**2 + Q[:-1]**2) / V0**2
            )
        )

Removing it might get you out of the exception and into bad results. Or putting it back in might. Or it might not. Sometimes adding an import time; time.sleep(2) before solve() might trigger this, or not.

Setting the non-determinism of yesterday aside, I've created the same setup on two other machines and, indeed, ECOS runs successfully there. So far we have:

  • Machine A: Gentoo x86_64 on i7-4500U - Fails (With and without latest ucode update)
ipdb> pl.architecture(), pl.machine(), pl.platform(), pl.python_build(), pl.python_compiler(), pl.python_implementation(), pl.python_version(), pl.release(), pl.system(), pl.version(),
(('64bit', 'ELF'), 'x86_64', 'Linux-4.19.27-gentoo-r1-x86_64-Intel-R-_Core-TM-_i7-4500U_CPU_@_1.80GHz-with-gentoo-2.6', ('default', 'Apr 10 2019 09:05:50'), 'GCC 7.3.0', 'CPython', '3.6.7', '4.19.27-gentoo-r1', 'Linux', '#1 SMP Sat Apr 6 11:30:35 CEST 2019')
  • Machine B: Gentoo x86_64 on Celeron E3300 - Works
ipdb> pl.architecture(), pl.machine(), pl.platform(), pl.python_build(), pl.python_compiler(), pl.python_implementation(), pl.python_version(), pl.release(), pl.system(), pl.version(),     
(('64bit', ''), 'x86_64', 'Linux-4.14.83-gentoo-x86_64-Intel-R-_Celeron-R-_CPU_E3300_@_2.50GHz-with-gentoo-2.6', ('default', 'Apr 10 2019 09:03:31'), 'GCC 7.3.0', 'CPython', '3.6.7', '4.14.83-gentoo', 'Linux', '#1 SMP Fri Jan 4 16:51:26 EET 2019')
  • Machine C: Devuan i386 on T2130 - Works

Stepping though cvxpy in the code above on machines A and B we land at /home/user/.pyenv/versions/foo/lib/python3.6/site-packages/cvxpy/reductions/solvers/conic_solvers/ecos_conif.py(148)solve_via_data(). Both result in the same data:

> print(f"C:\n{data[s.C]}\n\nG:\n{data[s.G]}\n\nH:\n{data[s.H]}\n\nCones:\n{cones}\n\nA:\n{data[s.A]}\n\nB:\n{data[s.B]}") 

C:
[1.74715616 3.65341729 2.19973389 1.74715616 3.65341729 2.19973389
 0.         0.         0.         0.         0.         0.
 0.         0.         0.         0.         0.         0.
 0.         0.         0.         0.         0.         0.        ]

G:
  (15, 0)	-1.0
  (16, 0)	-1.0
  (18, 1)	-1.0
  (19, 1)	-1.0
  (21, 2)	-1.0
  (22, 2)	-1.0
  (24, 3)	-1.0
  (25, 3)	-1.0
  (27, 4)	-1.0
  (28, 4)	-1.0
  (30, 5)	-1.0
  (31, 5)	-1.0
  (17, 6)	-2.0
  (20, 7)	-2.0
  (23, 8)	-2.0
  (26, 10)	-2.0
  (29, 11)	-2.0
  (32, 12)	-2.0
  (2, 14)	1.0
  (3, 14)	-1.0
  (0, 16)	-1.0
  (1, 16)	1.0
  (5, 17)	-1.0
  (6, 17)	1.0
  (10, 18)	-1.0
  (11, 18)	1.0
  (7, 19)	1.0
  (8, 19)	-1.0
  (12, 20)	1.0
  (13, 20)	-1.0
  (2, 21)	-1.0
  (3, 21)	-1.0
  (4, 21)	1.0
  (7, 22)	-1.0
  (8, 22)	-1.0
  (9, 22)	1.0
  (12, 23)	-1.0
  (13, 23)	-1.0
  (14, 23)	1.0

H:
[ 0.0975      0.1025     -0.         -0.          0.00953939  0.0975
  0.1025     -0.         -0.          0.00953939  0.0975      0.1025
 -0.         -0.          0.00953939  1.         -1.          0.
  1.         -1.          0.          1.         -1.          0.
  1.         -1.          0.          1.         -1.          0.
  1.         -1.          0.        ]

Cones:
{'l': 15, 'q': [3, 3, 3, 3, 3, 3], 'e': 0}

A:
  (0, 6)	-1.0
  (2, 6)	3.4943123254811566
  (0, 7)	1.0
  (3, 7)	-1.0
  (5, 7)	7.306834579561853
  (3, 8)	1.0
  (6, 8)	-1.0
  (8, 8)	4.399467776091153
  (6, 9)	1.0
  (9, 9)	1.0
  (1, 10)	-1.0
  (2, 10)	2.0932891062761194
  (1, 11)	1.0
  (4, 11)	-1.0
  (5, 11)	3.043421225239407
  (4, 12)	1.0
  (7, 12)	-1.0
  (8, 12)	1.096306291111486
  (7, 13)	1.0
  (10, 13)	1.0
  (1, 14)	-1.0
  (2, 15)	-1.0
  (11, 15)	1.0
  (2, 16)	1.0
  (5, 16)	-1.0
  (5, 17)	1.0
  (8, 17)	-1.0
  (8, 18)	1.0
  (4, 19)	-1.0
  (7, 20)	-1.0

B:
[-0.002    -0.005    -0.       -0.001    -0.006113 -0.       -0.007
 -0.       -0.       -0.       -0.       -0.      ]

Therefore numpy seems to be working the same on both machines, while ECOS does not:

Machine A:

ECOS 2.0.7 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS

It     pcost       dcost      gap   pres   dres    k/t    mu     step   sigma     IR    |   BT
 0  +9.702e+00  +2.298e-01  +0e+00  0e+00  0e+00  1e+00  0e+00    ---    ---    0  0  - |  -  - 

OPTIMAL (within feastol=0.0e+00, reltol=0.0e+00, abstol=0.0e+00).
Runtime: 0.000204 seconds.

--------------------------------------------------------------------------------------------------------------------------

ipdb> pprint(solution)                                                                                                                                                                        
{'info': {'dcost': 0.22982938543193038,
          'dinf': 0.0,
          'dinfres': nan,
          'dres': 0.0,
          'exitFlag': 0,
          'gap': 0.0,
          'infostring': 'Optimal solution found',
          'iter': 0,
          'mi_iter': -1,
          'numerr': 0,
          'pcost': 9.701526081563065,
          'pinf': 0.0,
          'pinfres': nan,
          'pres': 0.0,
          'r0': 1e-08,
          'relgap': 0.0,
          'timing': {'runtime': 0.000204425,
                     'tsetup': 0.000128833,
                     'tsolve': 7.5592e-05}},
 's': array([inf, nan, nan, nan, inf, inf, inf, inf, inf, inf, inf, nan, nan,
       nan, nan, nan, nan, nan, nan, nan, nan, nan, inf, inf, inf, inf,
       inf, inf, inf, inf, inf, inf, inf]),
 'x': array([1.26287353e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       1.27067061e+00, 1.29688362e+00, 3.60896340e-01, 3.81579800e-13,
       2.00414011e-06, 9.99972088e-01, 5.65065001e-01, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 1.57401079e+59, 3.37510073e-04]),
 'y': array([1.07850946e+00, 0.00000000e+00, 1.61806591e-03, 1.70398946e-03,
       3.20797645e-03, 1.14155965e-03, 3.39128939e-03, 9.77669014e-04,
       1.52943527e-03, 3.08576782e-03, 3.54405017e-03, 3.48294586e-03]),
 'z': array([6.74626390e-01, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       6.74626388e-01, 6.74626388e-01, 6.74626388e-01, 9.93339630e-01,
       2.79092443e-05, 9.99972088e-01, 6.74626385e-01, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 2.33421652e-01,
       2.33421652e-01, 2.22516953e-01, 4.50487776e-13, 7.50812960e-14,
       1.99429999e-01, 2.95615437e-01, 4.71039344e-13, 1.04504913e-13,
       2.06479420e-01, 2.06479424e-01, 0.00000000e+00, 1.96509831e-01,
       5.63601168e-13])}

Machine B:

ECOS 2.0.7 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS

It     pcost       dcost      gap   pres   dres    k/t    mu     step   sigma     IR    |   BT
 0  +1.204e-16  -2.519e+00  +5e+01  7e-01  8e-02  1e+00  2e+00    ---    ---    1  1  - |  -  -                                                                                              
 1  -8.302e-01  -9.302e-01  +3e+00  7e-02  3e-03  6e-02  1e-01  0.9603  1e-02   1  1  1 |  0  0                                                                                              
 2  -5.039e-02  -5.689e-02  +2e-01  4e-03  2e-04  3e-03  9e-03  0.9301  3e-03   2  2  2 |  0  0                                                                                              
 3  -4.068e-03  -4.747e-03  +2e-02  3e-04  1e-05  2e-04  9e-04  0.9315  4e-02   1  2  2 |  0  0                                                                                              
 4  -4.761e-04  -6.526e-04  +5e-03  9e-05  4e-06  5e-05  2e-04  0.7517  3e-02   1  1  2 |  0  0                                                                                              
 5  -1.397e-04  -2.416e-04  +3e-03  6e-05  2e-06  4e-05  2e-04  0.6099  4e-01   1  1  1 |  0  0                                                                                              
 6  +5.234e-04  +5.076e-04  +5e-04  9e-06  4e-07  6e-06  2e-05  0.8529  1e-02   1  1  1 |  0  0                                                                                              
 7  +6.162e-04  +6.129e-04  +1e-04  2e-06  9e-08  2e-06  6e-06  0.9890  2e-01   1  1  1 |  0  0                                                                                              
 8  +6.429e-04  +6.428e-04  +4e-06  6e-08  3e-09  6e-08  2e-07  0.9701  6e-04   2  1  1 |  0  0                                                                                              
 9  +6.438e-04  +6.438e-04  +8e-08  1e-09  6e-11  1e-09  4e-09  0.9777  1e-04   1  1  1 |  0  0                                                                                              
10  +6.438e-04  +6.438e-04  +4e-09  7e-11  3e-12  6e-11  2e-10  0.9502  1e-04   1  1  1 |  0  0                                                                                              

OPTIMAL (within feastol=6.9e-11, reltol=6.4e-06, abstol=4.1e-09).
Runtime: 0.005448 seconds.

--------------------------------------------------------------------------------------------------------------------------

ipdb> pprint(solution)                                                                                                                                                                       
{'info': {'dcost': 0.0006438011394196911,                                                                                                                                                    
          'dinf': 0.0,                                                                                                                                                                       
          'dinfres': nan,                                                                                                                                                                    
          'dres': 2.9100825007592447e-12,                                                                                                                                                    
          'exitFlag': 0,                                                                                                                                                                     
          'gap': 4.0952666110284685e-09,                                                                                                                                                     
          'infostring': 'Optimal solution found',
          'iter': 10,
          'mi_iter': -1,
          'numerr': 0,
          'pcost': 0.0006438012511756154,
          'pinf': 0.0,
          'pinfres': 0.816875053174683,
          'pres': 6.854394881079808e-11,
          'r0': 1e-08,
          'relgap': 6.361073878682253e-06,
          'timing': {'runtime': 0.00544805,
                     'tsetup': 0.000148619,
                     'tsolve': 0.005299431}},
 's': array([ 7.45321338e-02,  1.25467866e-01,  1.63584218e-03,  1.51193082e-02,
        1.16181695e-03,  2.81873888e-02,  1.71812611e-01,  8.94485316e-04,
        1.63191683e-02,  9.32565301e-04,  6.02644231e-09,  1.99999994e-01,
        6.60892541e-03,  1.13683465e-02,  5.50756144e-04,  1.00010000e+00,
       -9.99900000e-01,  2.00000000e-02,  1.00006400e+00, -9.99936000e-01,
        1.60000000e-02,  1.00004900e+00, -9.99951000e-01,  1.40000000e-02,
        1.00003273e+00, -9.99967273e-01, -1.14415701e-02,  1.00001583e+00,
       -9.99984167e-01, -7.95810412e-03,  1.00000566e+00, -9.99994337e-01,
       -4.75942112e-03]),                                                                                                                                                                    
 'x': array([ 9.99999397e-05,  6.39999358e-05,  4.89999380e-05,  3.27272977e-05,                                                                                                             
        1.58327859e-05,  5.66294417e-06,  9.99999999e-03,  7.99999999e-03,
        6.99999999e-03, -4.24740487e-12, -5.72078504e-03, -3.97905206e-03,
       -2.37971056e-03,  8.95019745e-14,  6.74173298e-03,  2.70852792e-13,
       -2.29678662e-02, -6.93126113e-02, -9.74999940e-02,  7.71234150e-03,
        2.37971056e-03,  8.37757512e-03,  8.60682676e-03,  8.98863592e-03]),                                                                                                                 
 'y': array([ 6.83124438e-02,  6.30362358e-08,  9.54961239e-03,  1.96544409e-01,                                                                                                             
        5.95711919e-08,  9.54961207e-03,  2.69353874e-01,  1.05583884e-08,
        9.54961021e-03, -2.69353874e-01, -1.05583884e-08,  9.54961239e-03]),                                                                                                                 
 'z': array([ 8.25643751e-10,  5.04223239e-10,  6.70121778e-08,  3.97639434e-09,                                                                                                             
        7.09389501e-08,  2.23767159e-09,  3.79234957e-10,  6.37037705e-08,
        4.13238745e-09,  6.77868078e-08,  9.54961053e-03,  3.20778864e-10,
        1.72446811e-08,  6.68629041e-09,  2.38815441e-08,  8.73665439e-01,
        8.73490724e-01, -1.74715578e-02,  1.82682555e+00,  1.82659174e+00,
       -2.92272649e-02,  1.09992084e+00,  1.09981305e+00, -1.53981310e-02,
        8.73606671e-01,  8.73549492e-01,  9.99501828e-03,  1.82673755e+00,
        1.82667974e+00,  1.45317478e-02,  1.09987317e+00,  1.09986072e+00,
        5.23467338e-03])}

Not a bug in ecos after all -- see issue referenced above.

stderred was overriding the init function of ecos, meaning w was never initialized and its contents were left at the mercy of malloc. Explains the non-deterministic behavior.