Skip to content

Commit 4ff7cba

Browse files
committed
Modify s2mpjlib.py
1 parent feda8c7 commit 4ff7cba

3 files changed

Lines changed: 63 additions & 50 deletions

File tree

.github/workflows/sync_s2mpj.yml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
# 2. Clean managed files in current workspace for fresh sync
4040
# Only remove the specific files/folders we are syncing.
4141
mkdir -p src
42-
rm -rf src/python_problems src/list_of_python_problems src/s2mpjlib.py
42+
rm -rf src/python_problems src/list_of_python_problems
4343
4444
# 3. Copy only the specific files/folders we want from the temporary upstream directory
4545
echo "Copying selected files..."
@@ -58,13 +58,6 @@ jobs:
5858
echo "::warning::File 'list_of_python_problems' not found in upstream"
5959
fi
6060
61-
# Copy the 's2mpjlib.py' file
62-
if [ -f "temp_upstream/s2mpjlib.py" ]; then
63-
cp temp_upstream/s2mpjlib.py src/
64-
else
65-
echo "::warning::File 's2mpjlib.py' not found in upstream"
66-
fi
67-
6861
# 4. Remove the temporary upstream directory
6962
rm -rf temp_upstream
7063

s2mpj_tools.py

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ def s2mpj_load(problem_name, *args):
182182
beq = bx[idx_aeq] + cu[idx_aeq] if bx is not None and idx_aeq.size > 0 else None
183183
bub = np.concatenate([bx[idx_aub_le] + cu[idx_aub_le], -bx[idx_aub_ge] - cl[idx_aub_ge]]) if bx is not None and (idx_aub_le.size > 0 or idx_aub_ge.size > 0) else None
184184

185-
getidx = lambda y, idx: y[idx] if (y is not None and idx.size > 0) else None
186185
# Construct nonlinear constraint functions
187186
# Remind that in S2MPJ, the constraints are defined as:
188187
# cl <= c(x) <= cu
@@ -192,32 +191,49 @@ def s2mpj_load(problem_name, *args):
192191
# cub(x) = [c(x)[idx_cle] - cu[idx_cle];
193192
# -c(x)[idx_cge] + cl[idx_cge]] <= 0
194193
def ceq(x):
194+
if idx_ceq.size == 0: return None
195195
y = _getcx(p, x)
196-
if idx_ceq.size > 0:
197-
z = getidx(y, idx_ceq) - cu[idx_ceq]
198-
else:
199-
z = None
200-
return None if z is None or (hasattr(z, "size") and z.size == 0) else z
196+
if y is None: return None
197+
z = y[idx_ceq] - cu[idx_ceq]
198+
return None if (hasattr(z, "size") and z.size == 0) else z
201199
def cub(x):
200+
if idx_cle.size == 0 and idx_cge.size == 0: return None
202201
y = _getcx(p, x)
203-
le = getidx(y, idx_cle) - cu[idx_cle] if idx_cle.size > 0 else None
204-
ge = getidx(y, idx_cge) - cl[idx_cge] if idx_cge.size > 0 else None
205-
if le is None and ge is None:
206-
return None
207-
if ge is None:
208-
return le
209-
if le is None:
210-
return -ge
202+
if y is None: return None
203+
le = y[idx_cle] - cu[idx_cle] if idx_cle.size > 0 else None
204+
ge = y[idx_cge] - cl[idx_cge] if idx_cge.size > 0 else None
205+
if le is None and ge is None: return None
206+
if ge is None: return le
207+
if le is None: return -ge
211208
return np.concatenate([le, -ge])
212-
213-
getidx_list = lambda y, idx: [y[i] for i in idx] if y is not None else []
214-
hceq = lambda x: getidx_list(_getHx(p, x), idx_ceq)
215-
hcub = lambda x: getidx_list(_getHx(p, x), idx_cle) + getidx_list(_getHx(p, x), idx_cge)
216-
217-
getidx_mat = lambda y, idx: y[idx, :] if y is not None else None
218-
jceq = lambda x: getidx_mat(_getJx(p, x), idx_ceq)
219-
jcub = lambda x: np.vstack([getidx_mat(_getJx(p, x), idx_cle),
220-
-getidx_mat(_getJx(p, x), idx_cge)]) if getidx_mat(_getJx(p, x), idx_cle) is not None else None
209+
def hceq(x):
210+
if idx_ceq.size == 0: return []
211+
Hx = _getHx(p, x)
212+
if Hx is None: raise RuntimeError("Hessian evaluation failed")
213+
return [Hx[i] for i in idx_ceq]
214+
def hcub(x):
215+
if idx_cle.size == 0 and idx_cge.size == 0: return []
216+
Hx = _getHx(p, x)
217+
if Hx is None: raise RuntimeError("Hessian evaluation failed")
218+
le = [Hx[i] for i in idx_cle] if idx_cle.size > 0 else []
219+
ge = [Hx[i] for i in idx_cge] if idx_cge.size > 0 else []
220+
return le + ge
221+
222+
def jceq(x):
223+
if idx_ceq.size == 0: return np.empty((0, p.n))
224+
Jx = _getJx(p, x)
225+
if Jx is None: return None
226+
return Jx[idx_ceq, :]
227+
def jcub(x):
228+
if idx_cle.size == 0 and idx_cge.size == 0: return np.empty((0, p.n))
229+
Jx = _getJx(p, x)
230+
if Jx is None: return None
231+
le = Jx[idx_cle, :] if idx_cle.size > 0 else None
232+
ge = Jx[idx_cge, :] if idx_cge.size > 0 else None
233+
if le is None and ge is None: return np.empty((0, p.n))
234+
if ge is None: return le
235+
if le is None: return -ge
236+
return np.vstack([le, -ge])
221237

222238
# Construct the Problem instance.
223239
problem = Problem(fun, x0, name=name, xl=xl, xu=xu, aub=aub, bub=bub, aeq=aeq, beq=beq, cub=cub, ceq=ceq, grad=grad, hess=hess, jcub=jcub, jceq=jceq, hcub=hcub, hceq=hceq)
@@ -497,7 +513,8 @@ def _gethess(p, is_feasibility, x):
497513
try:
498514
_, _, h = p.fgHx(x)
499515
h = h.toarray() if hasattr(h, 'toarray') else h
500-
except Exception:
516+
except Exception as e:
517+
print(f"Error eval Hx: {e}")
501518
h = None
502519
return h
503520

@@ -507,7 +524,8 @@ def _getcx(p, x):
507524
try:
508525
c = p.cx(x)
509526
c = c.toarray() if hasattr(c, 'toarray') else c
510-
except Exception:
527+
except Exception as e:
528+
print(f"Error eval cx: {e}")
511529
c = None
512530
return c
513531

@@ -517,7 +535,8 @@ def _getJx(p, x):
517535
try:
518536
_, j = p.cJx(x)[:2]
519537
j = j.toarray() if hasattr(j, 'toarray') else j
520-
except Exception:
538+
except Exception as e:
539+
print(f"Error eval Jx: {e}")
521540
j = None
522541
return j
523542

@@ -529,6 +548,7 @@ def _getHx(p, x):
529548
for i in range(len(h)):
530549
if hasattr(h[i], 'toarray'):
531550
h[i] = h[i].toarray()
532-
except Exception:
551+
except Exception as e:
552+
print(f"Error eval Hx: {e}")
533553
h = None
534554
return h

src/s2mpjlib.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,13 @@ def evalgrsum( self, isobj, glist, x, nargout ):
427427
# Evaluate the linear term, if any.
428428

429429
if hasattr(self,"gconst") and ig < len(self.gconst) and not self.gconst[ig] is None:
430-
fin = float(-self.gconst[ig])
430+
fin = float(np.array(-self.gconst[ig]).item())
431431
else:
432432
fin = 0
433433
if has_A and ig < sA1:
434434
gin = np.zeros( (n, 1) )
435435
gin[:sA2, :1] = self.A[ ig, :sA2 ].T.toarray()
436-
fin = float( fin + gin.T .dot(x) )
436+
fin = float(np.array( fin + gin.T .dot(x) ).item())
437437
elif nargout >= 2:
438438
gin = np.zeros(( n, 1 ))
439439

@@ -448,7 +448,7 @@ def evalgrsum( self, isobj, glist, x, nargout ):
448448
iel = self.grelt[ ig ][ iiel ] # the element's index
449449
efname = self.elftype[ iel ] # the element's ftype
450450
irange = [iv for iv in self.elvar[ iel ]] # the elemental variable's indeces
451-
xiel = x[ np.array(irange) ] # the elemental variable's values
451+
xiel = x[ np.array(irange) ].flatten().flatten() # the elemental variable's values
452452

453453
if hasattr( self, 'grelw' ) and ig <= len( self.grelw ) and not self.grelw[ig] is None :
454454
has_weights = True;
@@ -621,11 +621,11 @@ def evalgrsum( self, isobj, glist, x, nargout ):
621621
print( "ig = ", ig, " cx(final) = ", cx )#D
622622
if isobj:
623623
if nargout == 1:
624-
return float( fx )
624+
return float(np.array(fx).item())
625625
elif nargout == 2:
626-
return float( fx ), gx.reshape(-1,1)
626+
return float(np.array(fx).item()), gx.reshape(-1,1)
627627
elif nargout == 3:
628-
return float( fx ), gx.reshape(-1,1), Hx
628+
return float(np.array(fx).item()), gx.reshape(-1,1), Hx
629629
else:
630630
if nargout == 1:
631631
return cx
@@ -711,7 +711,7 @@ def evalHJv( self, mode, glist, x, v, y ):
711711
# Evaluate the quadratic term, if any.
712712

713713
if mode == "Hv" and hasattr( self, "H" ):
714-
HJv += self.H.dot(v);
714+
HJv += self.H.dot(v).item();
715715

716716
if debug: #D
717717
print( "HJv(quadratic) = ", HJv )
@@ -750,13 +750,13 @@ def evalHJv( self, mode, glist, x, v, y ):
750750
# Evaluate the linear term, if any.
751751

752752
if hasattr( self, "gconst" ) and ig < len( self.gconst ) and not self.gconst[ ig ] is None:
753-
fin = float(-self.gconst[ ig ] )
753+
fin = float(np.array(-self.gconst[ ig ] ).item())
754754
else:
755755
fin = 0.0
756756
gin = np.zeros((n,1))
757757
if has_A and ig < sA1:
758758
gin[:sA2, :1] = self.A[ ig, :sA2 ].T.toarray()
759-
fin = float(fin + gin.T .dot(x))
759+
fin = float(np.array(fin + gin.T .dot(x)).item())
760760

761761
if debug:
762762
print( "ig = ", ig, " fin(linear)", fin ) #D
@@ -768,7 +768,7 @@ def evalHJv( self, mode, glist, x, v, y ):
768768
iel = self.grelt[ ig ][ iiel ] # the element's index
769769
efname = self.elftype[ iel ]; # the element's ftype
770770
irange = [iv for iv in self.elvar[ iel ]] # the elemental variable's indeces
771-
xiel = x[ np.array(irange) ] # the elemental variable's values
771+
xiel = x[ np.array(irange) ].flatten().flatten() # the elemental variable's values
772772

773773
if hasattr( self, 'grelw' ) and ig <= len( self.grelw ) and not self.grelw[ig] is None :
774774
has_weights = 1;
@@ -831,7 +831,7 @@ def evalHJv( self, mode, glist, x, v, y ):
831831
else:
832832
fa, grada, Hessa = eval('self.'+egname+'( self, 3, fin, ig )' )
833833
sgin = lil_matrix(gin);
834-
HJv += ( ( Hessa * sgin) * (sgin.transpose().dot(v)) + grada * Hinv) / gsc
834+
HJv += ( ( Hessa * sgin) * (sgin.transpose().dot(v).item()) + grada * Hinv) / gsc
835835
elif mode == "HIv":
836836
if egname == "TRIVIAL":
837837
ic += 1
@@ -840,7 +840,7 @@ def evalHJv( self, mode, glist, x, v, y ):
840840
fa, grada, Hessa = eval('self.'+egname+'( self, 3, fin, ig )' )
841841
sgin = lil_matrix(gin);
842842
ic += 1
843-
HJv += y[ic] * ( ( Hessa * sgin) * (sgin.transpose().dot(v)) + grada * Hinv) / gsc
843+
HJv += y[ic] * ( ( Hessa * sgin) * (sgin.transpose().dot(v).item()) + grada * Hinv) / gsc
844844
elif mode == "Jv":
845845
ic += 1
846846
if derlvl >= 1:
@@ -883,7 +883,7 @@ def evalLx( self, gobjlist, gconlist, x, y, nargout ):
883883
if len( gconlist ):
884884
c = self.evalgrsum( False, gconlist, x, 1 )
885885
Lxy = Lxy + y.T.dot(c)
886-
return float(Lxy)
886+
return float(np.array(Lxy).item())
887887
elif nargout == 2:
888888
if len( gobjlist ) or hasattr( self, "H" ):
889889
Lxy, Lgxy = self.evalgrsum( True, gobjlist, x, 2 )
@@ -894,7 +894,7 @@ def evalLx( self, gobjlist, gconlist, x, y, nargout ):
894894
c, J = self.evalgrsum( False, gconlist, x, 2 )
895895
Lxy = Lxy + y.T.dot(c)
896896
Lgxy = Lgxy + J.T.dot(y)
897-
return float(Lxy), Lgxy
897+
return float(np.array(Lxy).item()), Lgxy
898898
elif nargout == 3:
899899
if len( gobjlist ) or hasattr( self, "H" ):
900900
Lxy, Lgxy, LgHxy = self.evalgrsum( True, gobjlist, x, 3 )
@@ -909,7 +909,7 @@ def evalLx( self, gobjlist, gconlist, x, y, nargout ):
909909
Lgxy = Lgxy + J.T.dot(y)
910910
for ig in range( len( gconlist ) ):
911911
LgHxy = LgHxy + y[ig,0] * cHi[ig]
912-
return float(Lxy), Lgxy.reshape(-1,1), LgHxy
912+
return float(np.array(Lxy).item()), Lgxy.reshape(-1,1), LgHxy
913913

914914
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
915915
#

0 commit comments

Comments
 (0)