Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 
34 #include "AnasaziOutputManager.hpp"
35 #include "Teuchos_BLAS.hpp"
36 #include "Teuchos_LAPACK.hpp"
38 
39 namespace 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 
52  SolverUtils();
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,
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 
151  typedef MultiVecTraits<ScalarType,MV> MVT;
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,
243  {
244  // Permute the vectors in Q according to the permutation vector \c perm, and
245  // optionally the residual vector \c resids
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
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
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
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,
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.
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 
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 
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
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
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>
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 
OrdinalType ILAENV(const OrdinalType &ispec, const std::string &NAME, const std::string &OPTS, const OrdinalType &N1=-1, const OrdinalType &N2=-1, const OrdinalType &N3=-1, const OrdinalType &N4=-1) const
Declaration of basic traits for the multivector type.
virtual ~SolverUtils()
Destructor.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Virtual base class which defines basic traits for the operator type.
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...
Anasazi&#39;s templated, static class providing utilities for the solvers.
void COPY(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx, ScalarType *y, const OrdinalType &incy) const
Abstract class definition for Anasazi Output Managers.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
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...
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...
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero())
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
OrdinalType numCols() const
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...
void HEEV(const char &JOBZ, const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, MagnitudeType *W, ScalarType *WORK, const OrdinalType &lwork, MagnitudeType *RWORK, OrdinalType *info) const
void HEGV(const OrdinalType &itype, const char &JOBZ, const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb, MagnitudeType *W, ScalarType *WORK, const OrdinalType &lwork, MagnitudeType *RWORK, OrdinalType *info) const
OrdinalType numRows() const