MADNESS  0.10.1
SVDTensor.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31  $Id: srconf.h 2816 2012-03-23 14:59:52Z 3ru6ruWu $
32  */
33 #ifndef SRC_MADNESS_TENSOR_SVDTENSOR_H_
34 #define SRC_MADNESS_TENSOR_SVDTENSOR_H_
35 
36 #include <madness/tensor/srconf.h>
37 
38 namespace madness{
39 
40 
41 template<typename T>
42 class SVDTensor : public SRConf<T> {
43 public:
44  using SRConf<T>::SRConf;
45 
46  SVDTensor() : SRConf<T>() {}
47 
48  SVDTensor(const Tensor<T>& rhs, const double eps) {
49  if (rhs.has_data()) {
50 // *this=compute_svd(rhs,eps);
51  *this=compute_randomized_svd(rhs,eps);
52  }
53  }
54 
55  SVDTensor(const SVDTensor<T>& rhs) = default;
56 
57  SVDTensor(const SRConf<T>& rhs) : SRConf<T>(rhs) { }
58 
59  SVDTensor(const std::vector<long>& dims) : SRConf<T>(dims.size(),dims.data(),dims.size()/2) { }
60 
61  SVDTensor(const long ndims, const long* dims) : SRConf<T>(ndims,dims,ndims/2) { }
62 
63  SVDTensor(const Tensor<double>& weights, const Tensor<T>& vector1,
64  const Tensor<T>& vector2, const long& ndim,
65  const long* dims) : SRConf<T>(weights, vector1, vector2, ndim, dims, ndim/2) {}
66 
67  SVDTensor& operator=(const T& number) {
68  SRConf<T>& base=*this;
69  base=number;
70  return *this;
71  }
72 
73  long nCoeff() const {
74  return SRConf<T>::nCoeff();
75  }
76 
77  long rank() const {return SRConf<T>::rank();};
78 
79  /// reduce the rank using SVD
80  static SVDTensor compute_svd(const Tensor<T>& tensor,
81  const double& eps, std::array<long,2> vectordim={0,0});
82 
83  /// reduce the rank using SVD
84  static SVDTensor compute_randomized_svd(const Tensor<T>& tensor,
85  const double& eps, std::array<long,2> vectordim={0,0});
86 
87  /// compute an SVD from a given matrix and its range
88 
89  /// following Alg. 5.1 of HMT 2011
90  static SVDTensor compute_svd_from_range(const Tensor<T>& range, const Tensor<T>& matrix);
91 
92  /// compute an SVD from a given matrix and its range
93 
94  /// following Alg. 5.1 of HMT 2011
95  void recompute_from_range(const Tensor<T>& range);
96 
97 
98  /// concatenate all arguments into a single SRConf (i.e. adding them all up)
99  static SVDTensor<T> concatenate(const std::list<SVDTensor<T> >& addends) {
100 
101  if (addends.size()==0) return SVDTensor<T>();
102 
103  // collect all terms in a single SRConf
104  SRConf<T> result(addends.front().ndim(),addends.front().dims(),addends.front().nci_left);
105 
106  long totalrank=0;
107  for (auto a : addends) totalrank+=a.rank();
108  if (totalrank==0) return result;
109 
110  auto dimensions=result.make_vector_dimensions(totalrank);
112 
114  Tensor<T> vector0(result.nci_left+1,dimensions[0].data());
115  vector0=vector0.reshape(totalrank,vector0.size()/totalrank);
116  Tensor<T> vector1(result.ndim()-result.nci_left+1,dimensions[1].data());
117  vector1=vector1.reshape(totalrank,vector1.size()/totalrank);
118 
119  long start=0;
120  for (auto a: addends) {
121  MADNESS_ASSERT(compatible(result,a));
122  long end=start+a.rank()-1;
123  vector0(Slice(start,end),_)=a.flat_vector(0);
124  vector1(Slice(start,end),_)=a.flat_vector(1);
125  weights(Slice(start,end))=a.weights_;
126  start+=a.rank();
127  }
128 
129  result.set_vectors_and_weights(weights,vector0,vector1);
130  return SVDTensor(result);
131 
132  }
133 
134  SVDTensor<T>& emul(const SVDTensor<T>& other) {
135  const SRConf<T>& base=other;
136  SRConf<T>::emul(base);
137  return *this;
138  }
139 
141  this->scale(alpha);
142  this->append(rhs,beta);
143  return *this;
144  }
145 
146  // reduce the rank using a divide-and-conquer approach
147  void divide_and_conquer_reduce(const double& thresh);
148 
149  void orthonormalize(const double& thresh);
150 
151  void orthonormalize_random(const double& thresh);
152 
153  void truncate_svd(const double& thresh);
154 
155  static std::string reduction_algorithm();
156  static void set_reduction_algorithm(const std::string alg);
157 
158 private:
159 
160 public:
161 
162  template <typename R, typename Q>
164  const SVDTensor<R>& t, const Tensor<Q>& c);
165 
166  template <typename R, typename Q>
168  const SVDTensor<R>& t, const Tensor<Q> c[]);
169 
170  template <typename R, typename Q>
172  const SVDTensor<R>& t, const Tensor<Q>& c, const int axis);
173 
174  template <typename R, typename Q>
176  const SVDTensor<R>& t1, const SVDTensor<Q>& t2);
177 
178  friend SVDTensor<T> reduce(std::list<SVDTensor<T> >& addends, double eps) {
179  SVDTensor<T>& ref=addends.front();
180  if (ref.reduction_algorithm()=="divide_conquer") {
181  SVDTensor<T> result=SVDTensor<T>::concatenate(addends);
182  result.divide_and_conquer_reduce(eps);
183  return result;
184  } else if (ref.reduction_algorithm()=="full") {
186  Tensor<T> full=tmp.reconstruct();
187  return SVDTensor<T>(full,eps);
188  } else if (ref.reduction_algorithm()=="rmd") {
189  SVDTensor<T> result=SVDTensor<T>::concatenate(addends);
190  result.orthonormalize_random(eps);
191  return result;
192  } else {
193  MADNESS_EXCEPTION("unknown reduction algorithm in SVDTensor.h",1);
194  return SVDTensor<T>();
195  }
196 
197  }
198 
199  friend SVDTensor<T> copy(const SVDTensor<T>& rhs) {
200  const SRConf<T>& base=rhs;
201  return SVDTensor<T>(copy(base));
202  }
203 
204 };
205 
206 template <typename R, typename Q>
208  const SVDTensor<R>& t, const Tensor<Q>& c) {
210 }
211 
212 template <typename R, typename Q>
214  const SVDTensor<R>& t, const Tensor<Q> c[]) {
216 }
217 
218 template <typename R, typename Q>
220  const SVDTensor<R>& t, const Tensor<Q>& c, const int axis) {
222 }
223 
224 }
225 
226 
227 
228 #endif /* SRC_MADNESS_TENSOR_SVDTENSOR_H_ */
const long * dims() const
Returns the array of tensor dimensions.
Definition: basetensor.h:153
long ndim() const
Returns the number of dimensions in the tensor.
Definition: basetensor.h:144
long size() const
Returns the number of elements in the tensor.
Definition: basetensor.h:138
Definition: srconf.h:67
long nci_left
separation dimensions: A(n,m) -> A(r,n) B(r,m), with n={k1,k2},m={k3,k4,k5..) multi-indices
Definition: srconf.h:93
TensorTypeData< T >::float_scalar_type float_scalar_type
Definition: srconf.h:73
unsigned int nCoeff() const
return the number of coefficients
Definition: srconf.h:709
Tensor< T > reconstruct() const
reconstruct this to return a full tensor
Definition: srconf.h:674
double weights(const unsigned int &i) const
return the weight
Definition: srconf.h:671
SRConf< T > & emul(const SRConf< T > &other)
perform elementwise Hadamard product
Definition: srconf.h:457
void set_vectors_and_weights(const Tensor< typename Tensor< T >::scalar_type > &weights, const Tensor< T > &vector1, const Tensor< T > &vector2)
Definition: srconf.h:234
long rank() const
return the logicalrank
Definition: srconf.h:661
friend bool compatible(const SRConf &lhs, const SRConf &rhs)
check compatibility
Definition: srconf.h:819
void append(const SRConf< T > &rhs, const double fac=1.0)
append configurations of rhs to this
Definition: srconf.h:300
void scale(const double &fac)
scale this by a number
Definition: srconf.h:812
std::array< std::array< long, TENSOR_MAXDIM >, 2 > make_vector_dimensions(const long rank) const
deduce the dimensions of the left and right singular vectors from the tensor dimensions
Definition: srconf.h:216
Definition: SVDTensor.h:42
long nCoeff() const
Definition: SVDTensor.h:73
SVDTensor(const std::vector< long > &dims)
Definition: SVDTensor.h:59
void truncate_svd(const double &thresh)
Definition: SVDTensor.cc:239
friend SVDTensor< TENSOR_RESULT_TYPE(R, Q)> general_transform(const SVDTensor< R > &t, const Tensor< Q > c[])
Definition: SVDTensor.h:213
void divide_and_conquer_reduce(const double &thresh)
reduce the rank using a divide-and-conquer approach
Definition: SVDTensor.cc:172
void recompute_from_range(const Tensor< T > &range)
compute an SVD from a given matrix and its range
Definition: SVDTensor.cc:148
SVDTensor(const long ndims, const long *dims)
Definition: SVDTensor.h:61
static SVDTensor compute_svd(const Tensor< T > &tensor, const double &eps, std::array< long, 2 > vectordim={0, 0})
reduce the rank using SVD
Definition: SVDTensor.cc:63
SVDTensor()
Definition: SVDTensor.h:46
SVDTensor(const SRConf< T > &rhs)
Definition: SVDTensor.h:57
friend SVDTensor< TENSOR_RESULT_TYPE(R, Q)> transform(const SVDTensor< R > &t, const Tensor< Q > &c)
Definition: SVDTensor.h:207
static SVDTensor compute_svd_from_range(const Tensor< T > &range, const Tensor< T > &matrix)
compute an SVD from a given matrix and its range
Definition: SVDTensor.cc:130
SVDTensor(const Tensor< double > &weights, const Tensor< T > &vector1, const Tensor< T > &vector2, const long &ndim, const long *dims)
Definition: SVDTensor.h:63
SVDTensor & operator=(const T &number)
Definition: SVDTensor.h:67
SVDTensor(const SVDTensor< T > &rhs)=default
static void set_reduction_algorithm(const std::string alg)
Definition: SVDTensor.cc:47
SVDTensor(const Tensor< T > &rhs, const double eps)
Definition: SVDTensor.h:48
SVDTensor< T > & gaxpy(T alpha, const SVDTensor< T > &rhs, T beta)
Definition: SVDTensor.h:140
friend SVDTensor< TENSOR_RESULT_TYPE(R, Q)> outer(const SVDTensor< R > &t1, const SVDTensor< Q > &t2)
friend SVDTensor< T > reduce(std::list< SVDTensor< T > > &addends, double eps)
Definition: SVDTensor.h:178
SVDTensor< T > & emul(const SVDTensor< T > &other)
Definition: SVDTensor.h:134
static std::string reduction_algorithm()
Definition: SVDTensor.cc:52
long rank() const
Definition: SVDTensor.h:77
static SVDTensor compute_randomized_svd(const Tensor< T > &tensor, const double &eps, std::array< long, 2 > vectordim={0, 0})
reduce the rank using SVD
Definition: SVDTensor.cc:97
friend SVDTensor< T > copy(const SVDTensor< T > &rhs)
Definition: SVDTensor.h:199
void orthonormalize_random(const double &thresh)
Definition: SVDTensor.cc:220
void orthonormalize(const double &thresh)
Definition: SVDTensor.cc:201
static SVDTensor< T > concatenate(const std::list< SVDTensor< T > > &addends)
concatenate all arguments into a single SRConf (i.e. adding them all up)
Definition: SVDTensor.h:99
friend SVDTensor< TENSOR_RESULT_TYPE(R, Q)> transform_dir(const SVDTensor< R > &t, const Tensor< Q > &c, const int axis)
Definition: SVDTensor.h:219
A slice defines a sub-range or patch of a dimension.
Definition: slice.h:103
Traits class to specify support of numeric types.
Definition: type_data.h:56
A tensor is a multidimension array.
Definition: tensor.h:317
Tensor< T > reshape(int ndimnew, const long *d)
Returns new view/tensor reshaping size/number of dimensions to conforming tensor.
Definition: tensor.h:1384
bool has_data() const
Definition: tensor.h:1886
Definition: y.cc:25
static const double R
Definition: csqrt.cc:46
auto T(World &world, response_space &f) -> response_space
Definition: global_functions.cc:34
const double beta
Definition: gygi_soltion.cc:62
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition: madness_exception.h:119
#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
GenTensor< TENSOR_RESULT_TYPE(R, Q)> general_transform(const GenTensor< R > &t, const Tensor< Q > c[])
Definition: gentensor.h:274
GenTensor< TENSOR_RESULT_TYPE(R, Q)> transform_dir(const GenTensor< R > &t, const Tensor< Q > &c, const int axis)
Definition: lowranktensor.h:1099
static const Slice _(0,-1, 1)
TENSOR_RESULT_TYPE(T, R) inner(const Function< T
Computes the scalar/inner product between two functions.
Definition: vmra.h:1059
std::vector< Function< TENSOR_RESULT_TYPE(T, R), NDIM > > transform(World &world, const std::vector< Function< T, NDIM > > &v, const Tensor< R > &c, bool fence=true)
Transforms a vector of functions according to new[i] = sum[j] old[j]*c[j,i].
Definition: vmra.h:689
static const double a
Definition: nonlinschro.cc:118
double Q(double a)
Definition: relops.cc:20
static const double c
Definition: relops.cc:10
static const double thresh
Definition: rk.cc:45
Definition: test_ccpairfunction.cc:22
const double alpha
Definition: test_coulomb.cc:54
std::size_t axis
Definition: testpdiff.cc:59