MADNESS  0.10.1
RandomizedMatrixDecomposition.h
Go to the documentation of this file.
1 
2 
3 #ifndef SRC_MADNESS_TENSOR_RANDOMIZEDMATRIXDECOMPOSITION_H_
4 #define SRC_MADNESS_TENSOR_RANDOMIZEDMATRIXDECOMPOSITION_H_
5 
7 
8 namespace madness {
9 
10 
11 /// simple factory pattern for the RandomizedMatrixDecomposition
12 struct RMDFactory {
13  long maxrank_=LONG_MAX;
14  long oversampling_=10;
15 
17 
18  RMDFactory& maxrank(const long mr) {
19  maxrank_=mr;
20  return *this;
21  }
22  RMDFactory& oversampling(const long os) {
23  oversampling_=os;
24  return *this;
25  }
26 
27 };
28 
29 
30 template<typename T>
32 
33 public:
35 
37 
39 
41  : maxrank(factory.maxrank_), oversampling(factory.oversampling_) {
42  }
43 
46  }
47 
48  /// check if the computed rank is too large
49  bool exceeds_maxrank() const {return (range.dim(1)>maxrank);}
50 
51  Tensor<T> get_range() const {return range;}
52 
53  /// compute the range of the matrix
54 
55  /// follows Halko, Martinsson, Tropp (2011), Alg. 4.2
56  /// the final range will satisfy for the input tensor A: || A - Q Q^T A || < eps
57  /// method will change member variables "range" and "maxrank"
58  /// @param[in] tensor the input tensor/matrix A (see matrixdim if not a matrix)
59  /// @param[in] eps the accuracy of the representation
60  /// @param[in] matrixdim how to reshape the tensor if it is not a matrix
61  /// @return range the range of the input tensor
62  Tensor<T> compute_range(const Tensor<T>& tensor,
63  const double& eps, std::array<long,2> matrixdim={0,0});
64 
65  /// compute the range of the matrix given in decomposed form
66 
67  /// see above;
68  /// Matrix is given by A(i,j)=columnspace(r,i) * rowspace(r,j)
69  /// @param[in] columnspace columnspace of the input tensor/matrix A
70  /// @param[in] rowspace rowspace of the input tensor/matrix A
71  /// @param[in] eps the accuracy of the representation
72  /// @return range the range of the input tensor
73  Tensor<T> compute_range(const Tensor<T>& columnspace, const Tensor<T>& rowspace,
74  const double& eps);
75 
76  /// return the error of the range Q
77 
78  /// explicitly compute the error measure || A - Q Q^T A ||
80  const Tensor<T>& range) {
82  return residual.normf();
83  }
84 
85  /// helper function
86  static Tensor<T> make_SVD_decaying_matrix(const Tensor<T>& matrix, const int n=1) {
87  Tensor<T> U,VT;
89  svd(matrix,U,s,VT);
90  for (long i=0; i<s.size(); ++i) {
91  s(i)*=exp(-i/n); // make singular values decay exponentially
92  U(_,i)*=s(i);
93  }
94  return inner(U,VT);
95  }
96 
97  /// resize Tensor to a matrix
98  static Tensor<T> resize_to_matrix(const Tensor<T>& matrix, std::array<long,2> vectordim={0,0}) {
99  // SVD works only with matrices (2D)
100  if (vectordim[0]==0) {
101  long dim1=matrix.ndim()/2; // integer division
102  vectordim[0]=vectordim[1]=1;
103  for (long i=0; i<dim1; ++i) vectordim[0]*=matrix.dim(i);
104  for (long i=dim1; i<matrix.ndim(); ++i) vectordim[1]*=matrix.dim(i);
105  MADNESS_ASSERT(vectordim[0]*vectordim[1]==matrix.size());
106  }
107  Tensor<T> values_eff=matrix.reshape(vectordim[0],vectordim[1]);
108  MADNESS_ASSERT(values_eff.ndim()==2);
109  return values_eff;
110  }
111 
112  void set_maxrank(const long max_rank) {
113  maxrank=max_rank;
114  }
115 
116 private:
117 
118  /// maximum rank to abort the decomposition
119  long maxrank=LONG_MAX;
120 
121  /// oversampling parameter
122  long oversampling=10;
123 
124  /// the range that spans the input matrix
126 
127  /// functor for forming Y = matrix * randomvector
128  struct Y_former {
130  std::string algo="matrix";
131 
132  Y_former(const Tensor<T>& matrix) : mat1(matrix), algo("matrix") {}
133  Y_former(const Tensor<T>& col, const Tensor<T>& row) : mat1(col), mat2(row), algo("col_row") {}
134 
135  long m() const {
136  if (algo=="matrix") return mat1.dim(0);
137  if (algo=="col_row") return mat1.dim(1);
138  throw;
139  return 0;
140  }
141 
142  long n() const {
143  if (algo=="matrix") return mat1.dim(1);
144  if (algo=="col_row") return mat2.dim(1);
145  throw;
146  return 0;
147 
148  }
149  long maxrank() const {
150  if (algo=="matrix") return std::min(mat1.dim(0),mat1.dim(1));
151  if (algo=="col_row") return mat1.dim(0);
152  throw;
153  return 0;
154  }
155  /// form Y with the transposed random trial vector as input
156  Tensor<T> operator()(const Tensor<T>& omegaT) const {
157  Tensor<T> Y;
158  if (algo=="matrix") {
159  Y=inner(mat1,omegaT,1,1);
160 
161  } else if (algo=="col_row") {
162  // compute col*row*omega
163  Y=inner(mat1,inner(mat2,omegaT,1,1),0,0);
164  }
165  return Y;
166 
167  }
168  };
169  /// perform the actual computation of the range
170  Tensor<T> do_compute_range(const Y_former& Y, const double& eps) const;
171 
172 
173 
174 };
175 
176 } /* namespace madness */
177 
178 #endif /* SRC_MADNESS_TENSOR_RANDOMIZEDMATRIXDECOMPOSITION_H_ */
Definition: RandomizedMatrixDecomposition.h:31
Tensor< T > range
the range that spans the input matrix
Definition: RandomizedMatrixDecomposition.h:125
static Tensor< T > resize_to_matrix(const Tensor< T > &matrix, std::array< long, 2 > vectordim={0, 0})
resize Tensor to a matrix
Definition: RandomizedMatrixDecomposition.h:98
void set_maxrank(const long max_rank)
Definition: RandomizedMatrixDecomposition.h:112
Tensor< T > do_compute_range(const Y_former &Y, const double &eps) const
perform the actual computation of the range
Definition: RandomizedMatrixDecomposition.cc:31
RandomizedMatrixDecomposition(const RandomizedMatrixDecomposition &other)=default
Tensor< T > compute_range(const Tensor< T > &tensor, const double &eps, std::array< long, 2 > matrixdim={0, 0})
compute the range of the matrix
Definition: RandomizedMatrixDecomposition.cc:12
long oversampling
oversampling parameter
Definition: RandomizedMatrixDecomposition.h:122
bool exceeds_maxrank() const
check if the computed rank is too large
Definition: RandomizedMatrixDecomposition.h:49
TensorTypeData< T >::scalar_type scalar_type
Definition: RandomizedMatrixDecomposition.h:34
RandomizedMatrixDecomposition(const RMDFactory &factory)
Definition: RandomizedMatrixDecomposition.h:40
Tensor< T > get_range() const
Definition: RandomizedMatrixDecomposition.h:51
static Tensor< T > make_SVD_decaying_matrix(const Tensor< T > &matrix, const int n=1)
helper function
Definition: RandomizedMatrixDecomposition.h:86
static scalar_type check_range(const Tensor< T > &matrix, const Tensor< T > &range)
return the error of the range Q
Definition: RandomizedMatrixDecomposition.h:79
long maxrank
maximum rank to abort the decomposition
Definition: RandomizedMatrixDecomposition.h:119
RandomizedMatrixDecomposition(const Tensor< T > &matrix, const double thresh)
Definition: RandomizedMatrixDecomposition.h:44
Traits class to specify support of numeric types.
Definition: type_data.h:56
A tensor is a multidimension array.
Definition: tensor.h:317
Definition: y.cc:25
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition: madness_exception.h:134
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
Function< T, NDIM > conj(const Function< T, NDIM > &f, bool fence=true)
Return the complex conjugate of the input function with the same distribution and optional fence.
Definition: mra.h:2046
static const Slice _(0,-1, 1)
void svd(const Tensor< T > &a, Tensor< T > &U, Tensor< typename Tensor< T >::scalar_type > &s, Tensor< T > &VT)
Compute the singluar value decomposition of an n-by-m matrix using *gesvd.
Definition: lapack.cc:739
double inner(response_space &a, response_space &b)
Definition: response_functions.h:442
static const double thresh
Definition: rk.cc:45
simple factory pattern for the RandomizedMatrixDecomposition
Definition: RandomizedMatrixDecomposition.h:12
long maxrank_
Definition: RandomizedMatrixDecomposition.h:13
long oversampling_
Definition: RandomizedMatrixDecomposition.h:14
RMDFactory & maxrank(const long mr)
Definition: RandomizedMatrixDecomposition.h:18
RMDFactory & oversampling(const long os)
Definition: RandomizedMatrixDecomposition.h:22
RMDFactory()
Definition: RandomizedMatrixDecomposition.h:16
functor for forming Y = matrix * randomvector
Definition: RandomizedMatrixDecomposition.h:128
long m() const
Definition: RandomizedMatrixDecomposition.h:135
Tensor< T > mat2
Definition: RandomizedMatrixDecomposition.h:129
Y_former(const Tensor< T > &col, const Tensor< T > &row)
Definition: RandomizedMatrixDecomposition.h:133
long maxrank() const
Definition: RandomizedMatrixDecomposition.h:149
long n() const
Definition: RandomizedMatrixDecomposition.h:142
Tensor< T > operator()(const Tensor< T > &omegaT) const
form Y with the transposed random trial vector as input
Definition: RandomizedMatrixDecomposition.h:156
Tensor< T > mat1
Definition: RandomizedMatrixDecomposition.h:129
std::string algo
Definition: RandomizedMatrixDecomposition.h:130
Y_former(const Tensor< T > &matrix)
Definition: RandomizedMatrixDecomposition.h:132
Defines and implements most of Tensor.
F residual(const F &f)
Definition: testcomplexfunctionsolver.cc:69