77 #include "ConstrainedOptPack/src/AbstractLinAlgPack_BFGS_helpers.hpp"
99 namespace ConstrainedOptPack {
158 ,
bool maintain_original
159 ,
bool maintain_inverse
163 initial_setup(max_size,m,maintain_original,maintain_inverse,auto_rescaling);
169 ,
bool maintain_original
170 ,
bool maintain_inverse
175 if( !maintain_original && !maintain_inverse )
176 throw std::invalid_argument(
177 "MatrixSymPosDefLBFGS::initial_setup(...) : "
178 "Error, both maintain_original and maintain_inverse can not both be false!" );
180 throw std::invalid_argument(
181 "MatrixSymPosDefLBFGS::set_num_updates_stored(m) : "
182 "Error, the number of storage locations must be > 0" );
203 out <<
"*** Limited Memory BFGS matrix.\n"
204 <<
"Conversion to dense =\n";
206 out <<
"\n*** Stored quantities\n"
207 <<
"\ngamma_k = " <<
gamma_k_ << std::endl;
209 out <<
"\nS =\n" <<
S()
212 <<
"\nlower(S'S) \\ zero diagonal \\ upper(Y'Y) =\n"
214 <<
"\nQ updated? = " <<
Q_updated_ << std::endl
215 <<
"\nCholesky of schur complement of Q, QJ =\n" <<
QJ_(1,
m_bar_,1,
m_bar_);
224 if( p_m ==
this )
return *
this;
226 auto_rescaling_ = p_m->auto_rescaling_;
246 throw std::invalid_argument(
"MatrixSymPosDefLBFGS::operator=(const MatrixOp& m)"
247 " : The concrete type of m is not a subclass of MatrixSymPosDefLBFGS as expected" );
320 t1 =
work_( t1s, t1s + t1n - 1 ),
321 t2 =
work_( t2s, t2s + t2n - 1 );
423 t1 =
work_( t1s, t1s + t1n - 1 ),
424 t2 =
work_( t2s, t2s + t2n - 1 ),
425 t3 =
work_( t3s, t3s + t3n - 1 ),
426 t4 =
work_( t4s, t4s + t4n - 1 ),
427 t5 =
work_( t5s, t5s + t5n - 1 );
448 V_mV( &t3, t1(mb+1,2*mb) );
477 std::ostringstream omsg;
479 <<
"MatrixSymPosDefLBFGS::init_identity(n,alpha) : Error, "
480 <<
"alpha = " << alpha <<
" <= 0 is not allowed!";
481 throw std::invalid_argument( omsg.str() );
487 std::ostringstream omsg;
489 <<
"MatrixSymPosDefLBFGS::init_identity(n,alpha) : Error, "
490 <<
"n = " << n <<
" > max_size = " <<
n_max_;
491 throw std::invalid_argument( omsg.str() );
495 S_.resize( n_max_,
m_ );
496 Y_.resize( n_max_,
m_ );
532 std::ostringstream omsg;
533 if( !
BFGS_sTy_suff_p_d(*s,*y,&sTy,&omsg,
"MatrixSymPosDefLBFGS::secant_update(...)" ) ) {
534 throw UpdateSkippedException( omsg.str() );
547 S_.col(k) =
S_.col(k+1);
548 Y_.col(k) =
Y_.col(k+1);
683 std::ostringstream omsg;
685 <<
"MatrixSymPosDefLBFGS::initialize(alpha,max_size) : Error, "
686 <<
"alpha = " << alpha <<
" <= 0 is not allowed!";
687 throw std::invalid_argument( omsg.str() );
696 ,
bool force_factorization
698 ,PivotTolerances pivot_tols
701 throw std::runtime_error(
702 "MatrixSymPosDefLBFGS::initialize(A,max_size,force_refactorization,inertia) : Error, "
703 "This function is undefined for this subclass. I am so sorry for this terrible hack!" );
713 return Inertia(0,0,
n_);
724 ,
bool force_refactorization
725 ,EEigenValType add_eigen_val
726 ,PivotTolerances pivot_tols
731 std::ostringstream omsg;
733 <<
"MatrixSymPosDefLBFGS::augment_update(...) : Error, "
734 <<
"this->rows() = " <<
n_ <<
" == this->max_size() = " << n_max_
735 <<
" so we can't allow the matrix to grow!";
736 throw std::invalid_argument( omsg.str() );
739 throw std::invalid_argument(
740 "MatrixSymPosDefLBFGS::augment_update(...) : Error, "
741 "t must be NULL in this implemention. Sorry for this hack" );
744 std::ostringstream omsg;
746 <<
"MatrixSymPosDefLBFGS::augment_update(...) : Error, "
747 <<
"alpha = " << alpha <<
" <= 0 is not allowed!";
748 throw std::invalid_argument( omsg.str() );
750 if( add_eigen_val == MatrixSymAddDelUpdateable::EIGEN_VAL_NEG ) {
751 std::ostringstream omsg;
753 <<
"MatrixSymPosDefLBFGS::augment_update(...) : Error, "
754 <<
"add_eigen_val == EIGEN_VAL_NEG is not allowed!";
755 throw std::invalid_argument( omsg.str() );
777 ,
bool force_refactorization
778 ,EEigenValType drop_eigen_val
779 ,PivotTolerances pivot_tols
858 DVectorSlice::const_iterator
859 d_itr =
STY_.diag(0).begin(),
861 DVectorSlice::iterator
864 while( y_itr != y->end() )
865 *y_itr++ += (*d_itr++) * (*x_itr++);
926 if(
QJ_.rows() <
m_ )
956 comp_Cb(
STY_(2,mb,1,mb-1),
STY_.diag(0)(1,mb-1), &
C(2,mb,2,mb) );
1000 x2 = (*x)(mb+1,2*mb);
1012 DVectorSlice::const_iterator
1013 d_itr =
STY_.diag(0).begin(),
1014 y2_itr = y2.begin();
1015 DVectorSlice::iterator
1016 x1_itr = x1.begin();
1017 while( x1_itr != x1.end() )
1018 *x1_itr++ = *y2_itr++ / *d_itr++;
1035 std::copy( x1a.rbegin(), x1a.rend(), x1b.rbegin() );
1036 V_MtV( &x1b,
Lb(), BLAS_Cpp::no_trans, x1b );
1048 V_InvMtV( &x1, J, BLAS_Cpp::no_trans, x1 );
1071 DVectorSlice::const_iterator
1072 d_itr =
STY_.diag(0).begin();
1073 DVectorSlice::iterator
1074 x2_itr = x2.begin();
1075 while( x2_itr != x2.end() )
1076 *x2_itr++ /= *d_itr++;
1083 throw std::logic_error(
"MatrixSymPosDefLBFGS::assert_initialized() : "
1084 "Error, matrix not initialized" );
1116 const size_type p = Db_diag.size();
1118 for( size_type i = 1; i <= p; ++i ) {
1119 for( size_type j = i; j <= p; ++j ) {
1120 value_type &c = (*Cb)(i,j) = 0.0;
1121 for( size_type k = 1; k <= i; ++k ) {
1122 c += Lb(i,k) * Lb(j,k) / Db_diag(k);
void V_invQtV(DVectorSlice *y, const DVectorSlice &x) const
y = inv(Q) * x
const DMatrixSliceTri Lb() const
Strictly lower triangular part of L.
void init_identity(const VectorSpace &space_diag, value_type alpha)
Teuchos::Ordinal size_type
Typedef for the size type of elements that are used by the library.
AbstractLinAlgPack::size_type size_type
void Vp_StMtV(DVectorSlice *vs_lhs, value_type alpha, const MatrixOp &mwo_rhs1, BLAS_Cpp::Transp trans_rhs1, const DVectorSlice &vs_rhs2, value_type beta=1.0)
vs_lhs = alpha * op(mwo_rhs1) * vs_rhs2 + beta * vs_lhs.
bool maintain_original() const
void Vp_StV(DVectorSlice *vs_lhs, value_type alpha, const DVectorSlice &vs_rhs)
vs_lhs += alpha * vs_rhs (BLAS xAXPY)
void secant_update(VectorMutable *s, VectorMutable *y, VectorMutable *Bs)
void initial_setup(size_type m=10, bool maintain_original=true, bool maintain_inverse=true, bool auto_rescaling=false)
Initial setup for the matrix.
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
v_lhs *= alpha
bool original_is_updated_
const DMatrixSliceTriEle tri_ele(const DMatrixSlice &gms, BLAS_Cpp::Uplo uplo)
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
v_lhs = alpha * v_rhs + v_lhs
void V_InvMtV(VectorMutable *v_lhs, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2) const
void update_Q() const
Update Q.
void initialize(value_type alpha, size_type max_size)
This is fine as long as alpha > 0.0.
VectorSliceTmpl< value_type > DVectorSlice
int resize(OrdinalType length_in)
void V_StV(VectorMutable *v_lhs, value_type alpha, const V &V_rhs)
v_lhs = alpha * V_rhs.
std::ostream & output(std::ostream &o, const COOMatrix &coom)
Output stream function for COOMatrix.
MatrixSymPosDefLBFGS(size_type m=10, bool maintain_original=true, bool maintain_inverse=true, bool auto_rescaling=false)
Calls this->initial_setup()
void ger(value_type alpha, const DVectorSlice &vs_rhs1, const DVectorSlice &vs_rhs2, DMatrixSlice *gms_lhs)
void V_StMtV(VectorMutable *v_lhs, value_type alpha, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const V &V_rhs2)
v_lhs = alpha * op(M_rhs1) * V_rhs2.
void delete_update(size_type jd, bool force_refactorization, EEigenValType drop_eigen_val, PivotTolerances pivot_tols)
Should always succeed unless user gives a wrong value for drop_eigen_val.
const DMatrixSliceSym sym(const DMatrixSlice &gms, BLAS_Cpp::Uplo uplo)
const DMatrixSliceTri tri(const DMatrixSlice &gms, BLAS_Cpp::Uplo uplo, BLAS_Cpp::Diag diag)
void init_diagonal(const Vector &diag)
Actually this calls init_identity( diag.space(), diag.norm_inf() ).
size_type num_secant_updates_
void V_InvMtV(DVector *v_lhs, const DMatrixSliceTri &tri_rhs1, BLAS_Cpp::Transp trans_rhs1, const DVectorSlice &vs_rhs2)
void Vp_MtV(VectorMutable *v_lhs, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const V &V_rhs2)
v_lhs += op(M_rhs1) * V_rhs2.
value_type norm_2(const DVectorSlice &vs_rhs)
result = ||vs_rhs||2 (BLAS xNRM2)
void V_mV(VectorMutable *v_lhs, const V &V_rhs)
v_lhs = - V_rhs.
DMatrixSliceSym nonconst_sym(DMatrixSlice gms, BLAS_Cpp::Uplo uplo)
Return a symmetric matrix.
void copy(const f_int &N, const f_dbl_prec *X, const f_int &INCX, f_dbl_prec *Y, const f_int &INCY)
const multi_vec_ptr_t S() const
void V_StV(DVector *v_lhs, value_type alpha, const DVectorSlice &vs_rhs)
v_lhs = alpha * vs_rhs
void syr(value_type alpha, const DVectorSlice &vs_rhs, DMatrixSliceSym *sym_lhs)
DenseLinAlgPack::DMatrixSliceTriEle DMatrixSliceTriEle
const DMatrixSliceTri R() const
const multi_vec_ptr_t Y() const
void potrf(DMatrixSliceTriEle *A)
Calls xPOTRF to compute the cholesky factorization of a symmetric positive definte matrix...
value_type norm_inf(const SparseVectorSlice< T_Ele > &sv_rhs)
result = ||sv_rhs||inf (BLAS IxAMAX)
const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_dbl_prec const LAPACK_C_Decl::f_int const LAPACK_C_Decl::f_dbl_prec LAPACK_C_Decl::f_dbl_prec * C
std::ostream & output(std::ostream &out) const
friend void Mp_StM(MatrixOp *mwo_lhs, value_type alpha, const MatrixOp &M_rhs, BLAS_Cpp::Transp trans_rhs)
bool BFGS_sTy_suff_p_d(const Vector &s, const Vector &y, const value_type *sTy=NULL, std::ostream *out=NULL, const char func_name[]=NULL)
Check that s'*y is sufficiently positive and print the result if it is not.
value_type dot(const Vector &v_rhs1, const Vector &v_rhs2)
result = v_rhs1' * v_rhs2
Inertia inertia() const
Returns (0,0,rows())
int size(OrdinalType length_in)
void assert_initialized() const
DenseLinAlgPack::VectorSliceTmpl< value_type > DVectorSlice
void Vt_S(DVectorSlice *vs_lhs, value_type alpha)
vs_lhs *= alpha (BLAS xSCAL) (*** Note that alpha == 0.0 is handeled as vs_lhs = 0.0)
void Vp_StMtV(VectorMutable *v_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2, value_type beta) const
void V_MtV(VectorMutable *v_lhs, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const V &V_rhs2)
v_lhs = op(M_rhs1) * V_rhs2.
AbstractLinAlgPack::value_type value_type
DenseLinAlgPack::DMatrixSliceTri DMatrixSliceTri
void Mp_StM(DMatrixSliceTriEle *tri_lhs, value_type alpha, const DMatrixSliceTriEle &tri_rhs)
tri_lhs += alpha * tri_rhs (BLAS xAXPY)
void Vp_MtV_assert_sizes(size_type v_lhs_size, size_type m_rhs1_rows, size_type m_rhs1_cols, BLAS_Cpp::Transp trans_rhs1, size_type v_rhs2_size)
v_lhs += op(m_rhs1) * v_rhs2
FortranTypes::f_dbl_prec value_type
Typedef for the value type of elements that is used for the library.
void V_mV(DVector *v_lhs, const DVectorSlice &vs_rhs)
v_lhs = - vs_rhs
void Vp_StMtV(DVectorSlice *vs_lhs, value_type alpha, const DMatrixSlice &gms_rhs1, BLAS_Cpp::Transp trans_rhs1, const DVectorSlice &vs_rhs2, value_type beta=1.0)
vs_lhs = alpha * op(gms_rhs1) * vs_rhs2 + beta * vs_lhs (BLAS xGEMV)
bool maintain_inverse() const
value_type norm_inf(const DVectorSlice &vs_rhs)
result = ||vs_rhs||infinity (BLAS IxAMAX)
MatrixOp & operator=(const MatrixOp &mwo)
DenseLinAlgPack::DMatrixSlice DMatrixSlice
DenseLinAlgPack::DMatrixSliceSym DMatrixSliceSym
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
void augment_update(const DVectorSlice *t, value_type alpha, bool force_refactorization, EEigenValType add_eigen_val, PivotTolerances pivot_tols)
Augment the matrix to add a row and column.
value_type dot(const DVectorSlice &vs_rhs1, const DVectorSlice &vs_rhs2)
result = vs_rhs1' * vs_rhs2 (BLAS xDOT)
void set_uninitialized()
Will set rows() == 0.
size_type max_size() const
void Vp_V(VectorMutable *v_lhs, const V &V_rhs)
v_lhs += V_rhs.
void Vp_DtV(DVectorSlice *y, const DVectorSlice &x) const
y += D * x