Skip to content

Commit 4c0b571

Browse files
committed
fix initialize step size for adaptive step size
1 parent 799788b commit 4c0b571

File tree

3 files changed

+46
-37
lines changed

3 files changed

+46
-37
lines changed

highs/pdlp/cupdlp/cupdlp_step.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ cupdlp_retcode PDHG_Update_Iterate_Adaptive_Step_Size(CUPDLPwork *pdhg) {
247247
while (!isDone) {
248248
++stepsize->nStepSizeIter;
249249
++stepIterThis;
250-
251250
cupdlp_float dPrimalStepUpdate = dStepSizeUpdate / sqrt(stepsize->dBeta);
252251
cupdlp_float dDualStepUpdate = dStepSizeUpdate * sqrt(stepsize->dBeta);
253252

@@ -265,7 +264,6 @@ cupdlp_retcode PDHG_Update_Iterate_Adaptive_Step_Size(CUPDLPwork *pdhg) {
265264
cupdlp_float dInteraction = 0.0;
266265

267266
cupdlp_compute_interaction_and_movement(pdhg, &dMovement, &dInteraction);
268-
269267
#if CUPDLP_DUMP_LINESEARCH_STATS && CUPDLP_DEBUG
270268
cupdlp_float dInteractiony = 0.0;
271269
// Δy' (AΔx)
@@ -312,6 +310,17 @@ cupdlp_retcode PDHG_Update_Iterate_Adaptive_Step_Size(CUPDLPwork *pdhg) {
312310
#endif
313311
}
314312

313+
double debug_pdlp_data_ax_norm = 0.0;
314+
cupdlp_twoNorm(pdhg, problem->nRows, ax->data,
315+
&debug_pdlp_data_ax_norm);
316+
pdhg->debug_pdlp_data_.ax_norm = debug_pdlp_data_ax_norm;
317+
318+
319+
double debug_pdlp_data_aty_norm = 0.0;
320+
cupdlp_twoNorm(pdhg, problem->nCols, aty->data,
321+
&debug_pdlp_data_aty_norm);
322+
pdhg->debug_pdlp_data_.aty_norm = debug_pdlp_data_aty_norm;
323+
315324
stepsize->dPrimalStep = dStepSizeUpdate / sqrt(stepsize->dBeta);
316325
stepsize->dDualStep = dStepSizeUpdate * sqrt(stepsize->dBeta);
317326

highs/pdlp/hipdlp/pdhg.cc

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,33 +1214,32 @@ void PDLPSolver::InitializeStepSizes() {
12141214
}
12151215
}
12161216

1217-
std::vector<double> PDLPSolver::UpdateX(double primal_step) {
1217+
std::vector<double> PDLPSolver::UpdateX(const std::vector<double> &x, const std::vector<double> &aty,double primal_step) {
12181218
std::vector<double> x_new(lp_.num_col_);
1219-
debug_pdlp_data_.aty_norm = linalg::vector_norm(ATy_cache_);
12201219
for (HighsInt i = 0; i < lp_.num_col_; i++) {
1221-
double gradient = lp_.col_cost_[i] - ATy_cache_[i];
1222-
x_new[i] = linalg::project_box(x_current_[i] - primal_step * gradient,
1220+
double gradient = lp_.col_cost_[i] - aty[i];
1221+
x_new[i] = linalg::project_box(x[i] - primal_step * gradient,
12231222
lp_.col_lower_[i], lp_.col_upper_[i]);
12241223
}
12251224
return x_new;
12261225
}
12271226

1228-
std::vector<double> PDLPSolver::UpdateY(double dual_step) {
1227+
std::vector<double> PDLPSolver::UpdateY(const std::vector<double> &y, const std::vector<double> &ax , const std::vector<double> &ax_next, double dual_step) {
12291228
std::vector<double> y_new(lp_.num_row_);
12301229
for (HighsInt j = 0; j < lp_.num_row_; j++) {
1231-
double extr_ax = 2 * Ax_next_[j] - Ax_cache_[j];
1230+
double extr_ax = 2 * ax_next[j] - ax[j];
12321231
bool is_equality = (lp_.row_lower_[j] == lp_.row_upper_[j]);
12331232
double q = lp_.row_lower_[j];
1234-
double dual_update = y_current_[j] + dual_step * (q - extr_ax);
1233+
double dual_update = y[j] + dual_step * (q - extr_ax);
12351234
y_new[j] = is_equality ? dual_update : linalg::project_non_negative(dual_update);
12361235
}
12371236
return y_new;
12381237
}
12391238

12401239
void PDLPSolver::UpdateIteratesFixed() {
1241-
x_next_ = UpdateX(stepsize_.primal_step);
1240+
x_next_ = UpdateX(x_current_, ATy_cache_,stepsize_.primal_step);
12421241
linalg::Ax(lp_, x_next_, Ax_next_);
1243-
y_next_ = UpdateY(stepsize_.dual_step);
1242+
y_next_ = UpdateY(y_current_, Ax_cache_,Ax_next_, stepsize_.dual_step);
12441243
}
12451244

12461245
void PDLPSolver::UpdateIteratesAdaptive() {
@@ -1255,46 +1254,50 @@ void PDLPSolver::UpdateIteratesAdaptive() {
12551254
stepsize_.dual_step);
12561255

12571256
// Compute candidate solution
1258-
std::vector<double> x_candidate(lp_.num_col_);
1259-
std::vector<double> y_candidate(lp_.num_row_);
1260-
std::vector<double> ax_candidate(lp_.num_row_);
1261-
std::vector<double> aty_candidate(lp_.num_col_);
1257+
std::vector<double> x_candidate = x_current_; // Start from current x
1258+
std::vector<double> y_candidate = y_current_; // Start from current y
1259+
std::vector<double> ax_candidate = Ax_cache_; // Start from current Ax
1260+
std::vector<double> aty_candidate = ATy_cache_; // Start from current ATy
1261+
std::vector<double> xupdate = x_next_;
1262+
std::vector<double> yupdate = y_next_;
1263+
std::vector<double> axupdate = Ax_next_;
1264+
std::vector<double> atyupdate = ATy_next_;
12621265
while (!accepted_step) {
12631266
stepsize_.step_size_iter++; //nStepSizeIter
12641267
inner_iterations++;
1265-
1268+
/* cupdlp does not have a max iteration limit here
12661269
if (inner_iterations >= 60) {
12671270
std::cerr << "Warning: Adaptive line search exceeded 60 iterations."
12681271
<< std::endl;
12691272
// Force accept the last candidate
12701273
break;
12711274
}
1272-
1275+
*/
12731276
// Calculate step sizes for this iteration
12741277
double primal_step_update = dStepSizeUpdate / std::sqrt(stepsize_.beta);
12751278
double dual_step_update = dStepSizeUpdate * std::sqrt(stepsize_.beta);
12761279

12771280
// Primal update
1278-
x_candidate = UpdateX(primal_step_update);
1279-
linalg::Ax(lp_, x_candidate, ax_candidate);
1281+
xupdate = UpdateX(x_candidate, aty_candidate,primal_step_update); //need to take aty
1282+
linalg::Ax(lp_, xupdate , axupdate);
12801283

12811284
// Dual update
1282-
y_candidate = UpdateY(dual_step_update);
1283-
linalg::ATy(lp_, y_candidate, aty_candidate);
1285+
yupdate = UpdateY(y_candidate, ax_candidate,axupdate, dual_step_update);
1286+
linalg::ATy(lp_, yupdate, atyupdate);
12841287

12851288
// Compute deltas
12861289
std::vector<double> delta_x(lp_.num_col_);
12871290
std::vector<double> delta_y(lp_.num_row_);
12881291
std::vector<double> delta_aty(lp_.num_col_);
12891292

12901293
for (size_t i = 0; i < x_candidate.size(); ++i) {
1291-
delta_x[i] = x_candidate[i] - x_current_[i];
1294+
delta_x[i] = xupdate[i] - x_candidate[i];
12921295
}
12931296
for (size_t i = 0; i < y_candidate.size(); ++i) {
1294-
delta_y[i] = y_candidate[i] - y_current_[i];
1297+
delta_y[i] = yupdate[i] - y_candidate[i];
12951298
}
12961299
for (size_t i = 0; i < aty_candidate.size(); ++i) {
1297-
delta_aty[i] = aty_candidate[i] - ATy_cache_[i];
1300+
delta_aty[i] = atyupdate[i] - aty_candidate[i];
12981301
}
12991302

13001303
// Check numerical stability
@@ -1310,12 +1313,10 @@ void PDLPSolver::UpdateIteratesAdaptive() {
13101313
double movement = ComputeMovement(delta_x, delta_y);
13111314
double nonlinearity =
13121315
ComputeNonlinearity(delta_x, delta_aty);
1313-
13141316
// Compute step size limit
1315-
double step_size_limit = (nonlinearity > 1e-12)
1316-
? (movement / (1.0 * nonlinearity))
1317-
: // in cupdlp-c, the factor is 1
1318-
std::numeric_limits<double>::infinity();
1317+
double step_size_limit = (nonlinearity != 0.0)
1318+
? (movement / std::fabs(nonlinearity))
1319+
: std::numeric_limits<double>::infinity();
13191320

13201321
/*
13211322
highsLogUser(*log_options_, HighsLogType::kInfo,
@@ -1349,14 +1350,13 @@ void PDLPSolver::UpdateIteratesAdaptive() {
13491350
//current_eta_ = std::max(MIN_ETA, std::min(MAX_ETA, current_eta_));
13501351
}
13511352

1352-
x_next_ = x_candidate;
1353-
y_next_ = y_candidate;
1354-
Ax_next_ = ax_candidate;
1355-
ATy_next_ = aty_candidate;
1353+
x_next_ = xupdate;
1354+
y_next_ = yupdate;
1355+
Ax_next_ = axupdate;
1356+
ATy_next_ = atyupdate;
13561357

13571358
current_eta_ = dStepSizeUpdate;
13581359
stepsize_.primal_step = dStepSizeUpdate / std::sqrt(stepsize_.beta);
1359-
std::cout << "new primal step: " << stepsize_.primal_step << std::endl;
13601360
stepsize_.dual_step = dStepSizeUpdate * std::sqrt(stepsize_.beta);
13611361
}
13621362

@@ -1412,6 +1412,6 @@ double PDLPSolver::ComputeNonlinearity(const std::vector<double>& delta_primal,
14121412
for (size_t i = 0; i < delta_primal.size(); ++i) {
14131413
nonlinearity += delta_primal[i] * delta_aty[i];
14141414
}
1415-
return std::abs(nonlinearity);
1415+
return nonlinearity; // cupdlp does not take absolute value
14161416
}
14171417

highs/pdlp/hipdlp/pdhg.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ class PDLPSolver {
6969

7070
// --- Step Update Methods (previously in Step) ---
7171
void InitializeStepSizes();
72-
std::vector<double> UpdateX(double primal_step);
73-
std::vector<double> UpdateY(double dual_step);
72+
std::vector<double> UpdateX(const std::vector<double> &x, const std::vector<double> &aty,double primal_step);
73+
std::vector<double> UpdateY(const std::vector<double> &y, const std::vector<double> &ax , const std::vector<double> &ax_next, double dual_step);
7474
void UpdateIteratesFixed();
7575
void UpdateIteratesAdaptive();
7676
bool UpdateIteratesMalitskyPock(bool first_malitsky_iteration);

0 commit comments

Comments
 (0)