Skip to content

Commit abf026e

Browse files
committed
Addressed review comments and updated the code as per the feedback
1 parent 9f91959 commit abf026e

File tree

3 files changed

+28
-31
lines changed

3 files changed

+28
-31
lines changed

highs/highs_bindings.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ std::function<dense_array_t<T>(const Base&)> make_readonly_ptr(
2828
};
2929
}
3030

31+
template<typename Base, typename T>
32+
std::function<void(Base&, dense_array_t<T>)> make_vector_setter(
33+
std::vector<T> Base::* member){
34+
return [member](Base& self,dense_array_t<T>values){
35+
auto buf = values.request();
36+
auto ptr = static_cast<T*>(buf.ptr);
37+
(self.*member).assign(ptr, ptr + buf.size);
38+
};
39+
}
40+
3141
HighsStatus highs_passModel(Highs* h, HighsModel& model) {
3242
return h->passModel(model);
3343
}
@@ -1059,7 +1069,8 @@ PYBIND11_MODULE(_core, m, py::mod_gil_not_used()) {
10591069
.def(py::init<>())
10601070
.def_readwrite("num_col_", &HighsLp::num_col_)
10611071
.def_readwrite("num_row_", &HighsLp::num_row_)
1062-
.def_readwrite("col_cost_", &HighsLp::col_cost_)
1072+
.def_property("col_cost_", make_readonly_ptr(&HighsLp::col_cost_),
1073+
make_vector_setter(&HighsLp::col_cost_))
10631074
.def_readwrite("col_lower_", &HighsLp::col_lower_)
10641075
.def_readwrite("col_upper_", &HighsLp::col_upper_)
10651076
.def_readwrite("row_lower_", &HighsLp::row_lower_)

highs/highspy/_core/__init__.pyi

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class HighsLogType:
262262

263263
class HighsLp:
264264
a_matrix_: HighsSparseMatrix
265-
col_cost_: list[float]
265+
col_cost_: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
266266
col_lower_: list[float]
267267
col_names_: list[str]
268268
col_upper_: list[float]
@@ -525,11 +525,11 @@ class HighsScale:
525525
pass
526526

527527
class HighsSolution:
528-
col_dual: list[float]
529-
col_value: list[float]
528+
col_dual: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
529+
col_value: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
530530
dual_valid: bool
531-
row_dual: list[float]
532-
row_value: list[float]
531+
row_dual: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
532+
row_value: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
533533
value_valid: bool
534534

535535
def __init__(self) -> None: ...

highs/highspy/highs.py

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ class Highs(_Highs):
3636
__solver_started: Lock = Lock()
3737
__solver_status: Optional[HighsStatus] = None
3838

39-
@staticmethod
40-
def float_array(vals):
41-
if isinstance(vals,np.ndarray): return vals
42-
return np.asarray(vals,dtype=np.float64)
43-
4439
def __init__(self):
4540
super().__init__()
4641
self.callbacks = [HighsCallback(cb.HighsCallbackType(_), self) for _ in range(int(cb.HighsCallbackType.kCallbackMax) + 1)]
@@ -184,15 +179,6 @@ def optimize(self):
184179
"""
185180
return self.solve()
186181

187-
def getSolution(self):
188-
#retriving the current solution to numpy vector fields
189-
solution = super().getSolution()
190-
solution.col_value = Highs.float_array(solution.col_value)
191-
solution.col_dual = Highs.float_array(solution.col_dual)
192-
solution.row_value = Highs.float_array(solution.row_value)
193-
solution.row_dual = Highs.float_array(solution.row_dual)
194-
return solution
195-
196182
# reset the objective
197183
def setObjective(self, obj: Optional[Union[highs_var, highs_linear_expression]] = None, sense: Optional[ObjSense] = None):
198184
"""
@@ -308,7 +294,7 @@ def val(
308294
Returns:
309295
The value of the variable in the solution.
310296
"""
311-
return Highs.internal_get_value(self.getSolution().col_value, var)
297+
return Highs.internal_get_value(super().getSolution().col_value, var)
312298

313299
@overload
314300
def vals(self, idxs: Union[Integral, highs_var, highs_cons]) -> float: ...
@@ -335,7 +321,7 @@ def vals(
335321
Returns:
336322
If idxs is a Mapping, returns a dict where keys are the same keys from the input idxs and values are the solution values of the corresponding variables. If idxs is an iterable, returns a list of solution values for the variables.
337323
"""
338-
return Highs.internal_get_value(self.getSolution().col_value, idxs)
324+
return Highs.internal_get_value(super().getSolution().col_value, idxs)
339325

340326
def variableName(self, var: Union[Integral, highs_var]):
341327
"""
@@ -428,7 +414,7 @@ def allVariableValues(self):
428414
Returns:
429415
A list of values for all variables in the solution.
430416
"""
431-
return self.getSolution().col_value
417+
return super().getSolution().col_value
432418

433419
def variableDual(
434420
self,
@@ -443,7 +429,7 @@ def variableDual(
443429
Returns:
444430
The dual value of the specified variable in the solution.
445431
"""
446-
return Highs.internal_get_value(self.getSolution().col_dual, var)
432+
return Highs.internal_get_value(super().getSolution().col_dual, var)
447433

448434
def variableDuals(
449435
self,
@@ -458,7 +444,7 @@ def variableDuals(
458444
Returns:
459445
If idxs is a Mapping, returns a dict where keys are the same keys from the input idxs and values are the dual values of the corresponding variables. If idxs is an iterable, returns a list of dual values for the variables.
460446
"""
461-
return Highs.internal_get_value(self.getSolution().col_dual, idxs)
447+
return Highs.internal_get_value(super().getSolution().col_dual, idxs)
462448

463449
def allVariableDuals(self):
464450
"""
@@ -467,7 +453,7 @@ def allVariableDuals(self):
467453
Returns:
468454
A list of dual values for all variables in the solution.
469455
"""
470-
return self.getSolution().col_dual
456+
return super().getSolution().col_dual
471457

472458
def constrValue(
473459
self,
@@ -482,7 +468,7 @@ def constrValue(
482468
Returns:
483469
The value of the specified constraint in the solution.
484470
"""
485-
return Highs.internal_get_value(self.getSolution().row_value, con)
471+
return Highs.internal_get_value(super().getSolution().row_value, con)
486472

487473
def constrValues(
488474
self,
@@ -497,7 +483,7 @@ def constrValues(
497483
Returns:
498484
If cons is a Mapping, returns a dict where keys are the same keys from the input cons and values are the solution values of the corresponding constraints. If cons is an iterable, returns a list of solution values for the constraints.
499485
"""
500-
return Highs.internal_get_value(self.getSolution().row_value, cons)
486+
return Highs.internal_get_value(super().getSolution().row_value, cons)
501487

502488
def allConstrValues(self):
503489
"""
@@ -521,7 +507,7 @@ def constrDual(
521507
Returns:
522508
The dual value of the specified constraint in the solution.
523509
"""
524-
return Highs.internal_get_value(self.getSolution().row_dual, con)
510+
return Highs.internal_get_value(super().getSolution().row_dual, con)
525511

526512
def constrDuals(
527513
self,
@@ -536,7 +522,7 @@ def constrDuals(
536522
Returns:
537523
If cons is a Mapping, returns a dict where keys are the same keys from the input cons and values are the dual values of the corresponding constraints. If cons is an iterable, returns a list of dual values for the constraints.
538524
"""
539-
return Highs.internal_get_value(self.getSolution().row_dual, cons)
525+
return Highs.internal_get_value(super().getSolution().row_dual, cons)
540526

541527
def allConstrDuals(self):
542528
"""
@@ -545,7 +531,7 @@ def allConstrDuals(self):
545531
Returns:
546532
A list of dual values for all constraints in the solution.
547533
"""
548-
return self.getSolution().row_dual
534+
return super().getSolution().row_dual
549535

550536
def addVariable(
551537
self,

0 commit comments

Comments
 (0)