summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <np@0hm.ch>2024-05-10 18:51:26 +0200
committerNao Pross <np@0hm.ch>2024-05-10 18:51:26 +0200
commit6eb0cf8879634c973fffe1be7061f491eca327b1 (patch)
tree319272f5fb9433787a80ddf3f499bf0fec7d1694
parentPrepare stub for MOSEK solver interface (diff)
downloadsumofsquares-6eb0cf8879634c973fffe1be7061f491eca327b1.tar.gz
sumofsquares-6eb0cf8879634c973fffe1be7061f491eca327b1.zip
Fix bug caused by non-scalar variables
-rw-r--r--sumofsquares/solver/cvxopt.py36
1 files changed, 21 insertions, 15 deletions
diff --git a/sumofsquares/solver/cvxopt.py b/sumofsquares/solver/cvxopt.py
index 0e5ce37..c4e1db3 100644
--- a/sumofsquares/solver/cvxopt.py
+++ b/sumofsquares/solver/cvxopt.py
@@ -3,6 +3,7 @@ Solve sumofsquares problems using CVXOPT
"""
import cvxopt
import numpy as np
+import math
from collections import UserDict
from numpy.typing import NDArray
@@ -65,17 +66,15 @@ def solve_sos_cone(prob: Problem, verbose: bool = False,
G_rows, h_rows= [], []
l_dims, q_dims, s_dims = [], [], []
- # Collect variable indices in dictionary and sort them by value
- # i.e. we want variable_indices.values() to be sorted
- variable_indices: dict[OptVariable, VariableIndex] = dict(sorted({
- # FIXME there can be more than one indices associated to v
- v: next(prob.state.get_indices_as_variable_index(v))
- for v in prob.variables
- }.items(), key=lambda item: item[1]))
+ # indices of variables in the optimization problem
+ variable_indices = sum(sorted(tuple(prob.state.get_indices_as_variable_index(v))
+ for v in prob.variables), ())
# cost linear term
- cost_coeffs = dict(cost.affine_coefficients_by_degrees(variable_indices.values()))
- q = cost_coeffs[1].T
+ cost_coeffs = dict(cost.affine_coefficients_by_degrees(variable_indices))
+ q = cost_coeffs.get(1)
+ if q is None:
+ q = np.zeros((len(variable_indices), 1))
# cost quadratic term
if is_qp:
@@ -114,10 +113,9 @@ def solve_sos_cone(prob: Problem, verbose: bool = False,
# Linear term
l_stacked_rows = []
- for v in variable_indices.values():
+ for v in variable_indices:
# Get the affine coefficient associated to this variable
- linear = MonomialIndex((v,))
- v_coeff = constr.affine_coefficient(linear)
+ v_coeff = constr.affine_coefficient(v)
# stack the columns of coeff matrix into a fat row vector (column major order).
v_stacked = v_coeff.T.reshape((nrows * ncols,))
@@ -145,7 +143,7 @@ def solve_sos_cone(prob: Problem, verbose: bool = False,
"into the canonical form of CVXOPT.")
# Convert to CVXOPT matrices
- q = cvxopt.matrix(q)
+ q = cvxopt.matrix(q.T)
G = cvxopt.matrix(np.hstack(G_rows).T) if G_rows else None
h = cvxopt.matrix(np.hstack(h_rows)) if h_rows else None
A = cvxopt.matrix(np.hstack(A_rows).T) if A_rows else None
@@ -177,7 +175,15 @@ def solve_sos_cone(prob: Problem, verbose: bool = False,
*args, **kwargs)
results = {}
- for i, v in enumerate(variable_indices.keys()):
- results[v] = info['x'][i]
+
+ i = 0
+ for variable in prob.variables:
+ num_indices = math.prod(variable.shape)
+ values = np.array(info['x'][i:i+num_indices]).reshape(variable.shape)
+ if values.shape == (1, 1):
+ values = values[0, 0]
+
+ results[variable] = values
+ i += num_indices
return results, CVXOPTInfo(info)