Anasazi Version of the Day
Loading...
Searching...
No Matches
AnasaziSolverUtils.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Anasazi: Block Eigensolvers Package
4//
5// Copyright 2004 NTESS and the Anasazi contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef ANASAZI_SOLVER_UTILS_HPP
11#define ANASAZI_SOLVER_UTILS_HPP
12
29#include "AnasaziConfigDefs.hpp"
32#include "Teuchos_ScalarTraits.hpp"
33
35#include "Teuchos_BLAS.hpp"
36#include "Teuchos_LAPACK.hpp"
37#include "Teuchos_SerialDenseMatrix.hpp"
38
39namespace Anasazi {
40
41 template<class ScalarType, class MV, class OP>
43 {
44 public:
45 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
46 typedef typename Teuchos::ScalarTraits<ScalarType> SCT;
47
49
50
53
55 virtual ~SolverUtils() {};
56
58
60
61
63 static void permuteVectors(const int n, const std::vector<int> &perm, MV &Q, std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType >* resids = 0);
64
66 static void permuteVectors(const std::vector<int> &perm, Teuchos::SerialDenseMatrix<int,ScalarType> &Q);
67
69
71
72
74
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);
96
98
100
101
103
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);
135
137
138
140
142 static typename Teuchos::ScalarTraits<ScalarType>::magnitudeType errorEquality(const MV &X, const MV &MX, Teuchos::RCP<const OP> M = Teuchos::null);
143
145
146 private:
147
149
150
153
155 };
156
157 //-----------------------------------------------------------------------------
158 //
159 // CONSTRUCTOR
160 //
161 //-----------------------------------------------------------------------------
162
163 template<class ScalarType, class MV, class OP>
165
166
167 //-----------------------------------------------------------------------------
168 //
169 // SORTING METHODS
170 //
171 //-----------------------------------------------------------------------------
172
174 // permuteVectors for MV
175 template<class ScalarType, class MV, class OP>
177 const int n,
178 const std::vector<int> &perm,
179 MV &Q,
180 std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType >* resids)
181 {
182 // Permute the vectors according to the permutation vector \c perm, and
183 // optionally the residual vector \c resids
184
185 int i, j;
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();
190
191 TEUCHOS_TEST_FOR_EXCEPTION(n > MVT::GetNumberVecs(Q), std::invalid_argument, "Anasazi::SolverUtils::permuteVectors(): argument n larger than width of input multivector.");
192
193 // We want to recover the elementary permutations (individual swaps)
194 // from the permutation vector. Do this by constructing the inverse
195 // of the permutation, by sorting them to {1,2,...,n}, and recording
196 // the elementary permutations of the inverse.
197 for (i=0; i<n-1; i++) {
198 //
199 // find i in the permcopy vector
200 for (j=i; j<n; j++) {
201 if (permcopy[j] == i) {
202 // found it at index j
203 break;
204 }
205 TEUCHOS_TEST_FOR_EXCEPTION(j == n-1, std::invalid_argument, "Anasazi::SolverUtils::permuteVectors(): permutation index invalid.");
206 }
207 //
208 // Swap two scalars
209 std::swap( permcopy[j], permcopy[i] );
210
211 swapvec[i] = j;
212 }
213
214 // now apply the elementary permutations of the inverse in reverse order
215 for (i=n-2; i>=0; i--) {
216 j = swapvec[i];
217 //
218 // Swap (i,j)
219 //
220 // Swap residuals (if they exist)
221 if (resids) {
222 std::swap( (*resids)[i], (*resids)[j] );
223 }
224 //
225 // Swap corresponding vectors
226 index[0] = j;
227 Teuchos::RCP<MV> tmpQ = MVT::CloneCopy( Q, index );
228 Teuchos::RCP<MV> tmpQj = MVT::CloneViewNonConst( Q, index );
229 index[0] = i;
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 );
233 }
234 }
235
236
238 // permuteVectors for MV
239 template<class ScalarType, class MV, class OP>
241 const std::vector<int> &perm,
242 Teuchos::SerialDenseMatrix<int,ScalarType> &Q)
243 {
244 // Permute the vectors in Q according to the permutation vector \c perm, and
245 // optionally the residual vector \c resids
246 Teuchos::BLAS<int,ScalarType> blas;
247 const int n = perm.size();
248 const int m = Q.numRows();
249
250 TEUCHOS_TEST_FOR_EXCEPTION(n != Q.numCols(), std::invalid_argument, "Anasazi::SolverUtils::permuteVectors(): size of permutation vector not equal to number of columns.");
251
252 // Sort the primitive ritz vectors
253 Teuchos::SerialDenseMatrix<int,ScalarType> copyQ(Teuchos::Copy, Q);
254 for (int i=0; i<n; i++) {
255 blas.COPY(m, copyQ[perm[i]], 1, Q[i], 1);
256 }
257 }
258
259
260 //-----------------------------------------------------------------------------
261 //
262 // BASIS UPDATE METHODS
263 //
264 //-----------------------------------------------------------------------------
265
266 // apply householder reflectors to multivector
267 template<class ScalarType, class MV, class OP>
268 void SolverUtils<ScalarType, MV, OP>::applyHouse(int k, MV &V, const Teuchos::SerialDenseMatrix<int,ScalarType> &H, const std::vector<ScalarType> &tau, Teuchos::RCP<MV> workMV) {
269
270 const int n = MVT::GetNumberVecs(V);
271 const ScalarType ONE = SCT::one();
272 const ScalarType ZERO = SCT::zero();
273
274 // early exit if V has zero-size or if k==0
275 if (MVT::GetNumberVecs(V) == 0 || MVT::GetGlobalLength(V) == 0 || k == 0) {
276 return;
277 }
278
279 if (workMV == Teuchos::null) {
280 // user did not give us any workspace; allocate some
281 workMV = MVT::Clone(V,1);
282 }
283 else if (MVT::GetNumberVecs(*workMV) > 1) {
284 std::vector<int> first(1);
285 first[0] = 0;
286 workMV = MVT::CloneViewNonConst(*workMV,first);
287 }
288 else {
289 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*workMV) < 1,std::invalid_argument,"Anasazi::SolverUtils::applyHouse(): work multivector was empty.");
290 }
291 // Q = H_1 ... H_k is square, with as many rows as V has vectors
292 // however, H need only have k columns, one each for the k reflectors.
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.");
296
297 // perform the loop
298 // flops: Sum_{i=0:k-1} 4 m (n-i) == 4mnk - 2m(k^2- k)
299 for (int i=0; i<k; i++) {
300 // apply V H_i+1 = V - tau_i+1 (V v_i+1) v_i+1^T
301 // because of the structure of v_i+1, this transform does not affect the first i columns of V
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);
305
306 // note, below H_i, v_i and tau_i are mathematical objects which use 1-based indexing
307 // while H, v and tau are data structures using 0-based indexing
308
309 // get v_i+1: i-th column of H
310 Teuchos::SerialDenseMatrix<int,ScalarType> v(Teuchos::Copy,H,n-i,1,i,i);
311 // v_i+1(1:i) = 0: this isn't part of v
312 // e_i+1^T v_i+1 = 1 = v(0)
313 v(0,0) = ONE;
314
315 // compute -tau_i V v_i
316 // tau_i+1 is tau[i]
317 // flops: 2 m n-i
318 MVT::MvTimesMatAddMv(-tau[i],*actV,v,ZERO,*workMV);
319
320 // perform V = V + workMV v_i^T
321 // flops: 2 m n-i
322 Teuchos::SerialDenseMatrix<int,ScalarType> vT(v,Teuchos::CONJ_TRANS);
323 MVT::MvTimesMatAddMv(ONE,*workMV,vT,ONE,*actV);
324
325 actV = Teuchos::null;
326 }
327 }
328
329
330 //-----------------------------------------------------------------------------
331 //
332 // EIGENSOLVER PROJECTION METHODS
333 //
334 //-----------------------------------------------------------------------------
335
336 template<class ScalarType, class MV, class OP>
338 int size,
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)
344 {
345 // Routine for computing the first NEV generalized eigenpairs of the symmetric pencil (KK, MM)
346 //
347 // Parameter variables:
348 //
349 // size : Dimension of the eigenproblem (KK, MM)
350 //
351 // KK : Hermitian "stiffness" matrix
352 //
353 // MM : Hermitian positive-definite "mass" matrix
354 //
355 // EV : Matrix to store the nev eigenvectors
356 //
357 // theta : Array to store the eigenvalues (Size = nev )
358 //
359 // nev : Number of the smallest eigenvalues requested (input)
360 // Number of the smallest computed eigenvalues (output)
361 // Routine may compute and return more or less eigenvalues than requested.
362 //
363 // esType : Flag to select the algorithm
364 //
365 // esType = 0 (default) Uses LAPACK routine (Cholesky factorization of MM)
366 // with deflation of MM to get orthonormality of
367 // eigenvectors (S^T MM S = I)
368 //
369 // esType = 1 Uses LAPACK routine (Cholesky factorization of MM)
370 // (no check of orthonormality)
371 //
372 // esType = 10 Uses LAPACK routine for simple eigenproblem on KK
373 // (MM is not referenced in this case)
374 //
375 // Note: The code accesses only the upper triangular part of KK and MM.
376 //
377 // Return the integer info on the status of the computation
378 //
379 // info = 0 >> Success
380 //
381 // info < 0 >> error in the info-th argument
382 // info = - 20 >> Failure in LAPACK routine
383
384 // Define local arrays
385
386 // Create blas/lapack objects.
387 Teuchos::LAPACK<int,ScalarType> lapack;
388 Teuchos::BLAS<int,ScalarType> blas;
389
390 int rank = 0;
391 int info = 0;
392
393 if (size < nev || size < 0) {
394 return -1;
395 }
396 if (KK.numCols() < size || KK.numRows() < size) {
397 return -2;
398 }
399 if ((esType == 0 || esType == 1)) {
400 if (MM == Teuchos::null) {
401 return -3;
402 }
403 else if (MM->numCols() < size || MM->numRows() < size) {
404 return -3;
405 }
406 }
407 if (EV.numCols() < size || EV.numRows() < size) {
408 return -4;
409 }
410 if (theta.size() < (unsigned int) size) {
411 return -5;
412 }
413 if (nev <= 0) {
414 return -6;
415 }
416
417 // Query LAPACK for the "optimal" block size for HEGV
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); // For HEEV, lwork should be NB+2, instead of NB+1
422 std::vector<ScalarType> work(lwork);
423 std::vector<MagnitudeType> rwork(3*size-2);
424 // tt contains the eigenvalues from HEGV, which are necessarily real, and
425 // HEGV expects this vector to be real as well
426 std::vector<MagnitudeType> tt( size );
427 //typedef typename std::vector<MagnitudeType>::iterator MTIter; // unused
428
429 MagnitudeType tol = SCT::magnitude(SCT::squareroot(SCT::eps()));
430 // MagnitudeType tol = 1e-12;
431 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
432 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
433
434 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > KKcopy, MMcopy;
435 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > U;
436
437 switch (esType) {
438 default:
439 case 0:
440 //
441 // Use LAPACK to compute the generalized eigenvectors
442 //
443 for (rank = size; rank > 0; --rank) {
444
445 U = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(rank,rank) );
446 //
447 // Copy KK & MM
448 //
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 ) );
451 //
452 // Solve the generalized eigenproblem with LAPACK
453 //
454 info = 0;
455 lapack.HEGV(1, 'V', 'U', rank, KKcopy->values(), KKcopy->stride(),
456 MMcopy->values(), MMcopy->stride(), &tt[0], &work[0], lwork,
457 &rwork[0], &info);
458 //
459 // Treat error messages
460 //
461 if (info < 0) {
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;
465 return -20;
466 }
467 if (info > 0) {
468 if (info > rank)
469 rank = info - rank;
470 continue;
471 }
472 //
473 // Check the quality of eigenvectors ( using mass-orthonormality )
474 //
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));
479 }
480 }
481 // U = 0*U + 1*MMcopy*KKcopy = MMcopy * KKcopy
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.");
485 // MMcopy = 0*MMcopy + 1*KKcopy^H*U = KKcopy^H * MMcopy * KKcopy
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) {
493 if (j == i)
494 maxNorm = SCT::magnitude((*MMcopy)(i,j) - one) > maxNorm
495 ? SCT::magnitude((*MMcopy)(i,j) - one) : maxNorm;
496 else
497 maxOrth = SCT::magnitude((*MMcopy)(i,j)) > maxOrth
498 ? SCT::magnitude((*MMcopy)(i,j)) : maxOrth;
499 }
500 }
501 /* if (verbose > 4) {
502 std::cout << " >> Local eigensolve >> Size: " << rank;
503 std::cout.precision(2);
504 std::cout.setf(std::ios::scientific, std::ios::floatfield);
505 std::cout << " Normalization error: " << maxNorm;
506 std::cout << " Orthogonality error: " << maxOrth;
507 std::cout << endl;
508 }*/
509 if ((maxNorm <= tol) && (maxOrth <= tol)) {
510 break;
511 }
512 } // for (rank = size; rank > 0; --rank)
513 //
514 // Copy the computed eigenvectors and eigenvalues
515 // ( they may be less than the number requested because of deflation )
516 //
517 // std::cout << "directSolve rank: " << rank << "\tsize: " << size << endl;
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 );
523 }
524 break;
525
526 case 1:
527 //
528 // Use the Cholesky factorization of MM to compute the generalized eigenvectors
529 //
530 // Copy KK & MM
531 //
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 ) );
534 //
535 // Solve the generalized eigenproblem with LAPACK
536 //
537 info = 0;
538 lapack.HEGV(1, 'V', 'U', size, KKcopy->values(), KKcopy->stride(),
539 MMcopy->values(), MMcopy->stride(), &tt[0], &work[0], lwork,
540 &rwork[0], &info);
541 //
542 // Treat error messages
543 //
544 if (info < 0) {
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;
548 return -20;
549 }
550 if (info > 0) {
551 if (info > size)
552 nev = 0;
553 else {
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;
557 return -20;
558 }
559 }
560 //
561 // Copy the eigenvectors and eigenvalues
562 //
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 );
566 }
567 break;
568
569 case 10:
570 //
571 // Simple eigenproblem
572 //
573 // Copy KK
574 //
575 KKcopy = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, KK, size, size ) );
576 //
577 // Solve the generalized eigenproblem with LAPACK
578 //
579 lapack.HEEV('V', 'U', size, KKcopy->values(), KKcopy->stride(), &tt[0], &work[0], lwork, &rwork[0], &info);
580 //
581 // Treat error messages
582 if (info != 0) {
583 std::cerr << std::endl;
584 if (info < 0) {
585 std::cerr << "Anasazi::SolverUtils::directSolver(): In DHEEV, argument " << -info << " has an illegal value\n";
586 }
587 else {
588 std::cerr << "Anasazi::SolverUtils::directSolver(): In DHEEV, the algorithm failed to converge (" << info << ").\n";
589 }
590 std::cerr << std::endl;
591 info = -20;
592 break;
593 }
594 //
595 // Copy the eigenvectors
596 //
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 );
600 }
601 break;
602 }
603
604 return info;
605 }
606
607
608 //-----------------------------------------------------------------------------
609 //
610 // SANITY CHECKING METHODS
611 //
612 //-----------------------------------------------------------------------------
613
614 template<class ScalarType, class MV, class OP>
615 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
616 SolverUtils<ScalarType, MV, OP>::errorEquality(const MV &X, const MV &MX, Teuchos::RCP<const OP> M)
617 {
618 // Return the maximum coefficient of the matrix M * X - MX
619 // scaled by the maximum coefficient of MX.
620 // When M is not specified, the identity is used.
621
622 MagnitudeType maxDiff = SCT::magnitude(SCT::zero());
623
624 int xc = MVT::GetNumberVecs(X);
625 int mxc = MVT::GetNumberVecs(MX);
626
627 TEUCHOS_TEST_FOR_EXCEPTION(xc != mxc,std::invalid_argument,"Anasazi::SolverUtils::errorEquality(): input multivecs have different number of columns.");
628 if (xc == 0) {
629 return maxDiff;
630 }
631
632 MagnitudeType maxCoeffX = SCT::magnitude(SCT::zero());
633 std::vector<MagnitudeType> tmp( xc );
634 MVT::MvNorm(MX, tmp);
635
636 for (int i = 0; i < xc; ++i) {
637 maxCoeffX = (tmp[i] > maxCoeffX) ? tmp[i] : maxCoeffX;
638 }
639
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 );
645 }
646 else {
647 MtimesX = MVT::CloneCopy(X);
648 }
649 MVT::MvAddMv( -1.0, MX, 1.0, *MtimesX, *MtimesX );
650 MVT::MvNorm( *MtimesX, tmp );
651
652 for (int i = 0; i < xc; ++i) {
653 maxDiff = (tmp[i] > maxDiff) ? tmp[i] : maxDiff;
654 }
655
656 return (maxCoeffX == 0.0) ? maxDiff : maxDiff/maxCoeffX;
657
658 }
659
660} // end namespace Anasazi
661
662#endif // ANASAZI_SOLVER_UTILS_HPP
663
Anasazi header file which uses auto-configuration information to include necessary C++ headers.
Declaration of basic traits for the multivector type.
Virtual base class which defines basic traits for the operator type.
Abstract class definition for Anasazi Output Managers.
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
Anasazi's templated, static class providing utilities for the solvers.
static void permuteVectors(const int n, const std::vector< int > &perm, MV &Q, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > *resids=0)
Permute the vectors in a multivector according to the permutation vector perm, and optionally the res...
static Teuchos::ScalarTraits< ScalarType >::magnitudeType errorEquality(const MV &X, const MV &MX, Teuchos::RCP< const OP > M=Teuchos::null)
Return the maximum coefficient of the matrix scaled by the maximum coefficient of MX.
virtual ~SolverUtils()
Destructor.
static int directSolver(int size, const Teuchos::SerialDenseMatrix< int, ScalarType > &KK, Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > MM, Teuchos::SerialDenseMatrix< int, ScalarType > &EV, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &theta, int &nev, int esType=0)
Routine for computing the first NEV generalized eigenpairs of the Hermitian pencil (KK,...
static void applyHouse(int k, MV &V, const Teuchos::SerialDenseMatrix< int, ScalarType > &H, const std::vector< ScalarType > &tau, Teuchos::RCP< MV > workMV=Teuchos::null)
Apply a sequence of Householder reflectors (from GEQRF) to a multivector, using minimal workspace.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.