Skip to content

Commit 933822d

Browse files
committed
Refinement on regularised system
1 parent 2555a6c commit 933822d

6 files changed

Lines changed: 73 additions & 21 deletions

File tree

highs/ipm/hipo/factorhighs/Numeric.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ Int Numeric::solve(std::vector<double>& x) const {
6262
return kRetOk;
6363
}
6464

65-
void Numeric::getReg(std::vector<double>& reg) { reg = std::move(total_reg_); }
65+
void Numeric::getReg(std::vector<double>& reg) {
66+
// unpermute regularisation
67+
permuteVector(total_reg_, S_->iperm());
68+
69+
reg = std::move(total_reg_);
70+
}
6671

6772
} // namespace hipo

highs/ipm/hipo/ipm/Iterate.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -627,52 +627,76 @@ void Iterate::finalResiduals(Info& info) const {
627627
}
628628
}
629629

630+
void Iterate::setReg(LinearSolver& LS, OptionNla opt) {
631+
// extract regularisation
632+
LS.getReg(total_reg);
633+
634+
// easy access to primal/dual regularisation
635+
if (opt == kOptionNlaNormEq) {
636+
Rp = nullptr;
637+
Rd = total_reg.data();
638+
} else {
639+
Rp = total_reg.data();
640+
Rd = &total_reg[model->n()];
641+
}
642+
}
643+
630644
void Iterate::residuals6x6(const NewtonDir& d) {
631645
const std::vector<double>& dx = d.x;
632646
const std::vector<double>& dy = d.y;
633647
const std::vector<double>& dxl = d.xl;
634648
const std::vector<double>& dxu = d.xu;
635649
const std::vector<double>& dzl = d.zl;
636650
const std::vector<double>& dzu = d.zu;
651+
const Int m = model->m();
652+
const Int n = model->n();
653+
assert(Rd);
637654

638655
// res1,2,3,4,5,6 contain the rhs of the linear system
639656

640-
// ires1 = res1 - A * dx
657+
// ires1 = res1 - A * dx - Rd * dy
641658
ires.r1 = res.r1;
642659
model->A().alphaProductPlusY(-1.0, dx, ires.r1);
660+
for (Int i = 0; i < m; ++i) {
661+
ires.r1[i] -= Rd[i] * dy[i];
662+
}
643663

644664
// ires2 = res2 - dx + dxl
645-
for (Int i = 0; i < model->n(); ++i)
665+
for (Int i = 0; i < n; ++i)
646666
if (model->hasLb(i))
647667
ires.r2[i] = res.r2[i] - dx[i] + dxl[i];
648668
else
649669
ires.r2[i] = 0.0;
650670

651671
// ires3 = res3 - dx - dxu
652-
for (Int i = 0; i < model->n(); ++i)
672+
for (Int i = 0; i < n; ++i)
653673
if (model->hasUb(i))
654674
ires.r3[i] = res.r3[i] - dx[i] - dxu[i];
655675
else
656676
ires.r3[i] = 0.0;
657677

658-
// ires4 = res4 - A^T * dy - dzl + dzu
678+
// ires4 = res4 - A^T * dy - dzl + dzu + Rp * dx
659679
ires.r4 = res.r4;
660-
for (Int i = 0; i < model->n(); ++i) {
680+
for (Int i = 0; i < n; ++i) {
661681
if (model->hasLb(i)) ires.r4[i] -= dzl[i];
662682
if (model->hasUb(i)) ires.r4[i] += dzu[i];
663683
}
664684
model->A().alphaProductPlusY(-1.0, dy, ires.r4, true);
685+
for (Int i = 0; i < n; ++i) {
686+
double reg_p = Rp ? Rp[i] : regul.primal;
687+
ires.r4[i] += reg_p * dx[i];
688+
}
665689

666690
// ires5 = res5 - zl * dxl - xl * dzl
667-
for (Int i = 0; i < model->n(); ++i) {
691+
for (Int i = 0; i < n; ++i) {
668692
if (model->hasLb(i))
669693
ires.r5[i] = res.r5[i] - zl[i] * dxl[i] - xl[i] * dzl[i];
670694
else
671695
ires.r5[i] = 0.0;
672696
}
673697

674698
// ires6 = res6 - zu * dxu - xu * dzu
675-
for (Int i = 0; i < model->n(); ++i) {
699+
for (Int i = 0; i < n; ++i) {
676700
if (model->hasUb(i))
677701
ires.r6[i] = res.r6[i] - zu[i] * dxu[i] - xu[i] * dzu[i];
678702
else

highs/ipm/hipo/ipm/Iterate.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "Info.h"
77
#include "IpmData.h"
8+
#include "LinearSolver.h"
89
#include "Model.h"
910
#include "ipm/hipo/auxiliary/IntConfig.h"
1011

@@ -55,6 +56,9 @@ struct Iterate {
5556

5657
// regularisation values
5758
Regularisation& regul;
59+
std::vector<double> total_reg;
60+
double* Rp;
61+
double* Rd;
5862

5963
// residuals of linear system for iterative refinement
6064
Residuals ires;
@@ -191,6 +195,8 @@ struct Iterate {
191195
// Compute residual of 6x6 linear system for iterative refinement.
192196
// ===================================================================================
193197
void residuals6x6(const NewtonDir& d);
198+
199+
void setReg(LinearSolver& LS, OptionNla opt);
194200
};
195201

196202
} // namespace hipo

highs/ipm/hipo/ipm/LinearSolver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace hipo {
2626
// - flops: return number of flops needed for factorisation
2727
// - spops: return number of sparse ops needed for factorisation
2828
// - nz: return number of nonzeros in factorisation
29+
// - getReg: extract regularisation
2930
//
3031
// NB: forming the normal equations or augmented system is delegated to the
3132
// linear solver chosen, so that only the appropriate data (upper triangle,

highs/ipm/hipo/ipm/Refine.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,26 @@ double Solver::computeOmega(const NewtonDir& delta) const {
8181

8282
// tau_i =
8383
// tau_const * (inf_norm_rows(big 6x6 matrix)_i * inf_norm_delta + |rhs_i|)
84+
8485
const double tau_const = 1000.0 * (5 * n_ + m_) * 1e-16;
8586
double omega_1{}, omega_2{};
8687

88+
assert(it_->Rd);
89+
8790
// First block
8891
for (Int i = 0; i < m_; ++i) {
89-
const double tau = tau_const * (model_.infNormRows(i) * inf_norm_delta +
90-
std::abs(it_->res.r1[i]));
91-
updateOmega(tau, omega_1, omega_2,
92-
// numerator
93-
std::abs(it_->ires.r1[i]),
94-
// denominators
95-
abs_prod_A[i], std::abs(it_->res.r1[i]),
96-
model_.oneNormRows(i) * inf_norm_delta);
92+
const double tau =
93+
tau_const * (std::max(model_.infNormRows(i), std::abs(it_->Rd[i])) *
94+
inf_norm_delta +
95+
std::abs(it_->res.r1[i]));
96+
updateOmega(
97+
tau, omega_1, omega_2,
98+
// numerator
99+
std::abs(it_->ires.r1[i]),
100+
// denominators
101+
abs_prod_A[i] + std::abs(it_->Rd[i]) * std::abs(delta.y[i]),
102+
std::abs(it_->res.r1[i]),
103+
(model_.oneNormRows(i) + std::abs(it_->Rd[i])) * inf_norm_delta);
97104
}
98105

99106
// Second block
@@ -128,20 +135,25 @@ double Solver::computeOmega(const NewtonDir& delta) const {
128135

129136
// Fourth block
130137
for (Int i = 0; i < n_; ++i) {
138+
double reg_p = it_->Rp ? it_->Rp[i] : regul_.primal;
139+
131140
const double tau =
132-
tau_const * (std::max(model_.infNormCols(i), 1.0) * inf_norm_delta +
133-
std::abs(it_->res.r4[i]));
141+
tau_const *
142+
(std::max(std::max(model_.infNormCols(i), 1.0), std::abs(reg_p)) *
143+
inf_norm_delta +
144+
std::abs(it_->res.r4[i]));
134145

135146
double denom1 = abs_prod_At[i];
136147
if (model_.hasLb(i)) denom1 += std::abs(delta.zl[i]);
137148
if (model_.hasUb(i)) denom1 += std::abs(delta.zu[i]);
149+
denom1 += std::abs(reg_p) * std::abs(delta.x[i]);
138150

139151
updateOmega(tau, omega_1, omega_2,
140152
// numerator
141153
std::abs(it_->ires.r4[i]),
142154
// denominators
143155
denom1, std::abs(it_->res.r4[i]),
144-
(model_.oneNormCols(i) + 2) * inf_norm_delta);
156+
(model_.oneNormCols(i) + 2 + std::abs(reg_p)) * inf_norm_delta);
145157
}
146158

147159
// Fifth block

highs/ipm/hipo/ipm/Solver.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,14 @@ bool Solver::solve2x2(NewtonDir& delta, const Residuals& rhs) {
293293
std::vector<double> res8 = it_->residual8(rhs, res7);
294294

295295
// factorise normal equations, if not yet done
296-
if (!LS_->valid_)
296+
if (!LS_->valid_) {
297297
if (Int status = LS_->factorNE(model_.A(), theta_inv)) {
298298
logH_.printe("Error while factorising normal equations\n");
299299
info_.status = (Status)status;
300300
return true;
301301
}
302+
it_->setReg(*LS_, options_.nla);
303+
}
302304

303305
// solve with normal equations
304306
if (Int status = LS_->solveNE(res8, delta.y)) {
@@ -321,12 +323,14 @@ bool Solver::solve2x2(NewtonDir& delta, const Residuals& rhs) {
321323
// AUGMENTED SYSTEM
322324
else {
323325
// factorise augmented system, if not yet done
324-
if (!LS_->valid_)
326+
if (!LS_->valid_) {
325327
if (Int status = LS_->factorAS(model_.A(), theta_inv)) {
326328
logH_.printe("Error while factorising augmented system\n");
327329
info_.status = (Status)status;
328330
return true;
329331
}
332+
it_->setReg(*LS_, options_.nla);
333+
}
330334

331335
// solve with augmented system
332336
if (Int status = LS_->solveAS(res7, rhs.r1, delta.x, delta.y)) {

0 commit comments

Comments
 (0)