HMLP: High-performance Machine Learning Primitives
lanczos.hpp
1 #ifndef LANCZOS_HPP
2 #define LANCZOS_HPP
3 
4 #include <limits>
5 #include <functional>
6 
7 #include <hmlp.h>
8 #include <Data.hpp>
9 #include <containers/KernelMatrix.hpp>
10 
11 namespace hmlp
12 {
13 
14 
19 template<typename VIRTUALMATRIX, typename T>
20 void lanczos(
21  VIRTUALMATRIX &A,
22  size_t n, size_t r, size_t nkrylov,
23  std::vector<T> &Sigma, std::vector<T> &V )
24 {
26  assert( r > 0 && r <= nkrylov );
27 
29  hmlp::Data<T> alpha( nkrylov, 1, 0.0 );
30  hmlp::Data<T> beta( nkrylov, 1, 0.0 );
31 
33  hmlp::Data<T> U( n, nkrylov, 1.0 );;
34  hmlp::Data<T> w( n, 1, 0.0 );
35 
37  beta[ 0 ] = hmlp::xnrm2( n, U.columndata( 0 ), 1 );
38  //for ( size_t i = 0; i < n; i ++ )
39  // beta[ 0 ] += U( i, (size_t)0 ) * U( i, (size_t)0 );
40  //beta[ 0 ] = std::sqrt( beta[ 0 ] );
41 
43  for ( size_t i = 0; i < n; i ++ )
44  U( i, (size_t)0 ) /= beta[ 0 ];
45 
47  //A.NormalizedMultiply( 1, w.data(), U.data() );
48  for ( size_t i = 0; i < n; i ++ ) w[ i ] = U[ i ];
49  A.Multiply( w );
50 
52  for ( size_t i = 0; i < n; i ++ )
53  {
54  alpha[ 0 ] += w[ i ] * U( i, (size_t)0 );
55  }
56 
58  for ( size_t i = 0; i < n; i ++ )
59  {
60  w[ i ] = w[ i ] - alpha[ 0 ] * U( i, (size_t)0 );
61  }
62 
64  for ( size_t iter = 1; iter < nkrylov; iter ++ )
65  {
66 
68  for ( size_t i = 0; i < n; i ++ )
69  {
70  beta[ iter ] += w[ i ] * w[ i ];
71  }
72  beta[ iter ] = std::sqrt( beta[ iter ] );
73 
74  if ( beta[ iter ] == 0.0 )
75  {
76  printf( "problemaic\n" );
77  exit( 1 );
78  }
79  else
80  {
82  for ( size_t i = 0; i < n; i ++ )
83  {
84  U( i, iter ) = w[ i ] / beta[ iter ];
85  }
86  }
87 
89  //for ( size_t i = 0; i < n; i ++ ) w[ i ] = 0.0;
90  //A.NormalizedMultiply( 1, w.data(), U.data() + iter * n );
91  for ( size_t i = 0; i < n; i ++ ) w[ i ] = U( i, iter );
92  A.Multiply( w );
93 
95  for ( size_t i = 0; i < n; i ++ )
96  {
97  alpha[ iter ] += w[ i ] * U( i, iter );
98  }
99 
101  for ( size_t i = 0; i < n; i ++ )
102  {
103  w[ i ] = w[ i ] - alpha[ iter ] * U( i ,iter );
104  w[ i ] = w[ i ] - beta[ iter ] * U( i ,iter - 1 );
105  }
106 
107  //printf( "alpha[ iter ] = %E, beta[ iter ] = %E\n",
108  // alpha[ iter ], beta[ iter ] );
109 
110  }
111 
113  hmlp::Data<T> D = alpha;
114  hmlp::Data<T> E = beta;
115  hmlp::Data<T> Z( nkrylov, nkrylov, 0.0 );
116  hmlp::Data<T> work( 2 * nkrylov - 2, 1, 0.0 );
117  xstev(
118  "Vectors", nkrylov,
119  D.data(),
120  E.data() + 1,
121  Z.data(), nkrylov, work.data() );
122 
123 
124  //for ( size_t j = 0; j < nkrylov; j ++ )
125  //{
126  // printf( "Sigma[ %lu ] = %E, residual = %E\n",
127  // j, D[ j ], Z( nkrylov - 1, j ) * beta[ j ] );
128  //}
129 
131  xgemm( "Transpose", "Transpose",
132  r, n, nkrylov,
133  1.0, Z.columndata( nkrylov - r ), nkrylov,
134  U.data(), n,
135  0.0, V.data(), r );
136 
138  for ( size_t j = 0; j < r; j ++ )
139  {
140  Sigma[ j ] = alpha[ j ];
141  }
142 
143 };
147 };
149 #endif
double xnrm2(int n, double *x, int incx)
DNRM2 wrapper.
Definition: blas_lapack.cpp:83
void xstev(const char *jobz, int n, double *D, double *E, double *Z, int ldz, double *work)
Definition: blas_lapack.cpp:1127
void xgemm(const char *transA, const char *transB, int m, int n, int k, double alpha, const double *A, int lda, const double *B, int ldb, double beta, double *C, int ldc)
DGEMM wrapper.
Definition: blas_lapack.cpp:130
void lanczos(VIRTUALMATRIX &A, size_t n, size_t r, size_t nkrylov, std::vector< T > &Sigma, std::vector< T > &V)
Definition: lanczos.hpp:20
Definition: gofmm.hpp:83