1616
1717import numpy as np
1818import scipy .sparse as sp
19- import torch
2019
2120import cvxpy .settings as s
2221from cvxpy .constraints import (
3231 nonpos2nonneg ,
3332)
3433from cvxpy .utilities .citations import CITATION_DICT
35- from cvxtorch import TorchExpression
3634
3735
3836class IPOPT (NLPsolver ):
@@ -146,7 +144,7 @@ def solve_via_data(self, data, warm_start: bool, verbose: bool, solver_opts, sol
146144 nlp = cyipopt .Problem (
147145 n = len (x0 ),
148146 m = len (bounds .cl ),
149- problem_obj = self .Oracles (bounds .new_problem ),
147+ problem_obj = self .Oracles (bounds .new_problem , x0 ),
150148 lb = bounds .lb ,
151149 ub = bounds .ub ,
152150 cl = bounds .cl ,
@@ -169,9 +167,10 @@ def cite(self, data):
169167 return CITATION_DICT ["IPOPT" ]
170168
171169 class Oracles ():
172- def __init__ (self , problem ):
170+ def __init__ (self , problem , inital_point ):
173171 self .problem = problem
174172 self .main_var = []
173+ self .initial_point = inital_point
175174 for var in self .problem .variables ():
176175 self .main_var .append (var )
177176
@@ -201,7 +200,10 @@ def gradient(self, x):
201200 for var in self .main_var :
202201 size = var .size
203202 if var in grad_dict :
204- grad [grad_offset :grad_offset + size ] = grad_dict [var ]
203+ array = grad_dict [var ]
204+ if sp .issparse (array ):
205+ array = array .toarray ().flatten (order = 'F' )
206+ grad [grad_offset :grad_offset + size ] = array
205207 grad_offset += size
206208 return grad
207209
@@ -231,23 +233,24 @@ def jacobian(self, x):
231233
232234 values = []
233235 for constraint in self .problem .constraints :
236+ # get the jacobian of the constraint
234237 grad_dict = constraint .expr .grad
235238 for var in self .main_var :
236239 if var in grad_dict :
237- array = grad_dict [var ]
238- if sp .issparse (array ):
239- array = array .toarray ().flatten (order = 'F' )
240- values .append (np .atleast_1d (array ))
240+ jacobian = grad_dict [var ]. T
241+ if sp .issparse (jacobian ):
242+ jacobian = jacobian .toarray ().flatten (order = 'F' )
243+ values .append (np .atleast_1d (jacobian ))
241244 else :
242- values .append (np .atleast_1d (array ))
245+ values .append (np .atleast_1d (jacobian ))
243246 return np .concatenate (values )
244247
245248 def jacobianstructure (self ):
246249 """Returns the sparsity structure of the Jacobian."""
247250 # Set dummy values to get gradient structure
248251 offset = 0
249252 for var in self .main_var :
250- var .value = np . zeros ( var .shape )
253+ var .value = self . initial_point [ offset : offset + var .size ]
251254 offset += var .size
252255 rows , cols = [], []
253256 row_offset = 0
@@ -256,12 +259,16 @@ def jacobianstructure(self):
256259 col_offset = 0
257260 for var in self .main_var :
258261 if var in grad_dict :
259- array = grad_dict [var ]
260- if sp .issparse (array ):
261- array = array .toarray ()
262- # get row and column indices
263- rows .extend (np .ones (array .size )* row_offset )
264- cols .extend (np .arange (col_offset , col_offset + var .size ))
262+ jacobian = grad_dict [var ].T
263+ if sp .issparse (jacobian ):
264+ row_indices , col_indices = np .indices (jacobian .shape )
265+ rows .extend (row_indices .flatten (order = 'F' ) + row_offset )
266+ cols .extend (col_indices .flatten (order = 'F' ) + col_offset )
267+ """
268+ else:
269+ rows.extend(np.ones(jacobian.size)*row_offset)
270+ cols.extend(np.arange(col_offset, col_offset + var.size))
271+ """
265272 col_offset += var .size
266273 row_offset += constraint .size
267274
0 commit comments