Skip to content

Commit 61ac876

Browse files
authored
Merge pull request #3655 from eslickj/pynum_sens
Add independent variable rows to sensitivity toolbox Pynumero-based sensitivity calcs
2 parents 367c2ff + d771a60 commit 61ac876

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

pyomo/contrib/sensitivity_toolbox/pynumero.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def get_dsdp_dfdp(model, theta):
6262
Returns
6363
-------
6464
scipy.sparse.csc_matrix, csc_matrix, ComponentMap, ComponentMap
65-
ds/dp (ns by np), df/dp (1 by np), row map, column map.
65+
ds/dp (ns + np by np), df/dp (1 by np), row map, column map.
6666
The column map maps Pyomo variables p to columns and the
6767
row map maps Pyomo variables s to rows.
6868
"""
@@ -98,6 +98,15 @@ def get_dsdp_dfdp(model, theta):
9898
_coo_reorder_cols(dfdx, remap=col_remap)
9999
dfdx = dfdx.tocsc()
100100
dfdp = dfdx[0, :ns] @ dsdp + dfdx[0, ns:]
101+
102+
# Add independent variables to the rows as the end
103+
dsdp = scipy.sparse.vstack(
104+
[dsdp, scipy.sparse.identity(len(column_map), format="csc")]
105+
)
106+
n = len(row_map)
107+
for p, i in column_map.items():
108+
row_map[p] = i + n
109+
101110
# return sensitivity of the outputs to p and component maps
102111
return dsdp, dfdp, row_map, column_map
103112

pyomo/contrib/sensitivity_toolbox/tests/test_pynumero.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,15 @@ def test_dsdp_dfdp_pyomo_nlp(self):
7373
dsdp, dfdp, rmap, cmap = pnsens.get_dsdp_dfdp(m2, theta)
7474

7575
# Since x1 = p1
76-
assert dsdp.shape == (2, 2)
76+
assert dsdp.shape == (4, 2)
7777
np.testing.assert_almost_equal(dsdp[rmap[m.x1], cmap[m.p1]], 40.0)
7878
np.testing.assert_almost_equal(dsdp[rmap[m.x1], cmap[m.p2]], 0.0)
7979
np.testing.assert_almost_equal(dsdp[rmap[m.x2], cmap[m.p1]], 0.0)
8080
np.testing.assert_almost_equal(dsdp[rmap[m.x2], cmap[m.p2]], 1.0)
81+
np.testing.assert_almost_equal(dsdp[rmap[m.p1], cmap[m.p2]], 0.0)
82+
np.testing.assert_almost_equal(dsdp[rmap[m.p2], cmap[m.p2]], 1.0)
83+
np.testing.assert_almost_equal(dsdp[rmap[m.p1], cmap[m.p1]], 1.0)
84+
np.testing.assert_almost_equal(dsdp[rmap[m.p2], cmap[m.p1]], 0.0)
8185

8286
# if x1 = 2 * p1 and x2 = p2 then
8387
# df/dp1 = 6 p1**2 + p2 = 45.0

0 commit comments

Comments
 (0)