Skip to content

Commit 01495bf

Browse files
committed
draft of weighted B0 in the LowRank quasi Newton solves
1 parent 038229f commit 01495bf

File tree

2 files changed

+44
-14
lines changed

2 files changed

+44
-14
lines changed

src/Optimization/HessianDiagPlusRowRank.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ HessianDiagPlusRowRank::HessianDiagPlusRowRank(hiopNlpDenseConstraints* nlp_in,
160160
sigma_strategy.c_str());
161161

162162
Dx_ = DhInv_->alloc_clone();
163+
//B0_ = Dx_->alloc_clone();
163164
#ifdef HIOP_DEEPCHECKS
164165
Vmat_ = V_->alloc_clone();
165166
#endif
@@ -172,6 +173,7 @@ HessianDiagPlusRowRank::~HessianDiagPlusRowRank()
172173
{
173174
delete DhInv_;
174175
delete Dx_;
176+
//delete B0_;
175177

176178
delete St_;
177179
delete Yt_;
@@ -238,7 +240,11 @@ void HessianDiagPlusRowRank::alloc_for_limited_mem(const size_type& mem_length)
238240

239241
bool HessianDiagPlusRowRank::update_logbar_diag(const hiopVector& Dx)
240242
{
241-
DhInv_->setToConstant(sigma_);
243+
// DhInv = (B0+Dx)^{-1}
244+
//DhInv_->setToConstant(sigma_);
245+
const hiopVector& B0 = *nlp_->inner_prod()->M_lumped();
246+
DhInv_->copyFrom(B0);
247+
DhInv_->scale(sigma_);
242248
DhInv_->axpy(1.0, Dx);
243249
Dx_->copyFrom(Dx);
244250
#ifdef HIOP_DEEPCHECKS
@@ -256,8 +262,6 @@ void HessianDiagPlusRowRank::print(FILE* f, hiopOutVerbosity v, const char* msg)
256262
fprintf(f, "%s\n", msg);
257263
#ifdef HIOP_DEEPCHECKS
258264
nlp_->log->write("Dx", *Dx_, v);
259-
#else
260-
fprintf(f, "Dx is not stored in this class, but it can be computed from Dx=DhInv^(1)-sigma");
261265
#endif
262266
nlp_->log->printf(v, "sigma=%22.16f;\n", sigma_);
263267
nlp_->log->write("DhInv", *DhInv_, v);
@@ -269,7 +273,7 @@ void HessianDiagPlusRowRank::print(FILE* f, hiopOutVerbosity v, const char* msg)
269273
nlp_->log->write("V", *Vmat_, v);
270274
#else
271275
fprintf(f,
272-
"V matrix is available at this point (only its LAPACK factorization). Print it in "
276+
"V matrix is not available at this point (only its LAPACK factorization). Print it in "
273277
"updateInternalBFGSRepresentation() instead, before factorizeV()\n");
274278
#endif
275279
nlp_->log->write("L", *L_, v);
@@ -383,9 +387,9 @@ bool HessianDiagPlusRowRank::update(const hiopIterate& it_curr,
383387
} // else of the switch
384388
// safe guard it
385389
sigma_ = fmax(fmin(sigma_safe_max_, sigma_), sigma_safe_min_);
386-
nlp_->log->printf(hovLinAlgScalars, "HessianDiagPlusRowRank: sigma was updated to %22.16e\n", sigma_);
390+
nlp_->log->printf(hovScalars, "HessianDiagPlusRowRank: sigma was updated to %22.16e\n", sigma_);
387391
} else { // sTy is too small or negative -> skip
388-
nlp_->log->printf(hovLinAlgScalars,
392+
nlp_->log->printf(hovScalars,
389393
"HessianDiagPlusRowRank: s^T*y=%12.6e not positive enough... skipping the Hessian update\n",
390394
sTy);
391395
}
@@ -422,7 +426,7 @@ bool HessianDiagPlusRowRank::update(const hiopIterate& it_curr,
422426
* Namely it computes V, a symmetric 2lx2l given by
423427
* V = [S'*B0*(DhInv*B0-I)*S -L+S'*B0*DhInv*Y ]
424428
* [-L'+Y'*Dhinv*B0*S +D+Y'*Dhinv*Y ]
425-
* In this function V is factorized and it will hold the factors at the end of the function
429+
* Also, the method factorizes V. V will contain the factors at the end of this method.
426430
* Note that L, D, S, and Y are from the BFGS secant representation and are updated/computed in 'update'
427431
*/
428432
void HessianDiagPlusRowRank::updateInternalBFGSRepresentation()
@@ -457,9 +461,11 @@ void HessianDiagPlusRowRank::updateInternalBFGSRepresentation()
457461

458462
//-- block (1,2)
459463
hiopMatrixDense& StB0DhInvYmL = DpYtDhInvY; // just a rename
464+
const hiopVector& B0 = *nlp_->inner_prod()->M_lumped();
460465
hiopVector& B0DhInv = new_n_vec1(n);
461466
B0DhInv.copyFrom(*DhInv_);
462-
B0DhInv.scale(sigma_);
467+
//B0DhInv.scale(sigma_);
468+
B0DhInv.axpy(sigma_, B0);
463469
mat_times_diag_times_mattrans_local(StB0DhInvYmL, *St_, B0DhInv, *Yt_);
464470
#ifdef HIOP_USE_MPI
465471
memcpy(buff1_lxlx3_ + l * l, StB0DhInvYmL.local_data(), buffsize);
@@ -470,10 +476,14 @@ void HessianDiagPlusRowRank::updateInternalBFGSRepresentation()
470476
V_->copyBlockFromMatrix(0, l, StB0DhInvYmL);
471477
#endif
472478

473-
//-- block (2,2)
479+
//-- block (1,1)
474480
hiopVector& theDiag = B0DhInv; // just a rename, also reuses values
475481
theDiag.addConstant(-1.0); // at this point theDiag=DhInv*B0-I
482+
483+
//multiply with sigma*I
476484
theDiag.scale(sigma_);
485+
theDiag.componentMult(B0);
486+
477487
hiopMatrixDense& StDS = DpYtDhInvY; // a rename
478488
sym_mat_times_diag_times_mattrans_local(0.0, StDS, 1.0, *St_, theDiag);
479489
#ifdef HIOP_USE_MPI
@@ -550,6 +560,9 @@ void HessianDiagPlusRowRank::solve(const hiopVector& rhsx, hiopVector& x)
550560
hiopVector& B0DhInvx = new_n_vec1(n);
551561
B0DhInvx.copyFrom(x); // it contains DhInv*res
552562
B0DhInvx.scale(sigma_); // B0*(DhInv*res)
563+
const hiopVector& B0 = *nlp_->inner_prod()->M_lumped();
564+
B0DhInvx.componentMult(B0);
565+
553566
St_->timesVec(0.0, stx, 1.0, B0DhInvx);
554567

555568
// 3. solve with V
@@ -562,6 +575,7 @@ void HessianDiagPlusRowRank::solve(const hiopVector& rhsx, hiopVector& x)
562575
hiopVector& result = new_n_vec1(n);
563576
St_->transTimesVec(0.0, result, 1.0, spart);
564577
result.scale(sigma_);
578+
result.componentMult(B0);
565579
Yt_->transTimesVec(1.0, result, 1.0, ypart);
566580
result.componentMult(*DhInv_);
567581

@@ -613,7 +627,9 @@ void HessianDiagPlusRowRank::sym_mat_times_inverse_times_mattrans(double beta,
613627
auto& Y1 = new_Y1(X, *Yt_); // both are kxl
614628
hiopVector& B0DhInv = new_n_vec1(n);
615629
B0DhInv.copyFrom(*DhInv_);
630+
const hiopVector& B0 = *nlp_->inner_prod()->M_lumped();
616631
B0DhInv.scale(sigma_);
632+
B0DhInv.componentMult(B0);
617633
mat_times_diag_times_mattrans_local(S1, X, B0DhInv, *St_);
618634
mat_times_diag_times_mattrans_local(Y1, X, *DhInv_, *Yt_);
619635

@@ -1060,7 +1076,8 @@ void HessianDiagPlusRowRank::times_vec_common(double beta,
10601076

10611077
// we have B+=B-B*s*B*s'/(s'*B*s)+yy'/(y'*s)
10621078
// B0 is sigma*I. There is an additional diagonal log-barrier term Dx_
1063-
1079+
const hiopVector& B0 = *nlp_->inner_prod()->M_lumped();
1080+
10641081
bool print = false;
10651082
if(print) {
10661083
nlp_->log->printf(hovMatrices, "---HessianDiagPlusRowRank::times_vec \n");
@@ -1106,6 +1123,7 @@ void HessianDiagPlusRowRank::times_vec_common(double beta,
11061123
// compute ak by an inner loop
11071124
a[k]->copyFrom(*sk);
11081125
a[k]->scale(sigma_);
1126+
a[k]->componentMult(B0);
11091127

11101128
for(int i = 0; i < k; i++) {
11111129
double biTsk = b[i]->dotProductWith(*sk);
@@ -1125,8 +1143,12 @@ void HessianDiagPlusRowRank::times_vec_common(double beta,
11251143
y.axzpy(alpha, x, *Dx_);
11261144
}
11271145

1128-
y.axpy(alpha * sigma_, x);
1146+
hiopVector* aux = B0.new_copy();
1147+
aux->componentMult(x);
11291148

1149+
y.axpy(alpha * sigma_, *aux);
1150+
delete aux;
1151+
11301152
for(int k = 0; k < l_curr_; k++) {
11311153
double bkTx = b[k]->dotProductWith(x);
11321154
double akTx = a[k]->dotProductWith(x);

src/Optimization/HessianDiagPlusRowRank.hpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,18 @@ class HessianDiagPlusRowRank : public hiopMatrix
161161
private:
162162
// Vector for (B0+Dk)^{-1}
163163
hiopVector* DhInv_;
164-
// Dx_ is needed in times_vec (for residual checking in solveCompressed). Can be recomputed from DhInv, but I decided to
165-
// store it instead to avoid round-off errors
164+
165+
/** @brief Log-barrier diagonal term
166+
*
167+
* `Dx_` is needed in times_vec (for residual checking in solveCompressed). While it can be recomputed on the fly,
168+
* for example from DhInv, I decided to store it to avoid round-off errors.
169+
*/
166170
hiopVector* Dx_;
167171

172+
//// The initial B0 Hessian approximation
173+
//hiopVector* B0_;
174+
175+
// Flags recomputation of the internal inverse representation
168176
bool matrix_changed_;
169177

170178
// These are matrices from the compact representation; they are updated at each iteration.
@@ -178,7 +186,7 @@ class HessianDiagPlusRowRank : public hiopMatrix
178186
hiopMatrixDense* L_;
179187
/// Diagonal matrix from the compact representation
180188
hiopVector* D_;
181-
// Matrix V from the representation of the inverse
189+
// Matrix V from the representation of the inverse, or its factors
182190
hiopMatrixDense* V_;
183191
#ifdef HIOP_DEEPCHECKS
184192
// copy of the V matrix - needed to check the residual

0 commit comments

Comments
 (0)