You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ABACUS_Matrix.h 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: ABACUS_Matrix.h
  6. Purpose: Declares square and rectangular matrix classes.
  7. ***********************************************************/
  8. #ifndef ABACUS_MATRIX_H
  9. #define ABACUS_MATRIX_H
  10. namespace ABACUS {
  11. // CLASS DEFINITIONS
  12. template <class T>
  13. class SQMat {
  14. private:
  15. int dim;
  16. T** M;
  17. public:
  18. SQMat (int N); // initializes all elements of this n by n matrix to zero
  19. SQMat (const SQMat& rhs); // copy constructor
  20. SQMat (const T& a, int N); // initialize to diagonal matrix with value a (NOT like in NR !!!)
  21. SQMat (const SQMat& a, const SQMat& b); // initialize to tensor product of a and b
  22. SQMat (const SQMat& a, int row_id, int col_id); // init by cutting row row_id and col col_id
  23. void Print ();
  24. SQMat& operator= (const SQMat& rhs); // assignment
  25. SQMat& operator= (const T& a); // assign 1 to diagonal elements (NOT like in NR !!!)
  26. inline T* operator[] (const int i); // subscripting: pointer to row i
  27. inline const T* operator[] (const int i) const;
  28. SQMat& operator+= (const T& a);
  29. SQMat& operator+= (const SQMat& a);
  30. SQMat& operator-= (const T& a);
  31. SQMat& operator-= (const SQMat& a);
  32. SQMat& operator*= (const T& a);
  33. SQMat& operator*= (const SQMat& a);
  34. inline int size() const;
  35. ~SQMat();
  36. };
  37. template <class T>
  38. SQMat<T>::SQMat (int N) : dim(N) , M(new T*[N])
  39. {
  40. M[0] = new T[N*N];
  41. for (int i = 1; i < N; i++) M[i] = M[i-1] + N;
  42. }
  43. template <class T>
  44. SQMat<T>::SQMat (const SQMat& rhs) : dim(rhs.dim) , M(new T*[dim])
  45. {
  46. int i,j;
  47. M[0] = new T[dim*dim];
  48. for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
  49. for (i = 0; i < dim; i++)
  50. for (j = 0; j < dim; j++) M[i][j] = rhs[i][j];
  51. }
  52. template <class T>
  53. SQMat<T>::SQMat (const T& a, int N) : dim(N) , M(new T*[dim])
  54. {
  55. int i, j;
  56. M[0] = new T[dim*dim];
  57. for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
  58. for (i = 0; i < dim; i++) {
  59. for (j = 0; j < dim; j++) M[i][j] = T(0);
  60. M[i][i] = a;
  61. }
  62. }
  63. template <class T>
  64. SQMat<T>::SQMat (const SQMat& a, const SQMat& b) : dim (a.dim * b.dim) , M(new T*[a.dim * b.dim])
  65. {
  66. M[0] = new T[a.dim * b.dim * a.dim * b.dim];
  67. for (int i = 1; i < a.dim * b.dim; ++i) M[i] = M[i-1] + a.dim * b.dim;
  68. for (int i1 = 0; i1 < a.dim; ++i1) {
  69. for (int i2 = 0; i2 < a.dim; ++i2) {
  70. for (int j1 = 0; j1 < b.dim; ++j1) {
  71. for (int j2 = 0; j2 < b.dim; ++j2) {
  72. M[i1 * (b.dim) + j1][i2 * (b.dim) + j2] = a[i1][i2] * b[j1][j2];
  73. }
  74. }
  75. }
  76. }
  77. }
  78. template <class T>
  79. SQMat<T>::SQMat (const SQMat&a, int row_id, int col_id) : dim (a.dim - 1) , M(new T*[dim])
  80. {
  81. if (dim == 0) {
  82. ABACUSerror("Error: chopping a row and col from size one matrix.");
  83. exit(1);
  84. }
  85. M[0] = new T[dim * dim];
  86. for (int i = 1; i < dim; ++i) M[i] = M[i-1] + dim;
  87. for (int i = 0; i < row_id; ++i)
  88. for (int j = 0; j < col_id; ++j) M[i][j] = a[i][j];
  89. for (int i = row_id; i < dim; ++i)
  90. for (int j = 0; j < col_id; ++j) M[i][j] = a[i+1][j];
  91. for (int i = 0; i < row_id; ++i)
  92. for (int j = col_id; j < dim; ++j) M[i][j] = a[i][j+1];
  93. for (int i = row_id; i < dim; ++i)
  94. for (int j = col_id; j < dim; ++j) M[i][j] = a[i+1][j+1];
  95. }
  96. // operators
  97. template <class T>
  98. void SQMat<T>::Print ()
  99. {
  100. std::cout << std::endl;
  101. for (int i = 0; i < dim; ++i) {
  102. for (int j = 0; j < dim; ++j) std::cout << M[i][j] << " ";
  103. std::cout << std::endl;
  104. }
  105. std::cout << std::endl;
  106. }
  107. template <class T>
  108. SQMat<T>& SQMat<T>::operator= (const SQMat<T>& rhs)
  109. {
  110. if (this != &rhs) {
  111. if (dim != rhs.dim) {
  112. ABACUSerror("Assignment between matrices of different dimensions. Bailing out.");
  113. exit(1);
  114. }
  115. for (int i = 0; i < dim; ++i)
  116. for (int j = 0; j < dim; ++j) M[i][j] = rhs[i][j];
  117. }
  118. return *this;
  119. }
  120. template <class T>
  121. SQMat<T>& SQMat<T>::operator= (const T& a)
  122. {
  123. for (int i = 0; i < dim; ++i) {
  124. for (int j = 0; j < dim; ++j)
  125. M[i][j] = T(0);
  126. M[i][i] = a;
  127. }
  128. return *this;
  129. }
  130. template <class T>
  131. inline T* SQMat<T>::operator[] (const int i)
  132. {
  133. return M[i];
  134. }
  135. template <class T>
  136. inline const T* SQMat<T>::operator[] (const int i) const
  137. {
  138. return M[i];
  139. }
  140. template <class T>
  141. SQMat<T>& SQMat<T>::operator+= (const T& a)
  142. {
  143. for (int i = 0; i < dim; ++i) M[i][i] += a;
  144. return *this;
  145. }
  146. template <class T>
  147. SQMat<T>& SQMat<T>::operator+= (const SQMat<T>& a)
  148. {
  149. if (dim != a.dim) {
  150. ABACUSerror("Incompatible matrix sizes in matrix operator +.");
  151. exit(1);
  152. }
  153. for (int i = 0; i < dim; ++i) {
  154. for (int j = 0; j < dim; ++j) {
  155. M[i][j] += a[i][j];
  156. }
  157. }
  158. return *this;
  159. }
  160. template <class T>
  161. SQMat<T>& SQMat<T>::operator-= (const T& a)
  162. {
  163. for (int i = 0; i < dim; ++i) M[i][i] -= a;
  164. return *this;
  165. }
  166. template <class T>
  167. SQMat<T>& SQMat<T>::operator-= (const SQMat<T>& a)
  168. {
  169. if (dim != a.dim) {
  170. ABACUSerror("Incompatible matrix sizes in matrix operator +.");
  171. exit(1);
  172. }
  173. for (int i = 0; i < dim; ++i) {
  174. for (int j = 0; j < dim; ++j) {
  175. M[i][j] -= a[i][j];
  176. }
  177. }
  178. return *this;
  179. }
  180. template <class T>
  181. SQMat<T>& SQMat<T>::operator*= (const T& a)
  182. {
  183. for (int i = 0; i < dim; ++i) for (int j = 0; j < dim; ++j) M[i][j] *= a;
  184. return *this;
  185. }
  186. template <class T>
  187. SQMat<T>& SQMat<T>::operator*= (const SQMat<T>& a)
  188. {
  189. if (dim != a.dim) {
  190. ABACUSerror("Incompatible matrix sizes in matrix operator *.");
  191. exit(1);
  192. }
  193. SQMat<T> leftarg(*this); // use copy constructor.
  194. for (int i = 0; i < dim; ++i) {
  195. for (int j = 0; j < dim; ++j) {
  196. M[i][j] = 0.0;
  197. for (int k = 0; k < dim; ++k) {
  198. M[i][j] += leftarg[i][k] * a[k][j];
  199. }
  200. }
  201. }
  202. return *this;
  203. }
  204. template <class T>
  205. inline int SQMat<T>::size() const
  206. {
  207. return dim;
  208. }
  209. template <class T>
  210. SQMat<T>::~SQMat()
  211. {
  212. if (M != 0) {
  213. delete[] (M[0]);
  214. delete[] (M);
  215. }
  216. }
  217. //*****************************
  218. template <class T>
  219. class RecMat {
  220. private:
  221. int nrows;
  222. int ncols;
  223. T** M;
  224. public:
  225. RecMat (int Nrows, int Ncols); // initializes all elements of this n by n matrix to zero
  226. RecMat (const T& a, int Nrows, int Ncols);
  227. RecMat (const RecMat& rhs); // copy constructor
  228. void Print ();
  229. RecMat& operator= (const RecMat& rhs); // assignment
  230. inline T* operator[] (const int i); // subscripting: pointer to row i
  231. inline const T* operator[] (const int i) const;
  232. inline int nr_rows() const;
  233. inline int nr_cols() const;
  234. ~RecMat();
  235. };
  236. template <class T>
  237. RecMat<T>::RecMat (int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
  238. {
  239. M[0] = new T[Nrows*Ncols];
  240. for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
  241. for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) M[i][j] = T(0);
  242. }
  243. template <class T>
  244. RecMat<T>::RecMat (const T& a, int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
  245. {
  246. M[0] = new T[Nrows*Ncols];
  247. for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
  248. for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) {
  249. if (i == j) M[i][i] = a;
  250. else M[i][j] = T(0);
  251. }
  252. }
  253. template <class T>
  254. RecMat<T>::RecMat (const RecMat& rhs) : nrows(rhs.nrows), ncols(rhs.ncols), M(new T*[nrows])
  255. {
  256. int i,j;
  257. M[0] = new T[nrows*ncols];
  258. for (i = 1; i < nrows; i++) M[i] = M[i-1] + ncols;
  259. for (i = 0; i < nrows; i++)
  260. for (j = 0; j < ncols; j++) M[i][j] = rhs[i][j];
  261. }
  262. // operators
  263. template <class T>
  264. void RecMat<T>::Print ()
  265. {
  266. std::cout << std::endl;
  267. for (int i = 0; i < nrows; ++i) {
  268. for (int j = 0; j < ncols; ++j) std::cout << M[i][j] << " ";
  269. std::cout << std::endl;
  270. }
  271. std::cout << std::endl;
  272. }
  273. template <class T>
  274. RecMat<T>& RecMat<T>::operator= (const RecMat<T>& rhs)
  275. {
  276. if (this != &rhs) {
  277. if (nrows != rhs.nrows || ncols != rhs.ncols) {
  278. if (M != 0) {
  279. delete[] (M[0]);
  280. delete[] (M);
  281. }
  282. nrows = rhs.nrows;
  283. ncols = rhs.ncols;
  284. M = new T*[nrows];
  285. M[0] = new T[nrows * ncols];
  286. }
  287. for (int i = 0; i < nrows; ++i)
  288. for (int j = 0; j < ncols; ++j) M[i][j] = rhs[i][j];
  289. }
  290. return *this;
  291. }
  292. template <class T>
  293. inline T* RecMat<T>::operator[] (const int i)
  294. {
  295. return M[i];
  296. }
  297. template <class T>
  298. inline const T* RecMat<T>::operator[] (const int i) const
  299. {
  300. return M[i];
  301. }
  302. template <class T>
  303. inline int RecMat<T>::nr_rows() const
  304. {
  305. return nrows;
  306. }
  307. template <class T>
  308. inline int RecMat<T>::nr_cols() const
  309. {
  310. return ncols;
  311. }
  312. template <class T>
  313. inline std::ostream& operator<< (std::ostream& s, const RecMat<T>& matrix)
  314. {
  315. for (int i = 0; i < matrix.nr_rows(); ++i) {
  316. for (int j = 0; j < matrix.nr_cols(); ++j) s << matrix[i][j] << " ";
  317. s << std::endl;
  318. }
  319. return (s);
  320. }
  321. template <class T>
  322. RecMat<T>::~RecMat()
  323. {
  324. if (M != 0) {
  325. delete[] (M[0]);
  326. delete[] (M);
  327. }
  328. }
  329. // TYPEDEFS:
  330. typedef ABACUS::SQMat<DP> SQMat_DP;
  331. typedef ABACUS::SQMat<std::complex<double> > SQMat_CX;
  332. // FUNCTION DEFINITIONS
  333. // Functions in src/MATRIX directory
  334. DP det_LU (SQMat_DP a);
  335. DP lndet_LU (SQMat_DP a);
  336. std::complex<DP> lndet_LU_dstry (SQMat_DP& a);
  337. std::complex<DP> det_LU_CX (SQMat_CX a);
  338. std::complex<DP> lndet_LU_CX (SQMat_CX a);
  339. std::complex<DP> lndet_LU_CX_dstry (SQMat_CX& a);
  340. void eigsrt (Vect_DP& d, SQMat_DP& v);
  341. void balanc (SQMat_DP& a);
  342. void elmhes (SQMat_DP& a);
  343. void gaussj (SQMat_DP& a, SQMat_DP& b);
  344. void hqr (SQMat_DP& a, Vect_CX& wri);
  345. void jacobi (SQMat_DP& a, Vect_DP& d, SQMat_DP& v, int& nrot);
  346. void lubksb (SQMat_DP& a, Vect_INT& indx, Vect_DP& b);
  347. void lubksb_CX (SQMat_CX& a, Vect_INT& indx, Vect_CX& b);
  348. void ludcmp (SQMat_DP& a, Vect_INT& indx, DP& d);
  349. void ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d);
  350. DP pythag(DP a, DP b);
  351. void tqli(Vect_DP& d, Vect_DP& e, SQMat_DP& z);
  352. void tred2 (SQMat_DP& a, Vect_DP& d, Vect_DP& e);
  353. } // namespace ABACUS
  354. #endif