FlexBox - A Flexible Primal-Dual ToolBox
flexMatrix.h
1 #ifndef flexMatrix_H
2 #define flexMatrix_H
3 
4 #include "flexLinearOperator.h"
5 
6 #include <vector>
7 
9 template<typename T>
10 class flexMatrix : public flexLinearOperator<T>
11 {
12 
13 #ifdef __CUDACC__
14  typedef thrust::device_vector<T> Tdata;
15 #else
16  typedef std::vector<T> Tdata;
17 #endif
18 
19 private:
20  std::vector<int> rowToIndexList;
21  std::vector<int> indexList;
22  Tdata valueList;
23 
24 public:
26  flexMatrix() : indexList(), valueList(), rowToIndexList(), flexLinearOperator<T>(0, 0, matrixOp, false) {};
27 
29 
34  flexMatrix(int aNumRows, int aNumCols, bool aMinus) : rowToIndexList(aNumRows + 1, static_cast<int>(0)), indexList(0, 0), valueList(0, 0), flexLinearOperator<T>(aNumRows, aNumCols, matrixOp, aMinus){};
35 
37  {
38  flexMatrix<T>* A = new flexMatrix<T>(this->getNumRows(), this->getNumCols(), this->isMinus);
39 
40  A->rowToIndexList = rowToIndexList;
41  A->indexList = indexList;
42  A->valueList = valueList;
43 
44  return A;
45  }
46 
47  void times(bool transposed, const Tdata &input, Tdata &output)
48  {
49 
50  }
51 
52  void timesPlus(bool transposed, const Tdata &input, Tdata &output)
53  {
54  if (this->isMinus)
55  {
56  doTimesCPU(transposed, input, output,MINUS);
57  }
58  else
59  {
60  doTimesCPU(transposed, input, output,PLUS);
61  }
62  }
63 
64  void timesMinus(bool transposed, const Tdata &input, Tdata &output)
65  {
66  if (this->isMinus)
67  {
68  doTimesCPU(transposed, input, output,PLUS);
69  }
70  else
71  {
72  doTimesCPU(transposed, input, output,MINUS);
73  }
74  }
75 
77 
83  void blockInsert(std::vector<int> &indexI, const std::vector<int> &indexJ, const Tdata &indexVal)
84  {
85  //clear matrix
86  //clear();
87 
88  int numberListElements = (int)indexI.size();
89 
90  //initialize vecvector
91  std::vector<int> emptyBucket(0, 0);
92  std::vector < std::vector<int> > buckets(this->getNumRows(), emptyBucket);
93 
94  //add elements to buckets
95  for (int indexInput = 0; indexInput < numberListElements; indexInput++)
96  {
97  int bucketIndex = indexI[indexInput];
98  buckets[bucketIndex].push_back(indexInput);
99  }
100 
101  //go trough all rows:
102  for (int indexRow = 0; indexRow < this->getNumRows(); indexRow++)
103  {
104  int numElements = 0;
105 
106  //go through bucket
107  for (int indexBucket = 0; indexBucket < (int)buckets[indexRow].size(); indexBucket++)
108  {
109  int tmpIndex = buckets[indexRow][indexBucket];
110 
111  indexList.push_back(indexJ[tmpIndex]);
112  valueList.push_back(indexVal[tmpIndex]);
113  ++numElements;
114  }
115 
116  //update rowToIndexList
117  rowToIndexList[indexRow + 1] = rowToIndexList[indexRow] + numElements;
118  }
119  }
120 
121  /*
122  //inserts new matrix element val at position [i][j]. This is SLOW!
123  void insertElement(int i, int j, T val)
124  {
125  //get start position of next row
126  int startIndexNextRow = rowToIndexList[i + 1];
127 
128  int numElt = indexList.size();
129 
130  //increment size of index and value list by 1
131  indexList.push_back(0);
132  valueList.push_back(static_cast<T>(0));
133  //indexList.resize(indexList.size() + 1,static_cast<T>(0));
134  //valueList.resize(valueList.size() + 1,static_cast<T>(0));
135 
136  //shift all elements starting with startIndexNextRow to next position
137  for (int index = indexList.size()-1; index > startIndexNextRow; index--)
138  {
139  indexList[index] = indexList[index - 1];
140  valueList[index] = valueList[index - 1];
141  }
142 
143  //update indexList and valueList at current position
144  indexList[startIndexNextRow] = j;
145  valueList[startIndexNextRow] = val;
146 
147  //increase all elemets above i in rowToIndexList
148  for (int index = i + 1; index < numRows+1; index++)
149  {
150  ++rowToIndexList[index];
151  }
152  }*/
153 
154  T getMaxRowSumAbs(bool transposed)
155  {
156  std::vector<T> rowSum = this->getAbsRowSum(transposed);
157 
158  return *std::max_element(rowSum.begin(), rowSum.end());
159  }
160 
161 
162  std::vector<T> getAbsRowSum(bool transposed)
163  {
164  if (transposed)
165  {
166  std::vector<T> result(this->getNumCols());
167 
168  //todo check if omp is possible
169  for (int k = 0; k < this->getNumRows(); ++k)
170  {
171  for (int index = rowToIndexList[k]; index < rowToIndexList[k + 1]; ++index)
172  {
173  result[indexList[index]] += std::abs(valueList[index]);
174  }
175  }
176 
177  return result;
178  }
179  else
180  {
181  std::vector<T> result(this->getNumRows());
182 
183  #pragma omp parallel for
184  for (int k = 0; k < this->getNumRows(); ++k)
185  {
186  T tmpSum = static_cast<T>(0);
187  for (int index = rowToIndexList[k]; index < rowToIndexList[k + 1]; ++index)
188  {
189  tmpSum += std::abs(valueList[index]);
190  }
191 
192 
193  result[k] = tmpSum;
194  }
195 
196  return result;
197  }
198  }
199 
201 
204  void printRow(int i)
205  {
206  for (int index = rowToIndexList[i]; index < rowToIndexList[i+1]; ++index)
207  {
208  printf("(%d,%d,%f)|", i, indexList[index], valueList[index]);
209  }
210 
211  printf("\n");
212  }
213 
215  void printMatrix()
216  {
217  for (int i = 0; i < this->getNumRows(); i++)
218  {
219  printRow(i);
220  }
221  }
222 
223  //DUMMY FUNCTION
224  #ifdef __CUDACC__
225  thrust::device_vector<T> getAbsRowSumCUDA(bool transposed)
226  {
227  thrust::device_vector<T> result(this->getNumRows(), (T)1);
228 
229  return result;
230  }
231  #endif
232 
233  private:
234  void doTimesCPU(bool transposed, const Tdata &input, Tdata &output,const mySign s)
235  {
236  if (transposed)
237  {
238  //todo: check if transposed multiplication can be parallelized
239  for (int i = 0; i < this->getNumRows(); ++i)
240  {
241  int indexNext = rowToIndexList[i + 1];
242  for (int index = rowToIndexList[i]; index < indexNext; ++index)
243  {
244  switch (s)
245  {
246  case PLUS:
247  {
248  output[indexList[index]] += input[i] * valueList[index];
249  break;
250  }
251  case MINUS:
252  {
253  output[indexList[index]] -= input[i] * valueList[index];
254  break;
255  }
256  }
257  }
258  }
259  }
260  else
261  {
262  #pragma omp parallel for
263  for (int i = 0; i < this->getNumRows(); ++i)
264  {
265  T rowsum = (T)0;
266  // initialize result
267  int indexNext = rowToIndexList[i + 1];
268  for (int index = rowToIndexList[i]; index < indexNext; ++index)
269  {
270  rowsum += input[indexList[index]] * valueList[index];
271  }
272 
273  switch (s)
274  {
275  case PLUS:
276  {
277  output[i] += rowsum;
278  break;
279  }
280  case MINUS:
281  {
282  output[i] -= rowsum;
283  break;
284  }
285  }
286  }
287  }
288  }
289 };
290 
291 #endif
T getMaxRowSumAbs(bool transposed)
returns the maximum sum of absolute values per row used for preconditioning
Definition: flexMatrix.h:154
int getNumRows() const
returns number of rows of the linear operator
Definition: flexLinearOperator.h:57
std::vector< T > getAbsRowSum(bool transposed)
returns a vector of sum of absolute values per row used for preconditioning
Definition: flexMatrix.h:162
bool isMinus
determines if operator is negated
Definition: flexLinearOperator.h:25
represents a (non-CUDA) matrix
Definition: flexMatrix.h:10
void timesMinus(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector and substracts its result from y
Definition: flexMatrix.h:64
void blockInsert(std::vector< int > &indexI, const std::vector< int > &indexJ, const Tdata &indexVal)
inserts data into matrix
Definition: flexMatrix.h:83
int getNumCols() const
returns number of columns of the linear operator
Definition: flexLinearOperator.h:48
void timesPlus(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector and adds its result to y
Definition: flexMatrix.h:52
flexMatrix()
initializes an empty matrix
Definition: flexMatrix.h:26
flexMatrix< T > * copy()
copies the linear operator
Definition: flexMatrix.h:36
thrust::device_vector< T > getAbsRowSumCUDA(bool transposed)
same function as getAbsRowSum() but implemented in CUDA
Definition: flexMatrix.h:225
flexMatrix(int aNumRows, int aNumCols, bool aMinus)
initializes a matrix
Definition: flexMatrix.h:34
mySign
enum representing the type of concatenation
Definition: tools.h:56
void times(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector
Definition: flexMatrix.h:47
abstract base class for linear operators
Definition: flexLinearOperator.h:12
void printMatrix()
prints the whole matrix
Definition: flexMatrix.h:215
void printRow(int i)
prints requested row
Definition: flexMatrix.h:204