HubbardGPU
Hubbard diagonalisation on the GPU (and CPU)
 All Classes Files Functions Variables Typedefs Friends Macros
SparseMatrix_CCS.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2014 Ward Poelmans
2 
3  This file is part of Hubbard-GPU.
4 
5  Hubbard-GPU 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  Hubbard-GPU 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 Hubbard-GPU. If not, see <http://www.gnu.org/licenses/>.
17  */
18 #include <cmath>
19 #include "helpers.h"
20 #include "SparseMatrix_CCS.h"
21 
22 #define MY_ZEROLIMIT 1e-10
23 
29 SparseMatrix_CCS::SparseMatrix_CCS(unsigned int n, unsigned int m)
30 {
31  this->n = n;
32  this->m = m;
33 }
34 
40 {
41  this->n = origin.n;
42  this->m = origin.m;
43  this->data = origin.data;
44  this->col = origin.col;
45  this->row = origin.row;
46 }
47 
49 {
50 }
51 
58 double SparseMatrix_CCS::operator()(unsigned int i,unsigned int j) const
59 {
60  for(unsigned int k=col[j];k<col[j+1];k++)
61  if( row[k] == i )
62  return data[k];
63 
64  return 0;
65 }
66 
70 unsigned int SparseMatrix_CCS::gn() const
71 {
72  return n;
73 }
74 
78 unsigned int SparseMatrix_CCS::gm() const
79 {
80  return m;
81 }
82 
89 {
90  this->n = origin.n;
91  this->m = origin.m;
92  this->data = origin.data;
93  this->col = origin.col;
94  this->row = origin.row;
95 
96  return *this;
97 }
98 
104 {
105  this->n = dense.getn();
106  this->m = dense.getm();
107  col.resize(m+1);
108 
109  data.clear();
110  row.clear();
111 
112  col[0] = 0;
113 
114  for(unsigned int j=0;j<m;j++)
115  {
116  for(unsigned int i=0;i<n;i++)
117  if( fabs(dense(i,j)) > MY_ZEROLIMIT )
118  {
119  data.push_back(dense(i,j));
120  row.push_back(i);
121  }
122 
123  col[j+1] = row.size();
124  }
125 
126  col.back() = row.size();
127 }
128 
134 {
135  dense = 0;
136  unsigned int dn = dense.getn();
137  unsigned int dm = dense.getm();
138 
139  assert(dn == n && dm == m);
140 
141  for(unsigned int i=0;i<m;i++)
142  for(unsigned int k=col[i];k<col[i+1];k++)
143  dense(row[k],i) = data[k];
144 }
145 
150 {
151  std::cout << n << " x " << m << " matrix" << std::endl;
152  std::cout << "Data(" << data.size() << "):" << std::endl;
153  for(unsigned int i=0;i<data.size();i++)
154  std::cout << data[i] << " ";
155  std::cout << std::endl;
156 
157  std::cout << "Row indices:" << std::endl;
158  for(unsigned int i=0;i<row.size();i++)
159  std::cout << row[i] << " ";
160  std::cout << std::endl;
161 
162  std::cout << "Col indices:" << std::endl;
163  for(unsigned int i=0;i<col.size();i++)
164  std::cout << col[i] << " ";
165  std::cout << std::endl;
166 }
167 
174 ostream &operator<<(ostream &output,SparseMatrix_CCS &matrix_p)
175 {
176  for(unsigned int i=0;i<matrix_p.m;i++)
177  for(unsigned int k=matrix_p.row[i];k<matrix_p.row[i+1];k++)
178  output << matrix_p.row[k] << "\t" << i << "\t" << matrix_p.data[k] << std::endl;
179 
180  return output;
181 }
182 
191 void SparseMatrix_CCS::PushToCol(unsigned int j, double value)
192 {
193  // thirth condition is for a new row begins
194  if(row.empty() || row.back() < j || col.back() == row.size())
195  {
196  data.push_back(value);
197  row.push_back(j);
198  }
199  else
200  {
201  unsigned int begin = col.back();
202  for(unsigned int i=begin;i<row.size();i++)
203  {
204  if( row[i] > j )
205  {
206  row.insert(row.begin() + i,j);
207  data.insert(data.begin() + i,value);
208  break;
209  } else if (row[i] == j)
210  {
211  data[i] += value;
212 
213  if(fabs(data[i]) < MY_ZEROLIMIT)
214  {
215  data.erase(data.begin() + i);
216  row.erase(row.begin() + i);
217  }
218  break;
219  }
220  }
221  }
222 }
223 
228 {
229  if(col.size() == (m+1))
230  return;
231 
232  col.push_back(data.size());
233 }
234 
240 unsigned int SparseMatrix_CCS::NumOfElInCol(unsigned int idx) const
241 {
242  assert(idx<m);
243  return (col[idx+1]-col[idx]);
244 }
245 
252 double SparseMatrix_CCS::GetElementInCol(unsigned int col_index, unsigned int element_index) const
253 {
254  assert(col_index < m);
255  assert((col[col_index]+element_index) < data.size());
256  return data[col[col_index]+element_index];
257 }
258 
265 unsigned int SparseMatrix_CCS::GetElementRowIndexInCol(unsigned int col_index, unsigned int element_index) const
266 {
267  assert((col[col_index]+element_index) < row.size());
268  return row[col[col_index]+element_index];
269 }
270 
271 
280 {
281  assert(A.getm() == B.gn());
282  this->n = A.getn();
283  this->m = B.gm();
284  col.resize(m+1);
285 
286  data.clear();
287  row.clear();
288 
289  NewCol();
290 
291  for(int j=0;j<B.gm();j++)
292  {
293  for(int k=0;k<B.NumOfElInCol(j);k++)
294  for(int i=0;i<A.getn();i++)
295  {
296  double val = A(i, B.GetElementRowIndexInCol(j,k)) * B.GetElementInCol(j,k);
297 
298  if(fabs(val) > MY_ZEROLIMIT)
299  PushToCol(i, val);
300  }
301 
302  NewCol();
303  }
304 
305  NewCol();
306 }
307 
313 //void SparseMatrix_CCS::mvprod(const matrix &xmat, matrix &ymat) const
314 //{
315 // double *x = const_cast<Matrix &>(xmat).gMatrix()[0];
316 // double *y = ymat.gMatrix()[0];
317 //
318 //
319 // // first run to initialize all values
320 // for(unsigned int i=0;i<n;i++)
321 // y[i] = 0;
322 //
323 // for(unsigned int i=0;i<m;i++)
324 // {
325 // for(unsigned int k=col[i];k<col[i+1];k++)
326 // y[row[k]] += data[k] * x[i];
327 // }
328 //}
329 
330 /* vim: set ts=3 sw=3 expandtab :*/