@@ -212,23 +212,6 @@ PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
212212 return PostSolveRetcode::DIMENSION_MISMATCH;
213213 }
214214
215- std::vector<double > x_unscaled = x_current_;
216- std::vector<double > y_unscaled = y_current_;
217-
218- std::vector<double > dSlackPos_unscaled = dSlackPos_;
219- std::vector<double > dSlackNeg_unscaled = dSlackNeg_;
220-
221- // 1. Unscale the solution vectors first
222- unscaleSolution (x_unscaled, y_unscaled);
223- const auto & row_scale = scaling_.GetRowScaling (); // Assumes getter exists
224- const auto & col_scale = scaling_.GetColScaling (); // Assumes getter exists
225- if (col_scale.size () == dSlackPos_unscaled.size ()) {
226- for (size_t i = 0 ; i < col_scale.size (); ++i) {
227- dSlackPos_unscaled[i] /= col_scale[i];
228- dSlackNeg_unscaled[i] /= col_scale[i];
229- }
230- }
231-
232215 // 2. Resize solution object to original dimensions
233216 solution.col_value .resize (original_num_col_);
234217 solution.row_value .resize (original_lp_->num_row_ );
@@ -237,12 +220,12 @@ PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
237220
238221 // 3. Recover Primal Column Values (x)
239222 for (int i = 0 ; i < original_lp_->num_col_ ; ++i) {
240- if (i >= (int )x_unscaled .size ()) {
241- logger_.info (" Index " + std::to_string (i) + " out of bounds for x_unscaled of size " + std::to_string (x_unscaled .size ()));
223+ if (i >= (int )x_current_ .size ()) {
224+ logger_.info (" Index " + std::to_string (i) + " out of bounds for x_current_ of size " + std::to_string (x_current_ .size ()));
242225 return PostSolveRetcode::DIMENSION_MISMATCH;
243226 }
244227
245- solution.col_value [i] = x_unscaled [i];
228+ solution.col_value [i] = x_current_ [i];
246229
247230 if (!std::isfinite (solution.col_value [i])) {
248231 logger_.info (" Non-finite primal variable value at index " + std::to_string (i) + " : " + std::to_string (solution.col_value [i]));
@@ -260,15 +243,17 @@ PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
260243 // 4. Recover Dual Row Values (y)
261244 for (int i = 0 ; i < original_lp_->num_row_ ; ++i) {
262245 if (constraint_types_[i] == LEQ) {
263- solution.row_dual [i] = -y_unscaled [i];
246+ solution.row_dual [i] = -y_current_ [i];
264247 } else {
265- solution.row_dual [i] = y_unscaled [i];
248+ solution.row_dual [i] = y_current_ [i];
266249 }
267250 }
268251
269252 // 5. Recover Primal Row Values (Ax)
270253 HighsLp unscaled_processed_lp = lp_;
271254
255+ const std::vector<double >& row_scale = scaling_.GetRowScaling ();
256+ const std::vector<double >& col_scale = scaling_.GetColScaling ();
272257 if (scaling_.IsScaled ()) {
273258 // Unscale matrix, costs, and rhs
274259 for (int iCol = 0 ; iCol < unscaled_processed_lp.num_col_ ; ++iCol) {
@@ -282,31 +267,31 @@ PostSolveRetcode PDLPSolver::postprocess(HighsSolution& solution) {
282267 }
283268 }
284269
285- std::vector<double > ax_unscaled (unscaled_processed_lp.num_row_ );
286- linalg::Ax (unscaled_processed_lp, x_unscaled, ax_unscaled );
270+ std::vector<double > ax_current_ (unscaled_processed_lp.num_row_ );
271+ linalg::Ax (unscaled_processed_lp, x_current_, ax_current_ );
287272
288273 int slack_variable_idx = original_num_col_;
289274 for (int i = 0 ; i < original_lp_->num_row_ ; ++i) {
290275 if (constraint_types_[i] == BOUND || constraint_types_[i] == FREE) {
291- solution.row_value [i] = x_unscaled [slack_variable_idx++];
276+ solution.row_value [i] = x_current_ [slack_variable_idx++];
292277 } else if (constraint_types_[i] == LEQ) {
293278 // We transformed Ax <= b to -Ax >= -b. The original row value is Ax.
294- // The calculated ax_unscaled is for -Ax, so we flip the sign back.
295- solution.row_value [i] = -ax_unscaled [i];
279+ // The calculated ax_current_ is for -Ax, so we flip the sign back.
280+ solution.row_value [i] = -ax_current_ [i];
296281 } else { // EQ, GEQ
297- solution.row_value [i] = ax_unscaled [i];
282+ solution.row_value [i] = ax_current_ [i];
298283 }
299284 }
300285
301286 // 6. Recover Dual Column Values (Reduced Costs)
302287 // The duals on the variable bounds l <= x <= u are the reduced costs.
303288 // In the PDLP framework, these are given by dSlackPos - dSlackNeg.
304289 for (int i = 0 ; i < original_num_col_; ++i) {
305- if (i >= (int )dSlackPos_unscaled .size () || i >= (int )dSlackNeg_unscaled .size ()) {
306- logger_.info (" Index " + std::to_string (i) + " out of bounds for dSlackPos/Neg_unscaled of size " + std::to_string (dSlackPos_unscaled .size ()));
290+ if (i >= (int )dSlackPos_ .size () || i >= (int )dSlackNeg_ .size ()) {
291+ logger_.info (" Index " + std::to_string (i) + " out of bounds for dSlackPos/Neg of size " + std::to_string (dSlackPos_ .size ()));
307292 return PostSolveRetcode::DIMENSION_MISMATCH;
308293 }
309- solution.col_dual [i] = dSlackPos_unscaled [i] - dSlackNeg_unscaled [i];
294+ solution.col_dual [i] = dSlackPos_ [i] - dSlackNeg_ [i];
310295 }
311296
312297 solution.value_valid = true ; // to do
@@ -1067,9 +1052,21 @@ void PDLPSolver::scaleProblem() {
10671052}
10681053
10691054void PDLPSolver::unscaleSolution (std::vector<double >& x,
1070- std::vector<double >& y) const {
1055+ std::vector<double >& y) {
10711056 scaling_.unscaleSolution (x, y);
1057+
1058+ x_current_ = x;
1059+ y_current_ = y;
1060+
1061+ const std::vector<double >& col_scale = scaling_.GetColScaling ();
1062+ if (!dSlackPos_.empty () && col_scale.size () == dSlackPos_.size ()) {
1063+ for (size_t i = 0 ; i < dSlackPos_.size (); ++i) {
1064+ dSlackPos_[i] /= col_scale[i];
1065+ dSlackNeg_[i] /= col_scale[i];
1066+ }
1067+ }
10721068}
1069+
10731070void PDLPSolver::logSummary () {
10741071 logger_.print_summary (results_, final_iter_count_, total_timer.read ());
10751072}
0 commit comments