@@ -16,10 +16,12 @@ void Solver::refine(NewtonDir& delta) {
1616 info_.residual_time += clock.stop ();
1717
1818 clock.start ();
19- double omega = computeOmega (delta);
19+ OmegaValues omegavals = computeOmega (delta);
20+ double omega = omegavals.compute ();
2021 info_.omega_time += clock.stop ();
2122
2223 double old_omega{};
24+ OmegaValues old_values;
2325
2426 for (Int iter = 0 ; iter < kMaxIterRefine ; ++iter) {
2527 if (omega < kTolRefine ) break ;
@@ -35,21 +37,30 @@ void Solver::refine(NewtonDir& delta) {
3537 info_.residual_time += clock.stop ();
3638
3739 old_omega = omega;
40+ old_values = omegavals;
3841
3942 clock.start ();
40- omega = computeOmega (temp);
43+ omegavals = computeOmega (temp);
44+ omega = omegavals.compute ();
4145 info_.omega_time += clock.stop ();
4246
4347 if (omega < old_omega) {
4448 delta = temp;
4549 } else {
4650 omega = old_omega;
51+ omegavals = old_values;
4752 break ;
4853 }
4954 }
5055
5156 // save worst residual seen in this ipm iteration
5257 it_->data .back ().omega = std::max (it_->data .back ().omega , omega);
58+
59+ double null, image, rest;
60+ omegavals.extract (null, image, rest);
61+ it_->data .back ().omega_null = std::max (it_->data .back ().omega_null , null);
62+ it_->data .back ().omega_image = std::max (it_->data .back ().omega_image , image);
63+ it_->data .back ().omega_rest = std::max (it_->data .back ().omega_rest , rest);
5364}
5465
5566static void updateOmega (double tau, double & omega1, double & omega2, double num,
@@ -63,7 +74,33 @@ static void updateOmega(double tau, double& omega1, double& omega2, double num,
6374 }
6475}
6576
66- double Solver::computeOmega (const NewtonDir& delta) const {
77+ double Solver::OmegaValues::compute () const {
78+ // Given the omega values of each block of equations, compute the omega value
79+ // of the whole system.
80+ double v1{}, v2{};
81+ for (Int i = 0 ; i < 6 ; ++i) {
82+ v1 = std::max (v1, omega_1[i]);
83+ v2 = std::max (v2, omega_2[i]);
84+ }
85+ return v1 + v2;
86+ }
87+
88+ void Solver::OmegaValues::extract (double & null, double & image,
89+ double & rest) const {
90+ // Given the omega values of each block of equations, compute the omega values
91+ // corresponding to the equations involging A ("null space error"), A^T
92+ // ("image space error") and the rest.
93+
94+ null = omega_1[0 ] + omega_2[0 ];
95+ image = omega_1[3 ] + omega_2[3 ];
96+
97+ rest = omega_1[1 ] + omega_2[1 ];
98+ rest = std::max (rest, omega_1[2 ] + omega_2[2 ]);
99+ rest = std::max (rest, omega_1[4 ] + omega_2[4 ]);
100+ rest = std::max (rest, omega_1[5 ] + omega_2[5 ]);
101+ }
102+
103+ Solver::OmegaValues Solver::computeOmega (const NewtonDir& delta) const {
67104 // Evaluate iterative refinement progress. Based on "Solving sparse linear
68105 // systems with sparse backward error", Arioli, Demmel, Duff.
69106
@@ -91,12 +128,12 @@ double Solver::computeOmega(const NewtonDir& delta) const {
91128 // rhs is in it_->res
92129 // residual of linear system is in it_->ires
93130
131+ OmegaValues w;
132+
94133 // tau_i =
95134 // tau_const * (inf_norm_rows(big 6x6 matrix)_i * inf_norm_delta + |rhs_i|)
96135
97136 const double tau_const = 1000.0 * (5 * n_ + m_) * 1e-16 ;
98- double omega_1{}, omega_2{};
99-
100137 assert (it_->Rd );
101138
102139 // First block
@@ -106,7 +143,7 @@ double Solver::computeOmega(const NewtonDir& delta) const {
106143 inf_norm_delta +
107144 std::abs (it_->res .r1 [i]));
108145 updateOmega (
109- tau, omega_1, omega_2,
146+ tau, w. omega_1 [ 0 ], w. omega_2 [ 0 ] ,
110147 // numerator
111148 std::abs (it_->ires .r1 [i]),
112149 // denominators
@@ -120,7 +157,7 @@ double Solver::computeOmega(const NewtonDir& delta) const {
120157 if (model_.hasLb (i)) {
121158 const double tau =
122159 tau_const * (1.0 * inf_norm_delta + std::abs (it_->res .r2 [i]));
123- updateOmega (tau, omega_1, omega_2,
160+ updateOmega (tau, w. omega_1 [ 1 ], w. omega_2 [ 1 ] ,
124161 // numerator
125162 std::abs (it_->ires .r2 [i]),
126163 // denominators
@@ -136,7 +173,7 @@ double Solver::computeOmega(const NewtonDir& delta) const {
136173 if (model_.hasUb (i)) {
137174 const double tau =
138175 tau_const * (1.0 * inf_norm_delta + std::abs (it_->res .r3 [i]));
139- updateOmega (tau, omega_1, omega_2,
176+ updateOmega (tau, w. omega_1 [ 2 ], w. omega_2 [ 2 ] ,
140177 // numerator
141178 std::abs (it_->ires .r3 [i]),
142179 // denominators
@@ -160,7 +197,7 @@ double Solver::computeOmega(const NewtonDir& delta) const {
160197 if (model_.hasUb (i)) denom1 += std::abs (delta.zu [i]);
161198 denom1 += std::abs (reg_p) * std::abs (delta.x [i]);
162199
163- updateOmega (tau, omega_1, omega_2,
200+ updateOmega (tau, w. omega_1 [ 3 ], w. omega_2 [ 3 ] ,
164201 // numerator
165202 std::abs (it_->ires .r4 [i]),
166203 // denominators
@@ -177,7 +214,7 @@ double Solver::computeOmega(const NewtonDir& delta) const {
177214 std::abs (it_->res .r5 [i]));
178215
179216 updateOmega (
180- tau, omega_1, omega_2,
217+ tau, w. omega_1 [ 4 ], w. omega_2 [ 4 ] ,
181218 // numerator
182219 std::abs (it_->ires .r5 [i]),
183220 // denominators
@@ -197,7 +234,7 @@ double Solver::computeOmega(const NewtonDir& delta) const {
197234 std::abs (it_->res .r6 [i]));
198235
199236 updateOmega (
200- tau, omega_1, omega_2,
237+ tau, w. omega_1 [ 5 ], w. omega_2 [ 5 ] ,
201238 // numerator
202239 std::abs (it_->ires .r6 [i]),
203240 // denominators
@@ -208,7 +245,7 @@ double Solver::computeOmega(const NewtonDir& delta) const {
208245 }
209246 }
210247
211- return omega_1 + omega_2 ;
248+ return w ;
212249}
213250
214251} // namespace hipo
0 commit comments