JDFTx  1.1.2
matrix.h
1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman
3 
4 This file is part of JDFTx.
5 
6 JDFTx 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 3 of the License, or
9 (at your option) any later version.
10 
11 JDFTx 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 JDFTx. If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #ifndef JDFTX_ELECTRONIC_MATRIX_H
21 #define JDFTX_ELECTRONIC_MATRIX_H
22 
23 #include <electronic/common.h>
24 #include <core/ManagedMemory.h>
25 #include <core/matrix3.h>
26 #include <core/scaled.h>
27 #include <gsl/gsl_cblas.h>
28 
30 class diagMatrix : public std::vector<double>
31 {
32 public:
33  diagMatrix(int N=0, double d=0.) : std::vector<double>(N,d) {}
34  int nRows() const { return size(); }
35  int nCols() const { return size(); }
36  bool isScalar(double absTol=1e-14, double relTol=1e-14) const;
37 
38  diagMatrix& operator*=(double s) { for(double& d: *this) d*=s; return *this; }
39 
40  //Splicing operations:
41  diagMatrix operator()(int iStart, int iStop) const;
42  diagMatrix operator()(int iStart, int iStep, int iStop) const;
43  void set(int iStart, int iStop, const diagMatrix& m);
44  void set(int iStart, int iStep, int iStop, const diagMatrix& m);
45 
46  void scan(FILE* fp);
47  void print(FILE* fp, const char* fmt="%lg\t") const;
48 
49  //Inter-process communication:
50  void send(int dest, int tag=0) const; //send to another process
51  void recv(int src, int tag=0); //receive from another process
52  void bcast(int root=0); //synchronize across processes (using value on specified root process)
53  void allReduce(MPIUtil::ReduceOp op, bool safeMode=false); //apply all-to-all reduction (see MPIUtil::allReduce)
54 };
55 
57 class matrix : public ManagedMemory
58 {
59  int nr;
60  int nc;
61 
62 public:
63  int nRows() const { return nr; }
64  int nCols() const { return nc; }
65  int index(int i, int j) const { return nr*j+i; }
66  explicit operator bool() const { return nr*nc; }
67 
68  void init(int nrows,int ncols, bool onGpu=false);
69  void reshape(int nrows, int ncols);
70  matrix(int nrows=0, int ncols=0, bool onGpu=false);
71  matrix(const matrix& m1);
72  matrix(matrix&& m1);
73  matrix(const diagMatrix&);
74  matrix(const std::vector<complex>&);
75  explicit matrix(const matrix3<>&);
76 
77  matrix& operator=(const matrix& m1);
78  matrix& operator=(matrix&& m1);
79 
81  complex operator()(int i, int j) const;
82 
84  matrix operator()(int iStart, int iStop, int jStart, int jStop) const { return (*this)(iStart,1,iStop, jStart,1,jStop); }
85 
87  matrix operator()(int iStart, int iStep, int iStop, int jStart, int jStep, int jStop) const;
88 
90  void set(int i, int j, complex m);
91 
93  void set(int iStart, int iStop, int jStart, int jStop, const matrix& m) { set(iStart,1,iStop, jStart,1,jStop, m); }
94 
96  void set(int iStart, int iStep, int iStop, int jStart, int jStep, int jStop, const matrix& m);
97 
98  void scan(FILE* fp, const char* fmt="%lg%+lgi");
99  void scan_real(FILE* fp);
100  void print(FILE* fp, const char* fmt="%lg%+lgi\t") const;
101  void print_real(FILE* fp, const char* fmt="%lg\t") const;
102 
103  void diagonalize(matrix& evecs, diagMatrix& eigs) const;
104  void diagonalize(matrix& levecs, std::vector<complex>& eigs, matrix& revecs) const;
105  void svd(matrix& U, diagMatrix& S, matrix& Vdag) const;
106 };
107 
110 { const matrix& mat;
111  double scale;
112  CBLAS_TRANSPOSE op;
113 
114  int nRows() const { return op==CblasNoTrans ? mat.nRows() : mat.nCols(); }
115  int nCols() const { return op==CblasNoTrans ? mat.nCols() : mat.nRows(); }
116  complex conjOp(complex a) const { return (op==CblasConjTrans) ? a.conj() : a; }
117  int index(int i, int j) const { return op==CblasNoTrans ? mat.index(i,j) : mat.index(j,i); }
118 
120  matrixScaledTransOp(const matrix& mat, double scale=1.0, CBLAS_TRANSPOSE op=CblasNoTrans)
121  : mat(mat), scale(scale), op(op) {}
122 
124  matrixScaledTransOp(const scaled<matrix>& smat, CBLAS_TRANSPOSE op=CblasNoTrans)
125  : mat(smat.data), scale(smat.scale), op(op) {}
126 
127  operator matrix() const;
128 
129  //Scaling:
130  matrixScaledTransOp& operator*=(double s) { scale *= s; return *this; }
131  matrixScaledTransOp operator*(double s) const { return matrixScaledTransOp(mat,scale*s,op); }
132  friend matrixScaledTransOp operator*(double s, const matrixScaledTransOp& A) { return A * s; }
133 };
134 matrix conj(const scaled<matrix>& A);
135 matrixScaledTransOp dagger(const scaled<matrix>& A);
136 matrixScaledTransOp transpose(const scaled<matrix>& A);
137 matrix dagger_symmetrize(const scaled<matrix>& A);
138 matrix transpose_symmetrize(const scaled<matrix>& A);
139 
140 
141 //------------ Arithmetic ------------------
142 
143 inline matrix& operator*=(matrix& m, double s) { scale(s, m); return m; }
144 inline scaled<matrix> operator*(double s, const matrix &m) { return scaled<matrix>(m, s); }
145 inline scaled<matrix> operator*(const matrix &m, double s) { return scaled<matrix>(m, s); }
146 inline scaled<matrix> operator-(const matrix &m) { return scaled<matrix>(m, -1); }
147 inline matrix& operator*=(matrix& m, complex s) { scale(s, m); return m; }
148 inline matrix operator*(complex s, const matrix &m) { matrix sm(m); sm *= s; return sm; }
149 inline matrix operator*(const matrix &m, complex s) { matrix sm(m); sm *= s; return sm; }
150 inline diagMatrix operator*(double s, const diagMatrix &m) { diagMatrix ret(m); return ret*=s; }
151 inline diagMatrix operator*(const diagMatrix &m, double s) { diagMatrix ret(m); return ret*=s; }
152 inline diagMatrix operator-(const diagMatrix &m) { return m * (-1); }
153 
155 matrix operator*(const matrix&, const diagMatrix&);
156 matrix operator*(const diagMatrix&, const matrix&);
157 diagMatrix operator*(const diagMatrix&, const diagMatrix&);
158 
159 inline matrix& operator+=(matrix &m1, const matrix &m2) { if(m1) axpy(1.0, m2, m1); else m1 = m2; return m1; }
160 inline matrix& operator-=(matrix &m1, const matrix &m2) { if(m1) axpy(-1.0, m2, m1); else m1 = -m2; return m1; }
161 inline matrix operator+(const matrix &m1, const matrix &m2) { matrix tm(m1); tm += m2; return tm; }
162 inline matrix operator-(const matrix &m1, const matrix &m2) { matrix tm(m1); tm -= m2; return tm; }
163 void axpy(double alpha, const diagMatrix& x, matrix& y);
164 inline matrix& operator+=(matrix& m, const diagMatrix& d) { if(m) axpy(1., d, m); else m = d; return m; }
165 inline matrix& operator-=(matrix& m, const diagMatrix& d) { if(m) axpy(-1., d, m); else m=-d; return m; }
166 inline matrix operator+(const matrix& m, const diagMatrix& d) { matrix ret(m); ret+=d; return ret; }
167 inline matrix operator+(const diagMatrix& d, const matrix& m) { matrix ret(m); ret+=d; return ret; }
168 inline matrix operator-(const matrix& m, const diagMatrix& d) { matrix ret(m); ret-=d; return ret; }
169 inline matrix operator-(const diagMatrix& d, const matrix& m) { matrix ret(-m); ret+=d; return ret; }
170 void axpy(double alpha, const diagMatrix& x, diagMatrix& y);
171 inline diagMatrix& operator+=(diagMatrix& d1, const diagMatrix& d2) { axpy(1., d2, d1); return d1; }
172 inline diagMatrix& operator-=(diagMatrix& d1, const diagMatrix& d2) { axpy(-1., d2, d1); return d1; }
173 inline diagMatrix operator+(const diagMatrix& d1, const diagMatrix& d2) { diagMatrix ret(d1); return ret+=d2; }
174 inline diagMatrix operator-(const diagMatrix& d1, const diagMatrix& d2) { diagMatrix ret(d1); return ret-=d2; }
175 
176 //Functions required for using the Minimizable template on matrices:
177 diagMatrix clone(const diagMatrix& x);
178 matrix clone(const matrix& x);
179 double dot(const diagMatrix& x, const diagMatrix& y);
180 double dot(const matrix& x, const matrix& y);
181 void randomize(diagMatrix& x);
182 void randomize(matrix& x);
183 
184 
185 //------- Nonlinear matrix functions and their gradients ---------
186 
188 matrix inv(const matrix& A);
189 diagMatrix inv(const diagMatrix& A);
190 matrix invApply(const matrix& A, const matrix& b); //return inv(A) * b (A must be hermitian, positive-definite)
191 
193 matrix LU(const matrix& A);
194 
197 complex det(const matrix& A);
198 
200 double det(const diagMatrix& A);
201 
203 matrix pow(const matrix& A, double exponent, matrix* Aevecs=0, diagMatrix* Aeigs=0);
204 
206 matrix invsqrt(const matrix& A, matrix* Aevecs=0, diagMatrix* Aeigs=0);
207 
209 matrix cis(const matrix& A, matrix* Aevecs=0, diagMatrix* Aeigs=0);
210 
213 matrix cisInv(const matrix& A, matrix* Bevecs=0, diagMatrix* Beigs=0);
214 
216 matrix sqrt_grad(const matrix& grad_sqrtA, const matrix& Aevecs, const diagMatrix& Aeigs);
217 
219 matrix cis_grad(const matrix& grad_cisA, const matrix& Aevecs, const diagMatrix& Aeigs);
220 
221 
222 //------------ Misc matrix functions --------------
223 complex trace(const matrix &m);
224 double trace(const diagMatrix& m);
225 double nrm2(const diagMatrix& m);
226 diagMatrix diag(const matrix &m);
227 diagMatrix eye(int N);
228 matrix zeroes(int nRows, int nCols);
229 
232 {
233  const matrix& mBlock;
234  int nBlocks;
235  const std::vector<complex>* phaseArr;
236 public:
237  tiledBlockMatrix(const matrix& mBlock, int nBlocks, const std::vector<complex>* phaseArr=0);
238 
239  matrix operator*(const matrix&) const;
240 };
241 
242 #endif // JDFTX_ELECTRONIC_MATRIX_H
ScalarField pow(const ScalarField &, double alpha)
Elementwise power (preserve input)
CBLAS_TRANSPOSE op
pending operation (none, transpose or dagger)
Definition: matrix.h:112
Definition: scaled.h:25
Tptr operator*(const Tptr &in, double scaleFac)
Scalar multiply (preserve input)
Definition: Operators.h:116
void randomize(TptrCollection &x)
Initialize to normal random numbers:
Definition: ScalarFieldArray.h:154
Tptr conj(Tptr &&in)
Generic elementwise conjugate for complex data:
Definition: Operators.h:122
void scan(FILE *fp)
set submatrix to m at arbitrary increments
complex dot(const Tptr &X, const Tptr &Y)
Definition: Operators.h:196
double scale
pending scale factor
Definition: matrix.h:111
General complex matrix.
Definition: matrix.h:57
Template to avoid (delay) scaling operations on linear objects.
int index(int i, int j) const
Index into data()
Definition: matrix.h:65
Base class for managed-memory objects (that could potentially live on GPUs as well) ...
Definition: ManagedMemory.h:26
Real diagonal matrix.
Definition: matrix.h:30
Tptr & operator-=(Tptr &in, const Tptr &other)
Decrement.
Definition: Operators.h:170
int index(int i, int j) const
Index into data() with possible transpose.
Definition: matrix.h:117
const matrix & mat
matrix
Definition: matrix.h:110
Tptr clone(const Tptr &X)
Clone (NOTE: operator= is by reference for the ScalarField classes)
Definition: Operators.h:111
matrixScaledTransOp(const scaled< matrix > &smat, CBLAS_TRANSPOSE op=CblasNoTrans)
Create from a scaled matrix, with an optional op.
Definition: matrix.h:124
matrix operator()(int iStart, int iStop, int jStart, int jStop) const
get submatrix of elements (iStart <= i < iStop, jStart <= j < jStop)
Definition: matrix.h:84
matrixScaledTransOp(const matrix &mat, double scale=1.0, CBLAS_TRANSPOSE op=CblasNoTrans)
Create from a matrix with an optional scale and op:
Definition: matrix.h:120
bool isScalar(double absTol=1e-14, double relTol=1e-14) const
Check if all entries are identical within threshold.
Tptr operator+(const Tptr &in1, const Tptr &in2)
Add (preserve inputs)
Definition: Operators.h:171
ScalarField inv(const ScalarField &)
Elementwise reciprocal (preserve input)
Matrix with a pending scale and transpose operation.
Definition: matrix.h:109
void print(FILE *fp, const char *fmt="%lg\t") const
print (ascii) to stream
Complex number (need to define our own because we need operators for gpu code as well) ...
Definition: scalar.h:49
void axpy(double alpha, const Tptr &X, Tptr &Y)
Generic axpy for complex data types (Note: null pointers are treated as zero)
Definition: Operators.h:158
complex conjOp(complex a) const
return conjugate if op requires it
Definition: matrix.h:116
A block matrix formed by repeating (tiling) a dense matrix along the diagonal.
Definition: matrix.h:231
Tptr & operator+=(Tptr &in, const Tptr &other)
Increment.
Definition: Operators.h:169
Tptr operator-(const Tptr &in1, const Tptr &in2)
Subtract (preserve inputs)
Definition: Operators.h:175
double nrm2(const Tptr &X)
Definition: Operators.h:199