Skip to content

Commit 5870139

Browse files
authored
Fix matmul gradient issue (#14)
* fix matmul grad * fix matmul and add sparsity in blocks --------- Co-authored-by: William Zijie Zhang <[email protected]>
1 parent d58baf8 commit 5870139

File tree

4 files changed

+29
-15
lines changed

4 files changed

+29
-15
lines changed

cvxpy/atoms/affine/binary_operators.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ def _grad(self, values):
174174
"""Compute the gradient of matrix multiplication w.r.t. each argument.
175175
176176
For Z = X @ Y, this computes the Jacobian matrices:
177-
- ∂vec(Z)/∂vec(X) = Y.T ⊗ I_m where X is (m, n)
178-
- ∂vec(Z)/∂vec(Y) = I_p ⊗ X where Y is (n, p)
177+
- ∂vec(Z)/∂vec(X) = (Y.T ⊗ I_m).T where X is (m, n)
178+
- ∂vec(Z)/∂vec(Y) = (I_p ⊗ X).T where Y is (n, p)
179179
180180
Args:
181181
values: A list of numeric values for the arguments [X, Y].
@@ -197,13 +197,13 @@ def _grad(self, values):
197197
# Verify dimension compatibility
198198
assert n == n2, f"Inner dimensions must match for multiplication: {n} != {n2}"
199199

200-
# Compute ∂vec(Z)/∂vec(X) = Y.T ⊗ I_m
201-
# This is a (m*p) × (m*n) matrix
202-
DX = sp.kron(Y.T, sp.eye(m, format='csc'), format='csc')
200+
# Compute ∂vec(Z)/∂vec(X) = (Y.T ⊗ I_m).T
201+
# This is a (m*n) × (m*p) matrix
202+
DX = sp.kron(Y.T, sp.eye(m, format='csc'), format='csc').T
203203

204-
# Compute ∂vec(Z)/∂vec(Y) = I_p ⊗ X
205-
# This is a (m*p) × (n*p) matrix
206-
DY = sp.kron(sp.eye(p, format='csc'), X, format='csc')
204+
# Compute ∂vec(Z)/∂vec(Y) = (I_p ⊗ X).T
205+
# This is a (n*p) × (m*p) matrix
206+
DY = sp.kron(sp.eye(p, format='csc'), X, format='csc').T
207207

208208
return [DX, DY]
209209

cvxpy/reductions/solvers/nlp_solvers/ipopt_nlpif.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,9 @@ def jacobian(self, x):
239239
if var in grad_dict:
240240
jacobian = grad_dict[var].T
241241
if sp.issparse(jacobian):
242-
jacobian = jacobian.toarray().flatten(order='F')
242+
jacobian = jacobian.tocoo()
243+
jacobian = jacobian.data
244+
#jacobian = jacobian.toarray().flatten(order='F')
243245
values.append(np.atleast_1d(jacobian))
244246
else:
245247
values.append(np.atleast_1d(jacobian))
@@ -264,9 +266,9 @@ def jacobianstructure(self):
264266
if var in grad_dict:
265267
jacobian = grad_dict[var].T
266268
if sp.issparse(jacobian):
267-
row_indices, col_indices = np.indices(jacobian.shape)
268-
rows.extend(row_indices.flatten(order='F') + row_offset)
269-
cols.extend(col_indices.flatten(order='F') + col_offset)
269+
jacobian = jacobian.tocoo()
270+
rows.extend(jacobian.row + row_offset)
271+
cols.extend(jacobian.col + col_offset)
270272
else:
271273
rows.extend(np.ones(jacobian.size)*row_offset)
272274
cols.extend(np.arange(col_offset, col_offset + var.size))

cvxpy/sandbox/control_of_car.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import cvxpy as cp
55

66

7-
def solve_car_control(x_final, L=0.1, N=50, h=0.1, gamma=10):
7+
def solve_car_control(x_final, L=0.1, N=5, h=0.1, gamma=10):
88
"""
99
Solve the nonlinear optimal control problem for car trajectory planning.
1010

cvxpy/tests/test_nlp_solvers.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,23 @@ def test_acopf(self):
194194
theta >= theta_lb,
195195
theta <= theta_ub
196196
]
197-
P_balance = cp.multiply(v, (G * cp.cos(theta_col - theta_col.T) + B * cp.sin(theta_col - theta_col.T)) @ v)
197+
P_balance = cp.multiply(
198+
v,
199+
(
200+
G * cp.cos(theta_col - theta_col.T)
201+
+ B * cp.sin(theta_col - theta_col.T)
202+
) @ v
203+
)
198204
constraints.append(P == P_balance)
199205

200206
# Reactive power balance
201-
Q_balance = cp.multiply(v, (G * cp.sin(theta_col - theta_col.T) - B * cp.cos(theta_col - theta_col.T)) @ v)
207+
Q_balance = cp.multiply(
208+
v,
209+
(
210+
G * cp.sin(theta_col - theta_col.T)
211+
- B * cp.cos(theta_col - theta_col.T)
212+
) @ v
213+
)
202214
constraints.append(Q == Q_balance)
203215

204216
# Objective: minimize reactive power at buses 1 and 3 (indices 0 and 2)

0 commit comments

Comments
 (0)