36 #ifdef MADNESS_HAS_EIGEN3
39 using madness::Tensor;
49 #include <Eigen/Dense>
50 using namespace Eigen;
59 #endif //MADNESS_FORINT
90 for (
integer j=0; j<n; ++j,++p1,++p0) { *p0 = *p1; }
114 template <
typename T>
115 void svd(
const Tensor<T>&
a, Tensor<T>& U,
116 Tensor<
typename Tensor<T>::scalar_type >& s, Tensor<T>& VT) {
118 integer m = a.dim(0), n = a.dim(1), rmax = min<int>(
m,n);
120 s = Tensor< typename Tensor<T>::scalar_type >(rmax);
121 U = Tensor<T>(
m,rmax);
122 VT = Tensor<T>(rmax,n);
124 Eigen::Matrix<T, Dynamic, Dynamic>
g(n,m);
127 copy_mad2eigen2( a.size(), a.ptr(),
g.data());
130 JacobiSVD< Eigen::Matrix<T, Dynamic, Dynamic>,HouseholderQRPreconditioner> svdm(
g, ComputeThinU | ComputeThinV);
132 Eigen::Matrix<T, Dynamic, Dynamic> dU = svdm.matrixV();
133 Eigen::Matrix<T, Dynamic, Dynamic> dV = svdm.matrixU();
135 copy_mad2eigen2( s.size(), svdm.singularValues().data(), s.ptr());
137 dU.transposeInPlace();
138 copy_mad2eigen2( VT.size(), dV.data(), VT.ptr());
139 copy_mad2eigen2( U.size(), dU.data(), U.ptr());
165 template <
typename T>
166 void gelss(
const Tensor<T>& a,
const Tensor<T>&
b,
double rcond,
167 Tensor<T>& x, Tensor<
typename Tensor<T>::scalar_type >& s,
168 long& rank, Tensor<
typename Tensor<T>::scalar_type>& sumsq) {
169 TENSOR_ASSERT(a.ndim() == 2,
"gelss requires matrix",a.ndim(),&
a);
170 integer n = a.dim(1), nrhs = b.dim(1);
171 TENSOR_ASSERT(b.ndim() <= 2,
"gelss require a vector or matrix for the RHS",b.ndim(),&
b);
172 TENSOR_ASSERT(a.dim(0) == b.dim(0),
"gelss matrix and RHS must conform",b.ndim(),&
b);
174 s = Tensor< typename Tensor<T>::scalar_type >(n);
177 Eigen::Matrix<T, Dynamic, Dynamic>
g(n,n);
178 copy_mad2eigen2( AT.size(), AT.ptr(),
g.data());
189 x = Tensor<T>(n,nrhs);
190 bT = Tensor<T>(n,nrhs);
194 Eigen::Matrix<T, Dynamic, Dynamic> h(n,nrhs);
195 copy_mad2eigen2( b.size(), bT.ptr(), h.data());
198 JacobiSVD< Eigen::Matrix<T, Dynamic, Dynamic> > svdm(
g, ComputeThinU | ComputeThinV);
199 Eigen::Matrix<T, Dynamic, Dynamic> sol = svdm.solve(h);
200 sol.transposeInPlace();
202 copy_mad2eigen2( b.size(), sol.data(), x.ptr());
204 rank = svdm.singularValues().nonZeros();
207 copy_mad2eigen2( s.size(), svdm.singularValues().data(), s.ptr());
221 template <
typename T>
222 void syev(
const Tensor<T>& a,
223 Tensor<T>&
V, Tensor<
typename Tensor<T>::scalar_type >& e) {
224 TENSOR_ASSERT(a.ndim() == 2,
"syev requires a matrix",a.ndim(),&
a);
225 TENSOR_ASSERT(a.dim(0) == a.dim(1),
"syev requires square matrix",0,&
a);
230 Eigen::Matrix<T, Dynamic, Dynamic>
g(n,n);
231 copy_mad2eigen2( a.size(), a.ptr(),
g.data());
232 Eigen::Matrix<T, Dynamic, Dynamic> gT =
g.transpose();
234 SelfAdjointEigenSolver< Eigen::Matrix<T, Dynamic, Dynamic> > sol(gT);
236 Eigen::Matrix<T, Dynamic, Dynamic> ev = sol.eigenvectors();
242 e = Tensor< typename Tensor<T>::scalar_type >(n);
245 copy_mad2eigen2( e.size(), sol.eigenvalues().data(), e.ptr());
249 copy_mad2eigen2( V.size(), ev.data(), V.ptr());
267 template <
typename T>
271 Eigen::Matrix<T, Dynamic, Dynamic>
g(n,n);
272 copy_mad2eigen2( a.size(), a.ptr(),
g.data());
273 g.transposeInPlace();
275 LLT< Eigen::Matrix<T, Dynamic, Dynamic> > ColDec(
g);
276 Eigen::Matrix<T, Dynamic, Dynamic>
L = ColDec.matrixU();
278 copy_mad2eigen2( a.size(), L.data(), a.ptr());
281 for (
int i=0; i<n; ++i)
282 for (
int j=0; j<i; ++j)
299 template <
typename T>
300 void gesv(
const Tensor<T>& a,
const Tensor<T>& b, Tensor<T>& x) {
301 TENSOR_ASSERT(a.ndim() == 2,
"gesve requires matrix",a.ndim(),&
a);
302 integer n = a.dim(0), m = a.dim(1), nrhs = b.dim(1);
304 TENSOR_ASSERT(b.ndim() <= 2,
"gesve require a vector or matrix for the RHS",b.ndim(),&
b);
305 TENSOR_ASSERT(a.dim(0) == b.dim(0),
"gesve matrix and RHS must conform",b.ndim(),&
b);
311 typedef typename TensorTypeData<T>::scalar_type scalar_type;
314 Eigen::Matrix<T, Dynamic, Dynamic>
g(n,n);
315 copy_mad2eigen2( AT.size(), AT.ptr(),
g.data());
325 x = Tensor<T>(n,nrhs);
329 Eigen::Matrix<T, Dynamic, Dynamic> h(n,nrhs);
330 copy_mad2eigen2( b.size(), bT.ptr(), h.data());
332 Eigen::Matrix<T, Dynamic, Dynamic> sol =
g.householderQr().solve(h);
335 sol.transposeInPlace();
336 copy_mad2eigen2( b.size(), sol.data(), x.ptr());
353 template <
typename T>
354 void sygv(
const Tensor<T>& a,
const Tensor<T>&
B,
int itype,
355 Tensor<T>& V, Tensor<
typename Tensor<T>::scalar_type >& e) {
356 TENSOR_ASSERT(a.ndim() == 2,
"sygv requires a matrix",a.ndim(),&
a);
357 TENSOR_ASSERT(a.dim(0) == a.dim(1),
"sygv requires square matrix",0,&
a);
358 TENSOR_ASSERT(B.ndim() == 2,
"sygv requires a matrix",B.ndim(),&
a);
359 TENSOR_ASSERT(B.dim(0) == B.dim(1),
"sygv requires square matrix",0,&
a);
364 e = Tensor<typename Tensor<T>::scalar_type>(n);
366 Eigen::Matrix<T, Dynamic, Dynamic>
g(n,n);
369 copy_mad2eigen2( a.size(), aT.ptr(),
g.data());
370 Eigen::Matrix<T, Dynamic, Dynamic> gT =
g.transpose();
372 Eigen::Matrix<T, Dynamic, Dynamic> h(n,n);
375 copy_mad2eigen2( b.size(), bT.ptr(), h.data());
376 Eigen::Matrix<T, Dynamic, Dynamic> hT = h.transpose();
378 GeneralizedSelfAdjointEigenSolver<Eigen::Matrix<T, Dynamic, Dynamic>> sol(
g, h);
380 Eigen::Matrix<T, Dynamic, Dynamic> ev = sol.eigenvectors();
385 ev.transposeInPlace();
386 copy_mad2eigen2( V.size(), ev.data(), V.ptr());
387 copy_mad2eigen2( e.size(), sol.eigenvalues().data(), e.ptr());
392 #endif //MADNESS_HAS_EIGEN3
Tensor< double > B
Definition: tdse1d.cc:167
void gesv(const Tensor< T > &a, const Tensor< T > &b, Tensor< T > &x)
Solve Ax = b for general A using the LAPACK *gesv routines.
Definition: lapack.cc:339
NDIM const Function< R, NDIM > & g
Definition: mra.h:2179
#define TENSOR_ASSERT(condition, msg, value, t)
Definition: tensorexcept.h:130
Tensor< T > conj_transpose(const Tensor< T > &t)
Returns a new deep copy of the complex conjugate transpose of the input tensor.
Definition: tensor.h:1954
void gelss(const Tensor< T > &a, const Tensor< T > &b, double rcond, Tensor< T > &x, Tensor< typename Tensor< T >::scalar_type > &s, long &rank, Tensor< typename Tensor< T >::scalar_type > &sumsq)
Solve Ax = b for general A using the LAPACK *gelss routines.
Definition: lapack.cc:393
const double L
Definition: 3dharmonic.cc:123
double V(const Vector< double, 3 > &r)
Definition: apps/ii/hatom_energy.cc:46
void syev(const Tensor< T > &A, Tensor< T > &V, Tensor< typename Tensor< T >::scalar_type > &e)
Real-symmetric or complex-Hermitian eigenproblem.
Definition: lapack.cc:478
Defines and implements most of Tensor.
const T1 &f1 return GTEST_2_TUPLE_() T(f0, f1)
#define max(a, b)
Definition: lda.h:53
Function< T, NDIM > copy(const Function< T, NDIM > &f, const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap, bool fence=true)
Create a new copy of the function with different distribution and optional fence. ...
Definition: mra.h:1835
const mpreal min(const mpreal &x, const mpreal &y)
Definition: mpreal.h:2675
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
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:273
int integer
Definition: DFcode/fci/crayio.c:25
const double m
Definition: gfit.cc:199
Defines simple templates for printing to std::cout "a la Python".
void cholesky(Tensor< T > &A)
Compute the Cholesky factorization.
Definition: lapack.cc:551
void sygv(const Tensor< T > &A, const Tensor< T > &B, int itype, Tensor< T > &V, Tensor< typename Tensor< T >::scalar_type > &e)
Generalized real-symmetric or complex-Hermitian eigenproblem.
Definition: lapack.cc:519
Tensor< T > transpose(const Tensor< T > &t)
Returns a new deep copy of the transpose of the input tensor.
Definition: tensor.h:1945
#define restrict
Definition: config.h:403
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
FLOAT b(int j, FLOAT z)
Definition: y1.cc:79