Skip to content

Commit

Permalink
Blacking
Browse files Browse the repository at this point in the history
  • Loading branch information
emma58 committed Jun 25, 2024
1 parent 8d582c9 commit 4c32954
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 44 deletions.
16 changes: 7 additions & 9 deletions pyomo/repn/plugins/parameterized_standard_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________

from pyomo.common.config import (
ConfigValue,
document_kwargs_from_configdict
)
from pyomo.common.config import ConfigValue, document_kwargs_from_configdict
from pyomo.common.dependencies import numpy as np
from pyomo.common.gc_manager import PauseGC

Expand All @@ -21,7 +18,7 @@
from pyomo.repn.plugins.standard_form import (
LinearStandardFormInfo,
LinearStandardFormCompiler,
_LinearStandardFormCompiler_impl
_LinearStandardFormCompiler_impl,
)
from pyomo.util.var_list_domain import var_component_set

Expand All @@ -30,7 +27,7 @@
'parameterized_standard_form_compiler',
'Compile an LP to standard form (`min cTx s.t. Ax <= b`) treating some '
'variables as data (e.g., variables decided by the outer problem in a '
'bilevel optimization problem).'
'bilevel optimization problem).',
)
class ParameterizedLinearStandardFormCompiler(LinearStandardFormCompiler):
CONFIG = LinearStandardFormCompiler.CONFIG()
Expand Down Expand Up @@ -99,6 +96,7 @@ def _csc_matrix_from_csr(self, data, index, index_ptr, nrows, ncols):
def _csc_matrix(self, data, index, index_ptr, nrows, ncols):
return _CSCMatrix(data, index, index_ptr, nrows, ncols)


class _SparseMatrixBase(object):
def __init__(self, data, indices, indptr, nrows, ncols):
self.data = np.array(data)
Expand Down Expand Up @@ -149,13 +147,13 @@ def tocsc(self):
csc_data[dest] = csr_data[j]

col_index_ptr[col] += 1

# fix the column index pointer by inserting 0 at the beginning--the rest
# is right because we know each entry got incremented by 1 in the loop
# above.
col_index_ptr = np.insert(col_index_ptr, 0, 0)

return _CSCMatrix(csc_data, row_index, col_index_ptr, *self.shape)
return _CSCMatrix(csc_data, row_index, col_index_ptr, *self.shape)

def todense(self):
nrows = self.shape[0]
Expand Down Expand Up @@ -184,7 +182,7 @@ def todense(self):
for col in range(ncols):
for j in range(col_index_ptr[col], col_index_ptr[col + 1]):
dense[row_index[j], col] = data[j]

return dense


Expand Down
22 changes: 11 additions & 11 deletions pyomo/repn/plugins/standard_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,7 @@ def _get_data_list(self, linear_repn):
return np.fromiter(linear_repn.values(), float, len(linear_repn))

def _csc_matrix_from_csr(self, data, index, index_ptr, nrows, ncols):
return scipy.sparse.csr_array( (data, index, index_ptr), [nrows, ncols]
).tocsc()
return scipy.sparse.csr_array((data, index, index_ptr), [nrows, ncols]).tocsc()

def _csc_matrix(self, data, index, index_ptr, nrows, ncols):
return scipy.sparse.csc_array((data, index, index_ptr), [nrows, ncols])
Expand Down Expand Up @@ -491,13 +490,15 @@ def write(self, model):
if obj_data:
obj_data = np.concatenate(obj_data)
obj_index = np.concatenate(obj_index)
c = self._csc_matrix_from_csr(obj_data, obj_index, obj_index_ptr,
len(obj_index_ptr) - 1, len(columns))
c = self._csc_matrix_from_csr(
obj_data, obj_index, obj_index_ptr, len(obj_index_ptr) - 1, len(columns)
)
if rows:
con_data = np.concatenate(con_data)
con_index = np.concatenate(con_index)
A = self._csc_matrix_from_csr(con_data, con_index, con_index_ptr, len(rows),
len(columns))
A = self._csc_matrix_from_csr(
con_data, con_index, con_index_ptr, len(rows), len(columns)
)

# Some variables in the var_map may not actually appear in the
# objective or constraints (e.g., added from col_order, or
Expand All @@ -516,12 +517,11 @@ def write(self, model):
nCol = len(reduced_A_indptr) - 1
if nCol != len(columns):
columns = [v for k, v in zip(active_var_mask, columns) if k]
c = self._csc_matrix(c.data, c.indices, c.indptr[augmented_mask],
c.shape[0], nCol)
# active_var_idx[-1] = len(columns)
A = self._csc_matrix(
A.data, A.indices, reduced_A_indptr, A.shape[0], nCol
c = self._csc_matrix(
c.data, c.indices, c.indptr[augmented_mask], c.shape[0], nCol
)
# active_var_idx[-1] = len(columns)
A = self._csc_matrix(A.data, A.indices, reduced_A_indptr, A.shape[0], nCol)

if self.config.nonnegative_vars:
# ESJ TODO: Need to rewrite this for parameterized too
Expand Down
61 changes: 37 additions & 24 deletions pyomo/repn/tests/test_parameterized_standard_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@
from pyomo.common.dependencies import numpy as np, scipy_available, numpy_available
import pyomo.common.unittest as unittest

from pyomo.environ import (
ConcreteModel,
Constraint,
Var,
)
from pyomo.environ import ConcreteModel, Constraint, Var
from pyomo.core.expr import (
MonomialTermExpression,
NegationExpression,
ProductExpression
ProductExpression,
)
from pyomo.core.expr.compare import assertExpressionsEqual

Expand All @@ -31,9 +27,10 @@
_CSCMatrix,
)


@unittest.skipUnless(
numpy_available & scipy_available, "CSC and CSR representations require "
"scipy and numpy"
numpy_available & scipy_available,
"CSC and CSR representations require scipy and numpy",
)
class TestSparseMatrixRepresentations(unittest.TestCase):
def test_csr_to_csc_only_data(self):
Expand All @@ -49,16 +46,15 @@ def test_csr_to_csc_pyomo_exprs(self):
m.x = Var()
m.y = Var()

A = _CSRMatrix([5, 8 * m.x, 3 * m.x * m.y ** 2, 6], [0, 1, 2, 1],
[0, 1, 2, 3, 4], 4, 4)
A = _CSRMatrix(
[5, 8 * m.x, 3 * m.x * m.y**2, 6], [0, 1, 2, 1], [0, 1, 2, 3, 4], 4, 4
)
thing = A.tocsc()

self.assertEqual(thing.data[0], 5)
assertExpressionsEqual(
self, thing.data[1], 8 * m.x)
assertExpressionsEqual(self, thing.data[1], 8 * m.x)
self.assertEqual(thing.data[2], 6)
assertExpressionsEqual(
self, thing.data[3], 3 * m.x * m.y ** 2)
assertExpressionsEqual(self, thing.data[3], 3 * m.x * m.y**2)
self.assertEqual(thing.data.shape, (4,))

self.assertTrue(np.all(thing.indices == np.array([0, 1, 3, 2])))
Expand All @@ -72,7 +68,7 @@ def test_csr_to_csc_empty_matrix(self):
self.assertEqual(thing.indices.size, 0)
self.assertEqual(thing.shape, (0, 4))
self.assertTrue(np.all(thing.indptr == np.zeros(5)))


def assertExpressionArraysEqual(self, A, B):
self.assertEqual(A.shape, B.shape)
Expand All @@ -88,8 +84,8 @@ def assertExpressionListsEqual(self, A, B):


@unittest.skipUnless(
numpy_available & scipy_available, "Parameterized standard form requires "
"scipy and numpy"
numpy_available & scipy_available,
"Parameterized standard form requires scipy and numpy",
)
class TestParameterizedStandardFormCompiler(unittest.TestCase):
def test_linear_model(self):
Expand All @@ -116,14 +112,31 @@ def test_parameterized_linear_model(self):
m.c = Constraint(expr=m.x + 2 * m.data[1] * m.data[2] * m.y[1] >= 3)
m.d = Constraint(expr=m.y[1] + 4 * m.y[3] <= 5 * m.more_data)

repn = ParameterizedLinearStandardFormCompiler().write(m, wrt=[m.data,
m.more_data])
repn = ParameterizedLinearStandardFormCompiler().write(
m, wrt=[m.data, m.more_data]
)

self.assertTrue(np.all(repn.c == np.array([0, 0, 0])))
assertExpressionArraysEqual(self, repn.A.todense(),
np.array([[-1, NegationExpression((ProductExpression([MonomialTermExpression([2, m.data[1]]), m.data[2]]),)), 0],
[0, 1, 4]]))
assertExpressionListsEqual(self, repn.rhs,
[-3, 5 * m.more_data])
assertExpressionArraysEqual(
self,
repn.A.todense(),
np.array(
[
[
-1,
NegationExpression(
(
ProductExpression(
[MonomialTermExpression([2, m.data[1]]), m.data[2]]
),
)
),
0,
],
[0, 1, 4],
]
),
)
assertExpressionListsEqual(self, repn.rhs, [-3, 5 * m.more_data])
self.assertEqual(repn.rows, [(m.c, -1), (m.d, 1)])
self.assertEqual(repn.columns, [m.x, m.y[1], m.y[3]])

0 comments on commit 4c32954

Please sign in to comment.