Foggalong / RobustOCS

Robust optimal contirbution selection problems for genetics with Python
https://pypi.org/project/robustocs
MIT License
1 stars 0 forks source link

Cleaner integraiton of $z$ for HiGHS #11

Closed Foggalong closed 2 months ago

Foggalong commented 2 months ago

As became apparent toward the end of #10, the way I've integrated $z$ into the model at the point of construction like

model.lp_.num_col_ = dimension + 1  # additional column for z
model.lp_.num_row_ = 2

model.lp_.col_cost_ = np.append(-mubar, kappa)

model.lp_.col_lower_ = np.append(highs_bound_like(mubar, lower_bound), 0)
model.lp_.col_upper_ = np.append(highs_bound_like(mubar, upper_bound), inf)

model.hessian_.dim_ = dimension + 1
model.hessian_.start_ = np.append(sigma.indptr, len(sigma.data))
model.hessian_.index_ = np.append(sigma.indices, dimension)
model.hessian_.value_ = np.append(lam*sigma.data, 0)

model.lp_.row_lower_ = model.lp_.row_upper_ = np.array([0.5, 0.5, 0])
model.lp_.a_matrix_.format_ = highspy.MatrixFormat.kRowwise
model.lp_.a_matrix_.start_ = np.array([0, len(sires), dimension + 1])
model.lp_.a_matrix_.index_ = np.array(list(sires) + list(dams) + [dimension])
model.lp_.a_matrix_.value_ = np.append(np.ones(dimension, dtype=int), 0)

leads to code which is prone to bugs. It should be possible to do this instead by starting with the standard model and straight forwardly adding a variable

h.addVar(0, highspy.kHighsInf)
h.changeColCost(dimension, kappa)

or by using h.addCol to add a column to the model, similar to how addRow is used to incorporate the conic approximations in

num_nz: int = dimension + 1
index: npt.NDArray[np.int8] = np.array(range(dimension + 1))
value: npt.NDArray[np.float64] = np.append(-omega@w_star, alpha)
h.addRow(0, inf, num_nz, index, value)

Either way, the result should be code which is less error prone.

Foggalong commented 2 months ago

@jajhall Do you know offhand if it's possible to update the Hessian with addCol? Been reading the C docs which go through the parameters for updating $c$, $L$, $A$, and $U$ (which are the same in Python), but don't mention $Q$.

If it's not yet possible should still be able to use addCol to incorporate $z$, then passHessian to add the extended Hessian to the model. This still removes most the messy extensions and amendment methods currently implemented!

jajhall commented 2 months ago

If you call addCol, then any non-empty Hessian will be extended with zeros so that its dimension is consistent with the vectors of costs and bounds. I added this feature as a consequence of modelling the robust optimization problem.

For non-zero modifications of the Hessian, it has to be re-loaded using passHessian

Foggalong commented 2 months ago

@jajhall This feature doesn't seem to be in highspy 1.7.1.dev2. I've got addCol working, but only if I add the Hessian separately using the extension method. Don't know if it's relevant, but the first line of the highspy terminal output has a different version number:

Running HiGHS 1.7.0 (git hash: 1ddc6c347):

jajhall commented 2 months ago

So you need to be using highspy 1.7.1. Update by running

pip install highspy -U

Foggalong commented 2 months ago

Damn, I'd missed off the -U flag when checking this. Thanks :+1: