RBGen  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RBGen_Utils.cpp
1 #include "RBGen_Utils.h"
2 
3 #include "Epetra_LAPACK.h"
4 #include "Epetra_LocalMap.h"
5 #include "Epetra_MultiVector.h"
6 #include <vector>
7 
8 namespace RBGen {
9 
10  double BasisAngle( const Epetra_MultiVector& S, const Epetra_MultiVector& T )
11  {
12  //
13  // Computes the largest acute angle between the two orthogonal basis
14  //
15  if (S.NumVectors() != T.NumVectors()) {
16  return acos( 0.0 );
17  } else {
18  int lwork, info = 0;
19  int m = S.NumVectors(), n = T.NumVectors();
20  int num_vecs = ( m < n ? m : n );
21  double U[ 1 ], Vt[ 1 ];
22  lwork = 3*m*n;
23  std::vector<double> work( lwork );
24  std::vector<double> theta( num_vecs );
25  Epetra_LAPACK lapack;
26  Epetra_LocalMap localMap( S.NumVectors(), 0, S.Map().Comm() );
27  Epetra_MultiVector Pvec( localMap, T.NumVectors() );
28  info = Pvec.Multiply( 'T', 'N', 1.0, S, T, 0.0 );
29  //
30  // Perform SVD on S^T*T
31  //
32  lapack.GESVD( 'N', 'N', num_vecs, num_vecs, Pvec.Values(), Pvec.Stride(),
33  &theta[0], U, 1, Vt, 1, &work[0], &lwork, &info );
34  assert( info == 0 );
35  return (acos( theta[num_vecs-1] ) );
36  }
37  //
38  // Default return statement, should never be executed.
39  //
40  return acos( 0.0 );
41  }
42 
43 } // end namespace RBGen
void GESVD(const char JOBU, const char JOBVT, const int M, const int N, float *A, const int LDA, float *S, float *U, const int LDU, float *VT, const int LDVT, float *WORK, const int *LWORK, int *INFO) const
double BasisAngle(const Epetra_MultiVector &S, const Epetra_MultiVector &T)
Method for computing the angle between two subspaces represented as Epetra_MultiVector bases...
Definition: RBGen_Utils.cpp:10