45 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
46 typedef typename Teuchos::ScalarTraits<ScalarType> SCT;
63 static void permuteVectors(
const int n,
const std::vector<int> &perm, MV &Q, std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType >* resids = 0);
66 static void permuteVectors(
const std::vector<int> &perm, Teuchos::SerialDenseMatrix<int,ScalarType> &Q);
95 static void applyHouse(
int k, MV &V,
const Teuchos::SerialDenseMatrix<int,ScalarType> &H,
const std::vector<ScalarType> &tau, Teuchos::RCP<MV> workMV = Teuchos::null);
129 static int directSolver(
int size,
const Teuchos::SerialDenseMatrix<int,ScalarType> &KK,
130 Teuchos::RCP<
const Teuchos::SerialDenseMatrix<int,ScalarType> > MM,
131 Teuchos::SerialDenseMatrix<int,ScalarType> &EV,
132 std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > &theta,
133 int &nev,
int esType = 0);
142 static typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
errorEquality(
const MV &X,
const MV &MX, Teuchos::RCP<const OP> M = Teuchos::null);
178 const std::vector<int> &perm,
180 std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType >* resids)
186 std::vector<int> permcopy(perm), swapvec(n-1);
187 std::vector<int> index(1);
188 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
189 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
191 TEUCHOS_TEST_FOR_EXCEPTION(n > MVT::GetNumberVecs(Q), std::invalid_argument,
"Anasazi::SolverUtils::permuteVectors(): argument n larger than width of input multivector.");
197 for (i=0; i<n-1; i++) {
200 for (j=i; j<n; j++) {
201 if (permcopy[j] == i) {
205 TEUCHOS_TEST_FOR_EXCEPTION(j == n-1, std::invalid_argument,
"Anasazi::SolverUtils::permuteVectors(): permutation index invalid.");
209 std::swap( permcopy[j], permcopy[i] );
215 for (i=n-2; i>=0; i--) {
222 std::swap( (*resids)[i], (*resids)[j] );
227 Teuchos::RCP<MV> tmpQ = MVT::CloneCopy( Q, index );
228 Teuchos::RCP<MV> tmpQj = MVT::CloneViewNonConst( Q, index );
230 Teuchos::RCP<MV> tmpQi = MVT::CloneViewNonConst( Q, index );
231 MVT::MvAddMv( one, *tmpQi, zero, *tmpQi, *tmpQj );
232 MVT::MvAddMv( one, *tmpQ, zero, *tmpQ, *tmpQi );
270 const int n = MVT::GetNumberVecs(V);
271 const ScalarType ONE = SCT::one();
272 const ScalarType ZERO = SCT::zero();
275 if (MVT::GetNumberVecs(V) == 0 || MVT::GetGlobalLength(V) == 0 || k == 0) {
279 if (workMV == Teuchos::null) {
281 workMV = MVT::Clone(V,1);
283 else if (MVT::GetNumberVecs(*workMV) > 1) {
284 std::vector<int> first(1);
286 workMV = MVT::CloneViewNonConst(*workMV,first);
289 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*workMV) < 1,std::invalid_argument,
"Anasazi::SolverUtils::applyHouse(): work multivector was empty.");
293 TEUCHOS_TEST_FOR_EXCEPTION( H.numCols() != k, std::invalid_argument,
"Anasazi::SolverUtils::applyHouse(): H must have at least k columns.");
294 TEUCHOS_TEST_FOR_EXCEPTION( (
int)tau.size() != k, std::invalid_argument,
"Anasazi::SolverUtils::applyHouse(): tau must have at least k entries.");
295 TEUCHOS_TEST_FOR_EXCEPTION( H.numRows() != MVT::GetNumberVecs(V), std::invalid_argument,
"Anasazi::SolverUtils::applyHouse(): Size of H,V are inconsistent.");
299 for (
int i=0; i<k; i++) {
302 std::vector<int> activeind(n-i);
303 for (
int j=0; j<n-i; j++) activeind[j] = j+i;
304 Teuchos::RCP<MV> actV = MVT::CloneViewNonConst(V,activeind);
310 Teuchos::SerialDenseMatrix<int,ScalarType> v(Teuchos::Copy,H,n-i,1,i,i);
318 MVT::MvTimesMatAddMv(-tau[i],*actV,v,ZERO,*workMV);
322 Teuchos::SerialDenseMatrix<int,ScalarType> vT(v,Teuchos::CONJ_TRANS);
323 MVT::MvTimesMatAddMv(ONE,*workMV,vT,ONE,*actV);
325 actV = Teuchos::null;
339 const Teuchos::SerialDenseMatrix<int,ScalarType> &KK,
340 Teuchos::RCP<
const Teuchos::SerialDenseMatrix<int,ScalarType> > MM,
341 Teuchos::SerialDenseMatrix<int,ScalarType> &EV,
342 std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > &theta,
343 int &nev,
int esType)
387 Teuchos::LAPACK<int,ScalarType> lapack;
388 Teuchos::BLAS<int,ScalarType> blas;
393 if (size < nev || size < 0) {
396 if (KK.numCols() < size || KK.numRows() < size) {
399 if ((esType == 0 || esType == 1)) {
400 if (MM == Teuchos::null) {
403 else if (MM->numCols() < size || MM->numRows() < size) {
407 if (EV.numCols() < size || EV.numRows() < size) {
410 if (theta.size() < (
unsigned int) size) {
418 std::string lapack_name =
"hetrd";
419 std::string lapack_opts =
"u";
420 int NB = lapack.ILAENV(1, lapack_name, lapack_opts, size, -1, -1, -1);
421 int lwork = size*(NB+2);
422 std::vector<ScalarType> work(lwork);
423 std::vector<MagnitudeType> rwork(3*size-2);
426 std::vector<MagnitudeType> tt( size );
429 MagnitudeType tol = SCT::magnitude(SCT::squareroot(SCT::eps()));
431 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
432 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
434 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > KKcopy, MMcopy;
435 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > U;
443 for (rank = size; rank > 0; --rank) {
445 U = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(rank,rank) );
449 KKcopy = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, KK, rank, rank ) );
450 MMcopy = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, *MM, rank, rank ) );
455 lapack.HEGV(1,
'V',
'U', rank, KKcopy->values(), KKcopy->stride(),
456 MMcopy->values(), MMcopy->stride(), &tt[0], &work[0], lwork,
462 std::cerr << std::endl;
463 std::cerr <<
"Anasazi::SolverUtils::directSolver(): In HEGV, argument " << -info <<
"has an illegal value.\n";
464 std::cerr << std::endl;
475 MMcopy = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, *MM, rank, rank ) );
476 for (
int i = 0; i < rank; ++i) {
477 for (
int j = 0; j < i; ++j) {
478 (*MMcopy)(i,j) = SCT::conjugate((*MM)(j,i));
482 TEUCHOS_TEST_FOR_EXCEPTION(
483 U->multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,*MMcopy,*KKcopy,zero) != 0,
484 std::logic_error,
"Anasazi::SolverUtils::directSolver() call to Teuchos::SerialDenseMatrix::multiply() returned an error.");
486 TEUCHOS_TEST_FOR_EXCEPTION(
487 MMcopy->multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,one,*KKcopy,*U,zero) != 0,
488 std::logic_error,
"Anasazi::SolverUtils::directSolver() call to Teuchos::SerialDenseMatrix::multiply() returned an error.");
489 MagnitudeType maxNorm = SCT::magnitude(zero);
490 MagnitudeType maxOrth = SCT::magnitude(zero);
491 for (
int i = 0; i < rank; ++i) {
492 for (
int j = i; j < rank; ++j) {
494 maxNorm = SCT::magnitude((*MMcopy)(i,j) - one) > maxNorm
495 ? SCT::magnitude((*MMcopy)(i,j) - one) : maxNorm;
497 maxOrth = SCT::magnitude((*MMcopy)(i,j)) > maxOrth
498 ? SCT::magnitude((*MMcopy)(i,j)) : maxOrth;
509 if ((maxNorm <= tol) && (maxOrth <= tol)) {
518 nev = (rank < nev) ? rank : nev;
519 EV.putScalar( zero );
520 std::copy(tt.begin(),tt.begin()+nev,theta.begin());
521 for (
int i = 0; i < nev; ++i) {
522 blas.COPY( rank, (*KKcopy)[i], 1, EV[i], 1 );
532 KKcopy = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, KK, size, size ) );
533 MMcopy = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, *MM, size, size ) );
538 lapack.HEGV(1,
'V',
'U', size, KKcopy->values(), KKcopy->stride(),
539 MMcopy->values(), MMcopy->stride(), &tt[0], &work[0], lwork,
545 std::cerr << std::endl;
546 std::cerr <<
"Anasazi::SolverUtils::directSolver(): In HEGV, argument " << -info <<
"has an illegal value.\n";
547 std::cerr << std::endl;
554 std::cerr << std::endl;
555 std::cerr <<
"Anasazi::SolverUtils::directSolver(): In HEGV, DPOTRF or DHEEV returned an error code (" << info <<
").\n";
556 std::cerr << std::endl;
563 std::copy(tt.begin(),tt.begin()+nev,theta.begin());
564 for (
int i = 0; i < nev; ++i) {
565 blas.COPY( size, (*KKcopy)[i], 1, EV[i], 1 );
575 KKcopy = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, KK, size, size ) );
579 lapack.HEEV(
'V',
'U', size, KKcopy->values(), KKcopy->stride(), &tt[0], &work[0], lwork, &rwork[0], &info);
583 std::cerr << std::endl;
585 std::cerr <<
"Anasazi::SolverUtils::directSolver(): In DHEEV, argument " << -info <<
" has an illegal value\n";
588 std::cerr <<
"Anasazi::SolverUtils::directSolver(): In DHEEV, the algorithm failed to converge (" << info <<
").\n";
590 std::cerr << std::endl;
597 std::copy(tt.begin(),tt.begin()+nev,theta.begin());
598 for (
int i = 0; i < nev; ++i) {
599 blas.COPY( size, (*KKcopy)[i], 1, EV[i], 1 );
622 MagnitudeType maxDiff = SCT::magnitude(SCT::zero());
624 int xc = MVT::GetNumberVecs(X);
625 int mxc = MVT::GetNumberVecs(MX);
627 TEUCHOS_TEST_FOR_EXCEPTION(xc != mxc,std::invalid_argument,
"Anasazi::SolverUtils::errorEquality(): input multivecs have different number of columns.");
632 MagnitudeType maxCoeffX = SCT::magnitude(SCT::zero());
633 std::vector<MagnitudeType> tmp( xc );
634 MVT::MvNorm(MX, tmp);
636 for (
int i = 0; i < xc; ++i) {
637 maxCoeffX = (tmp[i] > maxCoeffX) ? tmp[i] : maxCoeffX;
640 std::vector<int> index( 1 );
641 Teuchos::RCP<MV> MtimesX;
642 if (M != Teuchos::null) {
643 MtimesX = MVT::Clone( X, xc );
644 OPT::Apply( *M, X, *MtimesX );
647 MtimesX = MVT::CloneCopy(X);
649 MVT::MvAddMv( -1.0, MX, 1.0, *MtimesX, *MtimesX );
650 MVT::MvNorm( *MtimesX, tmp );
652 for (
int i = 0; i < xc; ++i) {
653 maxDiff = (tmp[i] > maxDiff) ? tmp[i] : maxDiff;
656 return (maxCoeffX == 0.0) ? maxDiff : maxDiff/maxCoeffX;