ergo
MatrixHierarchicBase.h
Go to the documentation of this file.
1 /* Ergo, version 3.2, a program for linear scaling electronic structure
2  * calculations.
3  * Copyright (C) 2012 Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Primary academic reference:
19  * Kohn−Sham Density Functional Theory Electronic Structure Calculations
20  * with Linearly Scaling Computational Time and Memory Usage,
21  * Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek,
22  * J. Chem. Theory Comput. 7, 340 (2011),
23  * <http://dx.doi.org/10.1021/ct100611z>
24  *
25  * For further information about Ergo, see <http://www.ergoscf.org>.
26  */
27 
38 #ifndef MAT_MATRIXHIERARCHICBASE
39 #define MAT_MATRIXHIERARCHICBASE
40 #include "matInclude.h"
41 namespace mat{
48  template<class Treal, class Telement = Treal>
50  public:
51  /* No public constructors (!) */
52  inline bool operator==(int k) const {
53  if (k == 0)
54  return this->is_zero();
55  else
56  throw Failure("Matrix::operator== only implemented for k == 0");
57  }
58  /* Check if matrix is zero (k = 0) */
59 #if 1
60  inline const int& nScalarsRows() const
61  {return rows.getNScalars();}
62  inline const int& nScalarsCols() const
63  {return cols.getNScalars();}
64 #endif
65 
66  inline const int& nrows() const /* Number of rows in Telement matrix */
67  {return rows.getNBlocks();}
68  inline const int& ncols() const /* Number of cols in Telement matrix */
69  {return cols.getNBlocks();}
70 
71  inline Telement& operator() /* Returns the element A(row, col) */
72  (int row, int col) {
74  assert(row >= 0);
75  assert(col >= 0);
76  assert(row < nrows());
77  assert(col < ncols());
78  return elements[row + col * nrows()];
79  }
80  inline const Telement& operator() /*Write protected reference returned*/
81  (int row, int col) const {
83  assert(row >= 0);
84  assert(col >= 0);
85  assert(row < nrows());
86  assert(col < ncols());
87  return elements[row + col * nrows()];
88  }
89 
90  inline Telement& operator[]
91  (int index) {
93  assert(index >= 0);
94  assert(index < nElements());
95  return elements[index];
96  }
97  inline Telement const & operator[]
98  (int index) const {
100  assert(index >= 0);
101  assert(index < nElements());
102  return elements[index];
103  }
104 
105  inline bool is_zero() const {return !elements;}
106 
107  inline int nElements() const {
108  return rows.getNBlocks() * cols.getNBlocks();
109  }
110 
111  inline void resetRows(SizesAndBlocks const & newRows) {
112  delete[] elements;
113  elements = 0;
114  rows = newRows;
115  }
116  inline void resetCols(SizesAndBlocks const & newCols) {
117  delete[] elements;
118  elements = 0;
119  cols = newCols;
120  }
121 
122  inline void getRows(SizesAndBlocks & rowsCopy) const {
123  rowsCopy = rows;
124  }
125  inline void getCols(SizesAndBlocks & colsCopy) const {
126  colsCopy = cols;
127  }
128 
129 
130  inline bool highestLevel() const {
131  return (rows.getNTotalScalars() == rows.getNScalars() &&
133  }
134 
140  inline bool is_empty() const {
141  return rows.is_empty() || cols.is_empty();
142  }
143  protected:
144 
145 
147  : elements(0) {}
148  MatrixHierarchicBase(SizesAndBlocks const & rowsInp,
149  SizesAndBlocks const & colsInp)
150  : rows(rowsInp), cols(colsInp), elements(0) {}
152 
153 
156 
159 
160  virtual ~MatrixHierarchicBase();
163  Telement* elements; /* Length is nRows * nCols unless 0 */
164 
165 
166 
167 #if 0
168  inline void assert_alloc() {
169  if (this->cap < this->nel) {
170  delete[] this->elements;
171  this->cap = this->nel;
172  this->elements = new Telement[this->cap];
173  for (int ind = 0; ind < this->cap; ind++)
174  this->elements[ind] = 0;
175  }
176  }
177 #endif
178  private:
179 
180  }; /* end class */
181 
182 
183 
184  template<class Treal, class Telement> /* Copy constructor */
187  : rows(mat.rows), cols(mat.cols), elements(0) {
188  if (!mat.is_zero()) {
189  elements = new Telement[nElements()];
190  for (int i = 0; i < nElements(); i++)
191  elements[i] = mat.elements[i];
192  }
193  }
194 
195 
196  template<class Treal, class Telement> /*Assignment operator*/
200  if (mat.is_zero()) { /* Condition also matches empty matrices. */
201  rows = mat.rows;
202  cols = mat.cols;
203  delete[] elements;
204  elements = 0;
205  return *this;
206  }
207  if (is_zero() || (nElements() != mat.nElements())) {
208  delete[] elements;
209  elements = new Telement[mat.nElements()];
210  }
211  rows = mat.rows;
212  cols = mat.cols;
213  for (int i = 0; i < nElements(); i++)
214  elements[i] = mat.elements[i];
215  return *this;
216  }
217 
218  template<class Treal, class Telement>
222  assert(A.rows == B.rows && A.cols == B.cols);
223  Telement* elementsTmp = A.elements;
224  A.elements = B.elements;
225  B.elements = elementsTmp;
226  }
227 
228 
229  template<class Treal, class Telement>
231  delete[] elements;
232  elements = 0;
233  }
234 
235 
236 } /* end namespace mat */
237 
238 #endif