inline void Mp_M(DMatrixSlice* gms_lhs, const M& M_rhs, BLAS_Cpp::Transp trans_rhs) { Mp_StM(gms_lhs,1.0,M_rhs,trans_rhs); }
void MatrixSymPosDefLBFGS::update_Q() const { using DenseLinAlgPack::tri; using DenseLinAlgPack::tri_ele; using DenseLinAlgPack::Mp_StM; // // We need update the factorizations to solve for: // // x = inv(Q) * y // // [ y1 ] = [ (1/gk)*S'S L ] * [ x1 ] // [ y2 ] [ L' -D ] [ x2 ] // // We will solve the above system using the schur complement: // // C = (1/gk)*S'S + L*inv(D)*L' // // According to the referenced paper, C is p.d. so: // // C = J*J' // // We then compute the solution as: // // x1 = inv(C) * ( y1 + L*inv(D)*y2 ) // x2 = - inv(D) * ( y2 - L'*x1 ) // // Therefore we will just update the factorization C = J*J' // // Form the upper triangular part of C which will become J // which we are using storage of QJ if( QJ_.rows() < m_ ) QJ_.resize( m_, m_ ); const size_type mb = m_bar_; DMatrixSlice C = QJ_(1,mb,1,mb); // C = L * inv(D) * L' // // Here L is a strictly lower triangular (zero diagonal) matrix where: // // L = [ 0 0 ] // [ Lb 0 ] // // Lb is lower triangular (nonzero diagonal) // // Therefore we compute L*inv(D)*L' as: // // C = [ 0 0 ] * [ Db 0 ] * [ 0 Lb' ] // [ Lb 0 ] [ 0 db ] [ 0 0 ] // // = [ 0 0 ] = [ 0 0 ] // [ 0 Cb ] [ 0 Lb*Db*Lb' ] // // We need to compute the upper triangular part of Cb. C.row(1) = 0.0; if( mb > 1 ) comp_Cb( STY_(2,mb,1,mb-1), STY_.diag(0)(1,mb-1), &C(2,mb,2,mb) ); // C += (1/gk)*S'S const DMatrixSliceSym &STS = this->STS(); Mp_StM( &C, (1/gamma_k_), tri( STS.gms(), STS.uplo(), BLAS_Cpp::nonunit ) , BLAS_Cpp::trans ); // Now perform a cholesky factorization of C // After this factorization the upper triangular part of QJ // (through C) will contain the cholesky factor. DMatrixSliceTriEle C_upper = tri_ele( C, BLAS_Cpp::upper ); try { DenseLinAlgLAPack::potrf( &C_upper ); } catch( const DenseLinAlgLAPack::FactorizationException &fe ) { TEUCHOS_TEST_FOR_EXCEPTION( true, UpdateFailedException ,"Error, the factorization of Q which should be s.p.d. failed with" " the error message: {" << fe.what() << "}"; ); }