10 #ifndef ANASAZI_GENERALIZED_DAVIDSON_HPP
11 #define ANASAZI_GENERALIZED_DAVIDSON_HPP
26 #include "Teuchos_FancyOStream.hpp"
44 template <
class ScalarType,
class MV>
77 std::vector< Value<ScalarType> >
eVals;
80 BV(Teuchos::null),
VAV(Teuchos::null),
81 VBV(Teuchos::null),
S(Teuchos::null),
82 T(Teuchos::null),
Q(Teuchos::null),
83 Z(Teuchos::null),
eVals(0) {}
108 template <
class ScalarType,
class MV,
class OP>
184 if( !d_ritzVectorsValid )
185 computeRitzVectors();
199 if( !d_ritzIndexValid )
211 return d_expansionIndices;
222 std::vector<MagnitudeType>
getResNorms(
int numWanted);
275 void setSize(
int blockSize,
int maxSubDim);
314 void expandSearchSpace();
317 void applyOperators();
320 void updateProjections();
323 void solveProjectedEigenproblem();
334 void sortValues( std::vector<MagnitudeType> &realParts,
335 std::vector<MagnitudeType> &imagParts,
336 std::vector<int> &permVec,
340 void computeResidual();
343 void computeRitzIndex();
346 void computeRitzVectors();
359 int d_maxSubspaceDim;
362 std::string d_initType;
364 bool d_relativeConvergence;
373 std::vector< Value<ScalarType> > d_eigenvalues;
377 std::vector<MagnitudeType> d_resNorms;
396 std::vector<MagnitudeType> d_alphar;
397 std::vector<MagnitudeType> d_alphai;
398 std::vector<MagnitudeType> d_betar;
399 std::vector<int> d_ritzIndex;
400 std::vector<int> d_convergedIndices;
401 std::vector<int> d_expansionIndices;
414 std::string d_testSpace;
422 bool d_ritzIndexValid;
423 bool d_ritzVectorsValid;
430 template <
class MagnitudeType,
class MV,
class OP>
431 class GeneralizedDavidson<std::complex<MagnitudeType>,MV,OP>
435 typedef std::complex<MagnitudeType> ScalarType;
437 const RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
438 const RCP<SortManager<MagnitudeType> > &sortman,
439 const RCP<OutputManager<ScalarType> > &outputman,
440 const RCP<StatusTest<ScalarType,MV,OP> > &tester,
441 const RCP<OrthoManager<ScalarType,MV> > &orthoman,
445 MagnitudeType::this_class_is_missing_a_specialization();
456 template <
class ScalarType,
class MV,
class OP>
475 std::invalid_argument,
"Either A or Operator must be non-null on Eigenproblem");
476 d_A = problem->getA()!=Teuchos::null ? problem->getA() : problem->getOperator();
477 d_B = problem->getM();
478 d_P = problem->getPrec();
480 d_outputMan = outputman;
482 d_orthoMan = orthoman;
485 d_NEV = d_problem->getNEV();
486 d_initType = d_pl.get<std::string>(
"Initial Guess",
"Random");
487 d_numToPrint = d_pl.get<
int>(
"Print Number of Ritz Values",-1);
488 d_useLeading = d_pl.get<
bool>(
"Use Leading Vectors",
false);
490 if( d_B != Teuchos::null )
495 if( d_P != Teuchos::null )
500 d_testSpace = d_pl.get<std::string>(
"Test Space",
"V");
502 "Anasazi::GeneralizedDavidson: Test Space must be V, AV, or BV" );
503 TEUCHOS_TEST_FOR_EXCEPTION( d_testSpace==
"V" ?
false : !d_haveB, std::invalid_argument,
504 "Anasazi::GeneralizedDavidson: Test Space must be V for standard eigenvalue problem" );
507 int blockSize = d_pl.get<
int>(
"Block Size",1);
508 int maxSubDim = d_pl.get<
int>(
"Maximum Subspace Dimension",3*d_NEV*blockSize);
510 d_maxSubspaceDim = -1;
511 setSize( blockSize, maxSubDim );
512 d_relativeConvergence = d_pl.get<
bool>(
"Relative Convergence Tolerance",
false);
515 TEUCHOS_TEST_FOR_EXCEPTION( d_blockSize <= 0, std::invalid_argument,
"Block size must be positive");
516 TEUCHOS_TEST_FOR_EXCEPTION( d_maxSubspaceDim <= 0, std::invalid_argument,
"Maximum Subspace Dimension must be positive" );
517 TEUCHOS_TEST_FOR_EXCEPTION( d_problem->getNEV()+2 > pl.
get<
int>(
"Maximum Subspace Dimension"),
518 std::invalid_argument,
"Maximum Subspace Dimension must be strictly greater than NEV");
519 TEUCHOS_TEST_FOR_EXCEPTION( d_maxSubspaceDim > MVT::GetGlobalLength(*problem->getInitVec()),
520 std::invalid_argument,
"Maximum Subspace Dimension cannot exceed problem size");
526 d_ritzIndexValid =
false;
527 d_ritzVectorsValid =
false;
534 template <
class ScalarType,
class MV,
class OP>
540 d_outputMan->stream(
Warnings) <<
"WARNING: GeneralizedDavidson::iterate called without first calling initialize" << std::endl;
541 d_outputMan->stream(
Warnings) <<
" Default initialization will be performed" << std::endl;
546 if( d_outputMan->isVerbosity(
Debug) )
548 currentStatus( d_outputMan->stream(
Debug) );
555 while( d_tester->getStatus() !=
Passed && d_curDim+d_expansionSize <= d_maxSubspaceDim )
565 solveProjectedEigenproblem();
570 int numToSort = std::max(d_blockSize,d_NEV);
571 numToSort = std::min(numToSort,d_curDim);
572 sortProblem( numToSort );
577 if( d_outputMan->isVerbosity(
Debug) )
579 currentStatus( d_outputMan->stream(
Debug) );
591 template <
class ScalarType,
class MV,
class OP>
605 state.
eVals = getRitzValues();
612 template <
class ScalarType,
class MV,
class OP>
615 setSize(blockSize,d_maxSubspaceDim);
621 template <
class ScalarType,
class MV,
class OP>
624 if( blockSize != d_blockSize || maxSubDim != d_maxSubspaceDim )
626 d_blockSize = blockSize;
627 d_maxSubspaceDim = maxSubDim;
628 d_initialized =
false;
630 d_outputMan->stream(
Debug) <<
" >> Anasazi::GeneralizedDavidson: Allocating eigenproblem"
631 <<
" state with block size of " << d_blockSize
632 <<
" and maximum subspace dimension of " << d_maxSubspaceDim << std::endl;
635 d_alphar.resize(d_maxSubspaceDim);
636 d_alphai.resize(d_maxSubspaceDim);
637 d_betar.resize(d_maxSubspaceDim);
640 int msd = d_maxSubspaceDim;
646 d_V = MVT::Clone(*initVec, msd);
647 d_AV = MVT::Clone(*initVec, msd);
658 d_BV = MVT::Clone(*initVec, msd);
671 d_R = MVT::Clone(*initVec,std::max(d_blockSize,d_NEV)+1);
672 d_ritzVecSpace = MVT::Clone(*initVec,std::max(d_blockSize,d_NEV)+1);
687 template <
class ScalarType,
class MV,
class OP>
692 d_curDim = (state.
curDim > 0 ? state.
curDim : d_blockSize );
694 d_outputMan->stream(
Debug) <<
" >> Anasazi::GeneralizedDavidson: Initializing state"
695 <<
" with subspace dimension " << d_curDim << std::endl;
698 std::vector<int> initInds(d_curDim);
699 for(
int i=0; i<d_curDim; ++i )
703 RCP<MV> V1 = MVT::CloneViewNonConst(*d_V,initInds);
706 bool reset_V =
false;;
707 if( state.
curDim > 0 && state.
V != Teuchos::null && MVT::GetNumberVecs(*state.
V) >= d_curDim )
710 MVT::SetBlock(*state.
V,initInds,*V1);
714 else if( MVT::GetNumberVecs(*d_problem->getInitVec()) < d_blockSize || d_initType ==
"Random" )
722 RCP<const MV> initVec = MVT::CloneView(*d_problem->getInitVec(),initInds);
723 MVT::SetBlock(*initVec,initInds,*V1);
730 int rank = d_orthoMan->projectAndNormalize( *V1, d_auxVecs );
732 "Anasazi::GeneralizedDavidson::initialize(): Error generating initial orthonormal basis" );
735 if( d_outputMan->isVerbosity(
Debug) )
737 d_outputMan->stream(
Debug) <<
" >> Anasazi::GeneralizedDavidson: Error in V^T V == I: "
738 << d_orthoMan->orthonormError( *V1 ) << std::endl;
742 RCP<MV> AV1 = MVT::CloneViewNonConst(*d_AV,initInds);
746 if( !reset_V && state.
AV != Teuchos::null && MVT::GetNumberVecs(*state.
AV) >= d_curDim )
748 if( state.
AV != d_AV )
749 MVT::SetBlock(*state.
AV,initInds,*AV1);
754 OPT::Apply( *d_A, *V1, *AV1 );
755 d_opApplies += MVT::GetNumberVecs( *V1 );
762 if( !reset_V && state.
VAV != Teuchos::null && state.
VAV->numRows() >= d_curDim && state.
VAV->numCols() >= d_curDim )
764 if( state.
VAV != d_VAV )
773 if( d_testSpace ==
"V" )
775 MVT::MvTransMv( ST::one(), *V1, *AV1, VAV1 );
777 else if( d_testSpace ==
"AV" )
779 MVT::MvTransMv( ST::one(), *AV1, *AV1, VAV1 );
781 else if( d_testSpace ==
"BV" )
783 RCP<MV> BV1 = MVT::CloneViewNonConst(*d_BV,initInds);
784 MVT::MvTransMv( ST::one(), *BV1, *AV1, VAV1 );
791 RCP<MV> BV1 = MVT::CloneViewNonConst(*d_BV,initInds);
795 if( !reset_V && state.
BV != Teuchos::null && MVT::GetNumberVecs(*state.
BV) >= d_curDim )
797 if( state.
BV != d_BV )
798 MVT::SetBlock(*state.
BV,initInds,*BV1);
803 OPT::Apply( *d_B, *V1, *BV1 );
810 if( !reset_V && state.
VBV != Teuchos::null && state.
VBV->numRows() >= d_curDim && state.
VBV->numCols() >= d_curDim )
812 if( state.
VBV != d_VBV )
821 if( d_testSpace ==
"V" )
823 MVT::MvTransMv( ST::one(), *V1, *BV1, VBV1 );
825 else if( d_testSpace ==
"AV" )
827 MVT::MvTransMv( ST::one(), *AV1, *BV1, VBV1 );
829 else if( d_testSpace ==
"BV" )
831 MVT::MvTransMv( ST::one(), *BV1, *BV1, VBV1 );
837 solveProjectedEigenproblem();
840 int numToSort = std::max(d_blockSize,d_NEV);
841 numToSort = std::min(numToSort,d_curDim);
842 sortProblem( numToSort );
848 d_initialized =
true;
854 template <
class ScalarType,
class MV,
class OP>
864 template <
class ScalarType,
class MV,
class OP>
865 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
868 return getResNorms(d_residualSize);
874 template <
class ScalarType,
class MV,
class OP>
875 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
878 std::vector<int> resIndices(numWanted);
879 for(
int i=0; i<numWanted; ++i )
882 RCP<const MV> R_checked = MVT::CloneView( *d_R, resIndices );
884 std::vector<MagnitudeType> resNorms;
885 d_orthoMan->norm( *R_checked, resNorms );
893 template <
class ScalarType,
class MV,
class OP>
896 std::vector< Value<ScalarType> > ritzValues;
897 for(
int ival=0; ival<d_curDim; ++ival )
900 thisVal.
realpart = d_alphar[ival] / d_betar[ival];
901 if( d_betar[ival] != MT::zero() )
902 thisVal.
imagpart = d_alphai[ival] / d_betar[ival];
906 ritzValues.push_back( thisVal );
921 template <
class ScalarType,
class MV,
class OP>
930 for( arrItr=auxVecs.
begin(); arrItr!=auxVecs.
end(); ++arrItr )
932 numAuxVecs += MVT::GetNumberVecs( *(*arrItr) );
935 d_initialized =
false;
941 template <
class ScalarType,
class MV,
class OP>
945 std::vector<MagnitudeType> realRitz(d_curDim), imagRitz(d_curDim);
946 std::vector< Value<ScalarType> > ritzVals = getRitzValues();
947 for(
int i=0; i<d_curDim; ++i )
949 realRitz[i] = ritzVals[i].realpart;
950 imagRitz[i] = ritzVals[i].imagpart;
953 std::vector<int> permVec;
954 sortValues( realRitz, imagRitz, permVec, d_curDim );
956 std::vector<int> sel(d_curDim,0);
957 for(
int ii=0; ii<numWanted; ++ii )
958 sel[ permVec[ii] ]=1;
965 int work_size=10*d_maxSubspaceDim+16;
966 std::vector<ScalarType> work(work_size);
973 lapack.
TGSEN( ijob, wantq, wantz, &sel[0], d_curDim, d_S->values(), d_S->stride(), d_T->values(), d_T->stride(),
974 &d_alphar[0], &d_alphai[0], &d_betar[0], d_Q->values(), d_Q->stride(), d_Z->values(), d_Z->stride(),
975 &sdim, 0, 0, 0, &work[0], work_size, &iwork, iwork_size, &info );
977 d_ritzIndexValid =
false;
978 d_ritzVectorsValid =
false;
980 std::stringstream ss;
981 ss <<
"Anasazi::GeneralizedDavidson: TGSEN returned error code " << info << std::endl;
988 d_outputMan->stream(
Warnings) <<
"WARNING: " << ss.str() << std::endl;
989 d_outputMan->stream(
Warnings) <<
" Problem may not be correctly sorted" << std::endl;
993 char getCondNum =
'N';
996 int work_size = d_curDim;
997 std::vector<ScalarType> work(work_size);
1003 lapack.
TRSEN (getCondNum, getQ, &sel[0], d_curDim, d_S->values (),
1004 d_S->stride (), d_Z->values (), d_Z->stride (),
1005 &d_alphar[0], &d_alphai[0], &subDim, 0, 0, &work[0],
1006 work_size, &iwork, iwork_size, &info );
1008 std::fill( d_betar.begin(), d_betar.end(), ST::one() );
1010 d_ritzIndexValid =
false;
1011 d_ritzVectorsValid =
false;
1014 info < 0, std::runtime_error,
"Anasazi::GeneralizedDavidson::"
1015 "sortProblem: LAPACK routine TRSEN returned error code INFO = "
1016 << info <<
" < 0. This indicates that argument " << -info
1017 <<
" (counting starts with one) of TRSEN had an illegal value.");
1024 info == 1, std::runtime_error,
"Anasazi::GeneralizedDavidson::"
1025 "sortProblem: LAPACK routine TRSEN returned error code INFO = 1. "
1026 "This indicates that the reordering failed because some eigenvalues "
1027 "are too close to separate (the problem is very ill-conditioned).");
1030 info > 1, std::logic_error,
"Anasazi::GeneralizedDavidson::"
1031 "sortProblem: LAPACK routine TRSEN returned error code INFO = "
1032 << info <<
" > 1. This should not be possible. It may indicate an "
1033 "error either in LAPACK itself, or in Teuchos' LAPACK wrapper.");
1045 template <
class ScalarType,
class MV,
class OP>
1050 std::vector<int> newIndices(d_expansionSize);
1051 for(
int i=0; i<d_expansionSize; ++i )
1053 newIndices[i] = d_curDim+i;
1057 std::vector<int> curIndices(d_curDim);
1058 for(
int i=0; i<d_curDim; ++i )
1062 RCP<MV> V_new = MVT::CloneViewNonConst( *d_V, newIndices);
1064 RCP<const MV> R_active = MVT::CloneView( *d_R, d_expansionIndices);
1069 OPT::Apply( *d_P, *R_active, *V_new );
1074 MVT::SetBlock( *R_active, newIndices, *d_V );
1080 int rank = d_orthoMan->projectAndNormalize(*V_new,against);
1082 if( d_outputMan->isVerbosity(
Debug) )
1084 std::vector<int> allIndices(d_curDim+d_expansionSize);
1085 for(
int i=0; i<d_curDim+d_expansionSize; ++i )
1090 d_outputMan->stream(
Debug) <<
" >> Anasazi::GeneralizedDavidson: Error in V^T V == I: "
1091 << d_orthoMan->orthonormError( *V_all ) << std::endl;
1095 "Anasazi::GeneralizedDavidson::ExpandSearchSpace(): Orthonormalization of new vectors failed" );
1102 template <
class ScalarType,
class MV,
class OP>
1103 void GeneralizedDavidson<ScalarType,MV,OP>::applyOperators()
1106 std::vector<int> newIndices(d_expansionSize);
1107 for(
int i=0; i<d_expansionSize; ++i )
1108 newIndices[i] = d_curDim+i;
1112 RCP<MV> AV_new = MVT::CloneViewNonConst( *d_AV, newIndices );
1115 OPT::Apply( *d_A, *V_new, *AV_new );
1116 d_opApplies += MVT::GetNumberVecs( *V_new );
1121 RCP<MV> BV_new = MVT::CloneViewNonConst( *d_BV, newIndices );
1122 OPT::Apply( *d_B, *V_new, *BV_new );
1129 template <
class ScalarType,
class MV,
class OP>
1130 void GeneralizedDavidson<ScalarType,MV,OP>::updateProjections()
1133 std::vector<int> newIndices(d_expansionSize);
1134 for(
int i=0; i<d_expansionSize; ++i )
1135 newIndices[i] = d_curDim+i;
1137 std::vector<int> curIndices(d_curDim);
1138 for(
int i=0; i<d_curDim; ++i )
1141 std::vector<int> allIndices(d_curDim+d_expansionSize);
1142 for(
int i=0; i<d_curDim+d_expansionSize; ++i )
1147 if( d_testSpace ==
"V" )
1149 W_new = MVT::CloneView(*d_V, newIndices );
1150 W_all = MVT::CloneView(*d_V, allIndices );
1152 else if( d_testSpace ==
"AV" )
1154 W_new = MVT::CloneView(*d_AV, newIndices );
1155 W_all = MVT::CloneView(*d_AV, allIndices );
1157 else if( d_testSpace ==
"BV" )
1159 W_new = MVT::CloneView(*d_BV, newIndices );
1160 W_all = MVT::CloneView(*d_BV, allIndices );
1165 RCP<const MV> AV_current = MVT::CloneView(*d_AV, curIndices);
1169 MVT::MvTransMv( ST::one(), *W_new, *AV_current, VAV_lastrow );
1173 MVT::MvTransMv( ST::one(), *W_all, *AV_new, VAV_lastcol );
1179 RCP<const MV> BV_current = MVT::CloneView(*d_BV, curIndices);
1183 MVT::MvTransMv( ST::one(), *W_new, *BV_current, VBV_lastrow );
1187 MVT::MvTransMv( ST::one(), *W_all, *BV_new, VBV_lastcol );
1191 d_curDim += d_expansionSize;
1193 d_ritzIndexValid =
false;
1194 d_ritzVectorsValid =
false;
1200 template <
class ScalarType,
class MV,
class OP>
1201 void GeneralizedDavidson<ScalarType,MV,OP>::solveProjectedEigenproblem()
1208 d_S->assign(*d_VAV);
1209 d_T->assign(*d_VBV);
1212 char leftVecs =
'V';
1213 char rightVecs =
'V';
1214 char sortVals =
'N';
1221 std::vector<ScalarType> work(1);
1222 lapack.
GGES( leftVecs, rightVecs, sortVals, NULL, d_curDim, d_S->values(), d_S->stride(),
1223 d_T->values(), d_T->stride(), &sdim, &d_alphar[0], &d_alphai[0], &d_betar[0],
1224 d_Q->values(), d_Q->stride(), d_Z->values(), d_Z->stride(), &work[0], work_size, 0, &info );
1226 work_size = work[0];
1227 work.resize(work_size);
1228 lapack.
GGES( leftVecs, rightVecs, sortVals, NULL, d_curDim, d_S->values(), d_S->stride(),
1229 d_T->values(), d_T->stride(), &sdim, &d_alphar[0], &d_alphai[0], &d_betar[0],
1230 d_Q->values(), d_Q->stride(), d_Z->values(), d_Z->stride(), &work[0], work_size, 0, &info );
1232 d_ritzIndexValid =
false;
1233 d_ritzVectorsValid =
false;
1235 std::stringstream ss;
1236 ss <<
"Anasazi::GeneralizedDavidson: GGES returned error code " << info << std::endl;
1243 d_S->assign(*d_VAV);
1248 int work_size = 3*d_curDim;
1249 std::vector<ScalarType> work(work_size);
1253 lapack.
GEES( vecs, d_curDim, d_S->values(), d_S->stride(), &sdim, &d_alphar[0], &d_alphai[0],
1254 d_Z->values(), d_Z->stride(), &work[0], work_size, 0, 0, &info);
1256 std::fill( d_betar.begin(), d_betar.end(), ST::one() );
1258 d_ritzIndexValid =
false;
1259 d_ritzVectorsValid =
false;
1261 std::stringstream ss;
1262 ss <<
"Anasazi::GeneralizedDavidson: GEES returned error code " << info << std::endl;
1275 template <
class ScalarType,
class MV,
class OP>
1276 void GeneralizedDavidson<ScalarType,MV,OP>::computeRitzIndex()
1278 if( d_ritzIndexValid )
1281 d_ritzIndex.resize( d_curDim );
1283 while( i < d_curDim )
1285 if( d_alphai[i] == ST::zero() )
1293 d_ritzIndex[i+1] = -1;
1297 d_ritzIndexValid =
true;
1308 template <
class ScalarType,
class MV,
class OP>
1309 void GeneralizedDavidson<ScalarType,MV,OP>::computeRitzVectors()
1311 if( d_ritzVectorsValid )
1318 std::vector<int> checkedIndices(d_residualSize);
1319 for(
int ii=0; ii<d_residualSize; ++ii )
1320 checkedIndices[ii] = ii;
1324 computeProjectedEigenvectors( X );
1330 d_ritzVecs = MVT::CloneViewNonConst( *d_ritzVecSpace, checkedIndices );
1332 std::vector<int> curIndices(d_curDim);
1333 for(
int i=0; i<d_curDim; ++i )
1336 RCP<const MV> V_current = MVT::CloneView( *d_V, curIndices );
1339 MVT::MvTimesMatAddMv(ST::one(),*V_current,X_wanted,ST::zero(),*d_ritzVecs);
1342 std::vector<MagnitudeType> scale(d_residualSize);
1343 MVT::MvNorm( *d_ritzVecs, scale );
1345 for(
int i=0; i<d_residualSize; ++i )
1347 if( d_ritzIndex[i] == 0 )
1349 scale[i] = 1.0/scale[i];
1351 else if( d_ritzIndex[i] == 1 )
1353 MagnitudeType nrm = lapack.
LAPY2(scale[i],scale[i+1]);
1355 scale[i+1] = 1.0/nrm;
1358 MVT::MvScale( *d_ritzVecs, scale );
1360 d_ritzVectorsValid =
true;
1367 template <
class ScalarType,
class MV,
class OP>
1368 void GeneralizedDavidson<ScalarType,MV,OP>::sortValues( std::vector<MagnitudeType> &realParts,
1369 std::vector<MagnitudeType> &imagParts,
1370 std::vector<int> &permVec,
1376 "Anasazi::GeneralizedDavidson::SortValues: Number of requested sorted values greater than vector length." );
1378 "Anasazi::GeneralizedDavidson::SortValues: Number of requested sorted values greater than vector length." );
1382 d_sortMan->sort( realParts, imagParts, rcpPermVec, N );
1384 d_ritzIndexValid =
false;
1385 d_ritzVectorsValid =
false;
1399 template <
class ScalarType,
class MV,
class OP>
1400 void GeneralizedDavidson<ScalarType,MV,OP>::computeProjectedEigenvectors(
1410 char whichVecs =
'R';
1412 int work_size = 6*d_maxSubspaceDim;
1413 std::vector<ScalarType> work(work_size,ST::zero());
1418 lapack.
TGEVC( whichVecs, howMany, 0, N, S.values(), S.stride(), T.values(), T.stride(),
1419 VL.values(), VL.stride(), X.
values(), X.
stride(), N, &M, &work[0], &info );
1421 std::stringstream ss;
1422 ss <<
"Anasazi::GeneralizedDavidson: TGEVC returned error code " << info << std::endl;
1430 char whichVecs =
'R';
1433 std::vector<ScalarType> work(3*N);
1439 lapack.
TREVC( whichVecs, howMany, &sel, N, S.values(), S.stride(), VL.values(), VL.stride(),
1442 std::stringstream ss;
1443 ss <<
"Anasazi::GeneralizedDavidson: TREVC returned error code " << info << std::endl;
1451 template <
class ScalarType,
class MV,
class OP>
1452 void GeneralizedDavidson<ScalarType,MV,OP>::scaleEigenvectors(
1461 "Anasazi::GeneralizedDavidson::ScaleEigenvectors: Matrix size exceeds current dimension");
1463 "Anasazi::GeneralizedDavidson::ScaleEigenvectors: Matrix size exceeds current dimension");
1465 "Anasazi::GeneralizedDavidson::ScaleEigenvectors: number of rows in Xalpha does not match X");
1467 "Anasazi::GeneralizedDavidson::ScaleEigenvectors: number of cols in Xalpha does not match X");
1469 "Anasazi::GeneralizedDavidson::ScaleEigenvectors: number of rows in Xbeta does not match X");
1471 "Anasazi::GeneralizedDavidson::ScaleEigenvectors: number of cols in Xbeta does not match X");
1480 for(
int i=0; i<Nc; ++i )
1482 if( d_ritzIndex[i] == 0 )
1484 Alpha(i,i) = d_alphar[i];
1485 Beta(i,i) = d_betar[i];
1487 else if( d_ritzIndex[i] == 1 )
1489 Alpha(i,i) = d_alphar[i];
1490 Alpha(i,i+1) = d_alphai[i];
1491 Beta(i,i) = d_betar[i];
1495 Alpha(i,i-1) = d_alphai[i];
1496 Alpha(i,i) = d_alphar[i];
1497 Beta(i,i) = d_betar[i];
1505 std::stringstream astream;
1506 astream <<
"GeneralizedDavidson::ScaleEigenvectors: multiply returned error code " << err;
1511 std::stringstream bstream;
1512 bstream <<
"GeneralizedDavidson::ScaleEigenvectors: multiply returned error code " << err;
1519 template <
class ScalarType,
class MV,
class OP>
1520 void GeneralizedDavidson<ScalarType,MV,OP>::computeResidual()
1525 d_residualSize = std::max( d_blockSize, d_NEV );
1526 if( d_curDim < d_residualSize )
1528 d_residualSize = d_curDim;
1530 else if( d_ritzIndex[d_residualSize-1] == 1 )
1536 std::vector<int> residualIndices(d_residualSize);
1537 for(
int i=0; i<d_residualSize; ++i )
1538 residualIndices[i] = i;
1544 computeProjectedEigenvectors( X );
1554 scaleEigenvectors( X_wanted, X_alpha, X_beta );
1557 RCP<MV> R_active = MVT::CloneViewNonConst( *d_R, residualIndices );
1560 std::vector<int> activeIndices(d_curDim);
1561 for(
int i=0; i<d_curDim; ++i )
1565 RCP<const MV> AV_active = MVT::CloneView( *d_AV, activeIndices );
1566 MVT::MvTimesMatAddMv(ST::one(),*AV_active, X_beta, ST::zero(),*R_active);
1570 RCP<const MV> BV_active = MVT::CloneView( *d_BV, activeIndices );
1571 MVT::MvTimesMatAddMv(ST::one(),*BV_active, X_alpha,-ST::one(), *R_active);
1575 RCP<const MV> V_active = MVT::CloneView( *d_V, activeIndices );
1576 MVT::MvTimesMatAddMv(ST::one(),*V_active, X_alpha,-ST::one(), *R_active);
1593 std::vector<MagnitudeType> resScaling(d_residualSize);
1594 for(
int icol=0; icol<d_residualSize; ++icol )
1596 if( d_ritzIndex[icol] == 0 )
1598 MagnitudeType Xnrm = blas.
NRM2( d_curDim, X_wanted[icol], 1);
1599 MagnitudeType ABscaling = d_relativeConvergence ? d_alphar[icol] : d_betar[icol];
1600 resScaling[icol] = MT::one() / (Xnrm * ABscaling);
1602 else if( d_ritzIndex[icol] == 1 )
1604 MagnitudeType Xnrm1 = blas.
NRM2( d_curDim, X_wanted[icol], 1 );
1605 MagnitudeType Xnrm2 = blas.
NRM2( d_curDim, X_wanted[icol+1], 1 );
1606 MagnitudeType Xnrm = lapack.
LAPY2(Xnrm1,Xnrm2);
1607 MagnitudeType ABscaling = d_relativeConvergence ? lapack.
LAPY2(d_alphar[icol],d_alphai[icol])
1609 resScaling[icol] = MT::one() / (Xnrm * ABscaling);
1610 resScaling[icol+1] = MT::one() / (Xnrm * ABscaling);
1613 MVT::MvScale( *R_active, resScaling );
1616 d_resNorms.resize(d_residualSize);
1617 MVT::MvNorm(*R_active,d_resNorms);
1624 for(
int i=0; i<d_residualSize; ++i )
1626 if( d_ritzIndex[i] == 1 )
1628 MagnitudeType nrm = lapack.
LAPY2(d_resNorms[i],d_resNorms[i+1]);
1629 d_resNorms[i] = nrm;
1630 d_resNorms[i+1] = nrm;
1635 d_tester->checkStatus(
this);
1638 if( d_useLeading || d_blockSize >= d_NEV )
1640 d_expansionSize=d_blockSize;
1641 if( d_ritzIndex[d_blockSize-1]==1 )
1644 d_expansionIndices.resize(d_expansionSize);
1645 for(
int i=0; i<d_expansionSize; ++i )
1646 d_expansionIndices[i] = i;
1650 std::vector<int> convergedVectors = d_tester->whichVecs();
1654 for( startVec=0; startVec<d_residualSize; ++startVec )
1656 if( std::find(convergedVectors.begin(),convergedVectors.end(),startVec)==convergedVectors.end() )
1662 int endVec = startVec + d_blockSize - 1;
1663 if( endVec > (d_residualSize-1) )
1665 endVec = d_residualSize-1;
1666 startVec = d_residualSize-d_blockSize;
1670 if( d_ritzIndex[startVec]==-1 )
1676 if( d_ritzIndex[endVec]==1 )
1679 d_expansionSize = 1+endVec-startVec;
1680 d_expansionIndices.resize(d_expansionSize);
1681 for(
int i=0; i<d_expansionSize; ++i )
1682 d_expansionIndices[i] = startVec+i;
1689 template <
class ScalarType,
class MV,
class OP>
1694 myout.setf(std::ios::scientific, std::ios::floatfield);
1697 myout <<
"================================================================================" << endl;
1699 myout <<
" GeneralizedDavidson Solver Solver Status" << endl;
1701 myout <<
"The solver is "<<(d_initialized ?
"initialized." :
"not initialized.") << endl;
1702 myout <<
"The number of iterations performed is " << d_iteration << endl;
1703 myout <<
"The number of operator applies performed is " << d_opApplies << endl;
1704 myout <<
"The block size is " << d_expansionSize << endl;
1705 myout <<
"The current basis size is " << d_curDim << endl;
1706 myout <<
"The number of requested eigenvalues is " << d_NEV << endl;
1707 myout <<
"The number of converged values is " << d_tester->howMany() << endl;
1710 myout.setf(std::ios_base::right, std::ios_base::adjustfield);
1714 myout <<
"CURRENT RITZ VALUES" << endl;
1716 myout << std::setw(24) <<
"Ritz Value"
1717 << std::setw(30) <<
"Residual Norm" << endl;
1718 myout <<
"--------------------------------------------------------------------------------" << endl;
1719 if( d_residualSize > 0 )
1721 std::vector<MagnitudeType> realRitz(d_curDim), imagRitz(d_curDim);
1722 std::vector< Value<ScalarType> > ritzVals = getRitzValues();
1723 for(
int i=0; i<d_curDim; ++i )
1725 realRitz[i] = ritzVals[i].realpart;
1726 imagRitz[i] = ritzVals[i].imagpart;
1728 std::vector<int> permvec;
1729 sortValues( realRitz, imagRitz, permvec, d_curDim );
1731 int numToPrint = std::max( d_numToPrint, d_NEV );
1732 numToPrint = std::min( d_curDim, numToPrint );
1739 if( d_ritzIndex[permvec[numToPrint-1]] != 0 )
1743 while( i<numToPrint )
1745 if( imagRitz[i] == ST::zero() )
1747 myout << std::setw(15) << realRitz[i];
1748 myout <<
" + i" << std::setw(15) << ST::magnitude( imagRitz[i] );
1749 if( i < d_residualSize )
1750 myout << std::setw(20) << d_resNorms[permvec[i]] << endl;
1752 myout <<
" Not Computed" << endl;
1759 myout << std::setw(15) << realRitz[i];
1760 myout <<
" + i" << std::setw(15) << ST::magnitude( imagRitz[i] );
1761 if( i < d_residualSize )
1762 myout << std::setw(20) << d_resNorms[permvec[i]] << endl;
1764 myout <<
" Not Computed" << endl;
1767 myout << std::setw(15) << realRitz[i];
1768 myout <<
" - i" << std::setw(15) << ST::magnitude( imagRitz[i] );
1769 if( i < d_residualSize )
1770 myout << std::setw(20) << d_resNorms[permvec[i]] << endl;
1772 myout <<
" Not Computed" << endl;
1780 myout << std::setw(20) <<
"[ NONE COMPUTED ]" << endl;
1784 myout <<
"================================================================================" << endl;
1790 #endif // ANASAZI_GENERALIZED_DAVIDSON_HPP
ScalarType * values() const
void sortProblem(int numWanted)
void TGEVC(const char &SIDE, const char &HOWMNY, const OrdinalType *SELECT, const OrdinalType &n, const ScalarType *S, const OrdinalType &lds, const ScalarType *P, const OrdinalType &ldp, ScalarType *VL, const OrdinalType &ldvl, ScalarType *VR, const OrdinalType &ldvr, const OrdinalType &mm, OrdinalType *M, ScalarType *WORK, OrdinalType *info) const
Teuchos::Array< RCP< const MV > > getAuxVecs() const
Get the auxilliary vectors.
void setStatusTest(RCP< StatusTest< ScalarType, MV, OP > > tester)
Set status test.
RCP< MV > V
Orthonormal basis for search subspace.
RCP< MV > AV
Image of V under A.
std::vector< MagnitudeType > getRitzRes2Norms()
Get the current Ritz residual norms (2-norm)
Teuchos::ScalarTraits< ScalarType >::magnitudeType imagpart
The imaginary component of the eigenvalue.
std::vector< int > getBlockIndex() const
Get indices of current block.
This class defines the interface required by an eigensolver and status test class to compute solution...
Solves eigenvalue problem using generalized Davidson method.
std::vector< Value< ScalarType > > getRitzValues()
Get the current Ritz values.
T & get(const std::string &name, T def_value)
RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > T
Right quasi upper triangular matrix from QZ decomposition of (VAV,VBV)
int multiply(ETransp transa, ETransp transb, ScalarType alpha, const SerialDenseMatrix< OrdinalType, ScalarType > &A, const SerialDenseMatrix< OrdinalType, ScalarType > &B, ScalarType beta)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Virtual base class which defines basic traits for the operator type.
GeneralizedDavidsonState< ScalarType, MV > getState()
Get the current state of the eigensolver.
RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > VAV
Projection of A onto V.
int getMaxSubspaceDim() const
Get maximum subspace dimension.
void setBlockSize(int blockSize)
Set block size.
ScalarTraits< ScalarType >::magnitudeType NRM2(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const
int curDim
The current subspace dimension.
std::vector< int > getRitzIndex()
Get the current Ritz index vector.
void TREVC(const char &SIDE, const char &HOWMNY, OrdinalType *select, const OrdinalType &n, const ScalarType *T, const OrdinalType &ldt, ScalarType *VL, const OrdinalType &ldvl, ScalarType *VR, const OrdinalType &ldvr, const OrdinalType &mm, OrdinalType *m, ScalarType *WORK, OrdinalType *info) const
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get eigenproblem.
Pure virtual base class which describes the basic interface to the iterative eigensolver.
void iterate()
Solves the eigenvalue problem.
std::vector< MagnitudeType > getRes2Norms()
Get the current residual norms (2-norm)
RCP< MV > BV
Image of V under B.
Structure to contain pointers to GeneralizedDavidson state variables.
void GGES(const char &JOBVL, const char &JOBVR, const char &SORT, OrdinalType &(*ptr2func)(ScalarType *, ScalarType *, ScalarType *), const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb, OrdinalType *sdim, MagnitudeType *ALPHAR, MagnitudeType *ALPHAI, MagnitudeType *BETA, ScalarType *VL, const OrdinalType &ldvl, ScalarType *VR, const OrdinalType &ldvr, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *BWORK, OrdinalType *info) const
Abstract class definition for Anasazi Output Managers.
std::vector< Value< ScalarType > > eVals
Vector of generalized eigenvalues.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void setSize(int blockSize, int maxSubDim)
Set problem size.
Abstract base class which defines the interface required by an eigensolver and status test class to c...
void GEES(const char &JOBVS, const char &SORT, OrdinalType &(*ptr2func)(ScalarType *, ScalarType *), const OrdinalType &n, ScalarType *A, const OrdinalType &lda, OrdinalType *sdim, ScalarType *WR, ScalarType *WI, ScalarType *VS, const OrdinalType &ldvs, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *BWORK, OrdinalType *info) const
Output managers remove the need for the eigensolver to know any information about the required output...
std::vector< MagnitudeType > getResNorms()
Get the current residual norms (w.r.t. norm defined by OrthoManager)
Templated virtual class for providing orthogonalization/orthonormalization methods.
RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get status test.
RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Q
Left generalized Schur vectors from QZ decomposition of (VAV,VBV)
Traits class which defines basic operations on multivectors.
This struct is used for storing eigenvalues and Ritz values, as a pair of real values.
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
Virtual base class which defines the interface between an eigensolver and a class whose job is the so...
ScalarType LAPY2(const ScalarType &x, const ScalarType &y) const
GeneralizedDavidson(const RCP< Eigenproblem< ScalarType, MV, OP > > &problem, const RCP< SortManager< MagnitudeType > > &sortman, const RCP< OutputManager< ScalarType > > &outputman, const RCP< StatusTest< ScalarType, MV, OP > > &tester, const RCP< OrthoManager< ScalarType, MV > > &orthoman, Teuchos::ParameterList &pl)
Constructor.
void TRSEN(const char &JOB, const char &COMPQ, const OrdinalType *SELECT, const OrdinalType &n, ScalarType *T, const OrdinalType &ldt, ScalarType *Q, const OrdinalType &ldq, MagnitudeType *WR, MagnitudeType *WI, OrdinalType *M, ScalarType *S, MagnitudeType *SEP, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *IWORK, const OrdinalType &liwork, OrdinalType *info) const
OrdinalType numCols() const
RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > S
Left quasi upper triangular matrix from QZ decomposition of (VAV,VBV)
RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > VBV
Projection of B onto V.
void initialize()
Initialize the eigenvalue problem.
void push_back(const value_type &x)
bool isInitialized() const
Query if the solver is in an initialized state.
RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Z
Right generalized Schur vectors from QZ decomposition of (VAV,VBV)
void setAuxVecs(const Teuchos::Array< RCP< const MV > > &auxVecs)
Set auxilliary vectors.
Types and exceptions used within Anasazi solvers and interfaces.
Anasazi's templated virtual class for providing routines for orthogonalization and orthonormalization...
int getBlockSize() const
Get block size.
void TGSEN(const OrdinalType &ijob, const OrdinalType &wantq, const OrdinalType &wantz, const OrdinalType *SELECT, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb, MagnitudeType *ALPHAR, MagnitudeType *ALPHAI, MagnitudeType *BETA, ScalarType *Q, const OrdinalType &ldq, ScalarType *Z, const OrdinalType &ldz, OrdinalType *M, MagnitudeType *PL, MagnitudeType *PR, MagnitudeType *DIF, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *IWORK, const OrdinalType &liwork, OrdinalType *info) const
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
RCP< const MV > getRitzVectors()
Get the current Ritz vectors.
void currentStatus(std::ostream &myout)
Print current status of solver.
Teuchos::ScalarTraits< ScalarType >::magnitudeType realpart
The real component of the eigenvalue.
Common interface of stopping criteria for Anasazi's solvers.
int getNumIters() const
Get number of iterations.
SerialDenseMatrix< OrdinalType, ScalarType > & assign(const SerialDenseMatrix< OrdinalType, ScalarType > &Source)
int getCurSubspaceDim() const
Get current subspace dimension.
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
OrdinalType stride() const
OrdinalType numRows() const
Declaration and definition of Anasazi::StatusTest.
void resetNumIters()
Reset the number of iterations.