@@ -210,6 +210,17 @@ def solveLP_sparse(objective: coo_array = blank_coo_array,
210210 # Since the value of infinity is ignored, define it for symbolic purposes
211211 inf = 0.0
212212
213+ nof_primal_variables = inequalities .shape [1 ]
214+ if default_non_negative and solve_dual :
215+ merely_lbbounded = np .setdiff1d (np .arange (nof_primal_variables ), known_vars .col )
216+ lower_bounds = coo_array ((lower_bounds .toarray ().ravel ()[merely_lbbounded ], (
217+ [0 ] * len (merely_lbbounded ),
218+ merely_lbbounded
219+ )), shape = (1 , nof_primal_variables ))
220+
221+
222+
223+
213224 if relax_known_vars or relax_inequalities :
214225 default_non_negative = False
215226
@@ -297,36 +308,18 @@ def solveLP_sparse(objective: coo_array = blank_coo_array,
297308 if objective .shape [- 1 ] == 0 :
298309 objective = coo_array ((1 , nof_primal_variables ), dtype = np .int8 )
299310
300- nof_lb = lower_bounds .nnz
301- nof_ub = upper_bounds .nnz
302-
303311 if verbose > 0 :
304312 print (f"Size of constraint matrix: { constraints .shape } " )
305313
306314 if solve_dual :
307315 if verbose > 1 :
308316 print ("Proceeding with dual initialization..." )
309317
310- nof_primal_nontriv_bounds = nof_lb + nof_ub
311318 nof_dual_constraints = nof_primal_variables
312- nof_dual_variables = nof_primal_constraints + \
313- nof_primal_nontriv_bounds
314-
315- # Add variable bounds as inequality constraints to matrix
316- if nof_primal_nontriv_bounds > 0 :
317- lb_mat = expand_sparse_vec (lower_bounds ,
318- conversion_style = "eq" )
319- ub_mat = expand_sparse_vec (upper_bounds ,
320- conversion_style = "eq" )
321- ub_mat .data [:] = - ub_mat .data # just a list of ones
322- matrix = vstack ((constraints , lb_mat , ub_mat ),
323- format = 'csr' )
324- b_extra = np .concatenate (
325- (lower_bounds .data , - np .asarray (upper_bounds .data )))
326- objective_vector = np .concatenate ((b , b_extra ))
327- else :
328- matrix = constraints .tocsr (copy = False )
329- objective_vector = b
319+ nof_dual_variables = nof_primal_constraints
320+
321+ matrix = constraints .tocsr (copy = False )
322+ objective_vector = b
330323
331324 if verbose > 1 :
332325 print ("Sparse matrix reformat complete..." )
@@ -338,11 +331,14 @@ def solveLP_sparse(objective: coo_array = blank_coo_array,
338331 else :
339332 blc = buc = objective .toarray ().ravel ()
340333
341- # Set constraint bounds corresponding to primal variable bounds
342- if default_non_negative :
343- bkc = np .broadcast_to (mosek .boundkey .lo , nof_dual_constraints )
344- else :
345- bkc = np .broadcast_to (mosek .boundkey .fx , nof_dual_constraints )
334+ bkc = np .array (np .broadcast_to (mosek .boundkey .fx , nof_dual_constraints ), copy = True )
335+ # Variable bounds are reflected in the dual on the objective!
336+ bkc [lower_bounds .col ] = mosek .boundkey .up
337+ buc [lower_bounds .col ] = lower_bounds .data
338+ bkc [upper_bounds .col ] = mosek .boundkey .lo
339+ blc [upper_bounds .col ] = upper_bounds .data
340+ bkc [np .intersect1d (upper_bounds .col , upper_bounds .col )] = mosek .boundkey .ra
341+
346342
347343 # Set bound keys and values for variables
348344 # Non-positivity for y corresponding to inequalities
0 commit comments