Skip to content

Commit 32e5df2

Browse files
committed
allow _reduce_convex_constraints to keep reducing iteratively until it cannot reduce further
1 parent 91fbf4b commit 32e5df2

1 file changed

Lines changed: 34 additions & 22 deletions

File tree

hydradx/model/solver/omnix_solver.py

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -750,47 +750,59 @@ def copy_cone(cone, cone_size: int = None):
750750

751751

752752
def _reduce_convex_constraints(A, b, cones, cone_sizes):
753-
# condense the problem
754-
# identify variables that are zero
755-
zero_constraints = []
756753
zero_is = []
757754
rows_seen = 0
758-
759-
for i, cone in enumerate(cones):
755+
for i, cone in enumerate(cones): # identify variables that are zero
760756
if isinstance(cone, cb.ZeroConeT):
761757
for j in range(cone_sizes[i]):
762758
if np.count_nonzero(A[rows_seen + j, :]) == 1 and b[rows_seen + j] == 0:
763-
zero_constraints.append(rows_seen + j)
764759
zero_is.append(np.nonzero(A[rows_seen + j, :])[0][0])
765760
rows_seen += cone_sizes[i]
761+
A_reduced = np.delete(A, zero_is, axis=1) # delete columns that are zero
766762

767-
# remove variables that are zero
768-
A_reduced = np.delete(A, zero_constraints, axis=0)
769-
A_reduced = np.delete(A_reduced, zero_is, axis=1)
770-
b_reduced = np.delete(b, zero_constraints)
771-
rows_seen = 0
772-
zero_rows = []
763+
constraints_to_delete = []
773764
new_cones = []
774765
new_cone_sizes = []
775-
for i in range(len(cones)):
776-
cone_size = cone_sizes[i]
777-
new_cones.append(copy_cone(cones[i], cone_sizes[i]))
778-
if isinstance(cones[i], cb.ZeroConeT):
766+
rows_seen = 0
767+
for i, cone in enumerate(cones): # identify rows that are zero in linear cones
768+
new_cone_size = cone_sizes[i]
769+
new_cone = copy_cone(cone, cone_sizes[i])
770+
if isinstance(cone, cb.ZeroConeT):
779771
for j in range(cone_sizes[i]):
780-
if rows_seen + j in zero_constraints:
781-
cone_size -= 1
782-
new_cones[i] = cb.ZeroConeT(cone_size)
772+
if np.count_nonzero(A_reduced[rows_seen + j, :]) == 0 and b[rows_seen + j] == 0:
773+
constraints_to_delete.append(rows_seen + j)
774+
new_cone_size -= 1
775+
new_cone = cb.ZeroConeT(new_cone_size)
776+
elif isinstance(cone, cb.NonnegativeConeT):
777+
for j in range(cone_sizes[i]):
778+
if np.count_nonzero(A_reduced[rows_seen + j, :]) == 0 and b[rows_seen + j] == 0:
779+
constraints_to_delete.append(rows_seen + j)
780+
new_cone_size -= 1
781+
new_cone = cb.NonnegativeConeT(new_cone_size)
782+
new_cones.append(new_cone)
783+
new_cone_sizes.append(new_cone_size)
783784
rows_seen += cone_sizes[i]
784-
new_cone_sizes.append(cone_size)
785+
A_reduced = np.delete(A_reduced, constraints_to_delete, axis=0) # delete rows that are zero
786+
b_reduced = np.delete(b, constraints_to_delete)
787+
788+
assert A.shape[0] >= A_reduced.shape[0], "Reduced A has more rows than original A"
785789

786790
return A_reduced, b_reduced, new_cones, new_cone_sizes, zero_is
787791

788792

789793
def _reduce_convex_problem(A, b, cones, cone_sizes, q):
794+
orig_var_ct = A.shape[1]
790795
A_reduced, b_reduced, new_cones, new_cone_sizes, zero_is = _reduce_convex_constraints(A, b, cones, cone_sizes)
796+
vars_kept = [i for i in range(orig_var_ct) if i not in zero_is]
797+
while A_reduced.shape[0] < A.shape[0]: # keep reducing until no more constraints can be removed
798+
A, b, cones, cone_sizes = A_reduced, b_reduced, new_cones, new_cone_sizes
799+
A_reduced, b_reduced, new_cones, new_cone_sizes, zero_is = _reduce_convex_constraints(A, b, cones, cone_sizes)
800+
vars_kept = [x for i, x in enumerate(vars_kept) if i not in zero_is]
801+
802+
vars_removed = [i for i in range(orig_var_ct) if i not in vars_kept]
791803
# remove variables that are zero from q
792-
q_reduced = np.delete(q, zero_is)
793-
return A_reduced, b_reduced, new_cones, new_cone_sizes, q_reduced, zero_is
804+
q_reduced = np.delete(q, vars_removed)
805+
return A_reduced, b_reduced, new_cones, new_cone_sizes, q_reduced, vars_removed
794806

795807

796808
def _find_solution_unrounded(

0 commit comments

Comments
 (0)