FlexBox - A Flexible Primal-Dual ToolBox
flexDiagonalOperator.h
1 #ifndef flexDiagonalOperator_H
2 #define flexDiagonalOperator_H
3 
4 #include <vector>
5 #include "flexLinearOperator.h"
6 
8 template <typename T>
10 {
11 
12 #ifdef __CUDACC__
13  typedef thrust::device_vector<T> Tdata;
14 #else
15  typedef std::vector<T> Tdata;
16 #endif
17 
18 private:
19  Tdata diagonalElements;
20 public:
21 
23 
27  flexDiagonalOperator(std::vector<T> aDiagonalElements, bool aMinus)
28  : flexLinearOperator<T>(static_cast<int>(aDiagonalElements.size()), static_cast<int>(aDiagonalElements.size()), diagonalOp, aMinus)
29  {
30  this->diagonalElements.resize(aDiagonalElements.size());
31 
32  #ifdef __CUDACC__
33  thrust::copy(aDiagonalElements.begin(), aDiagonalElements.end(), this->diagonalElements.begin());
34 
35  #else
36  this->diagonalElements = aDiagonalElements;
37  #endif
38  }
39 
40  #ifdef __CUDACC__
41 
46  flexDiagonalOperator(Tdata aDiagonalElements, bool aMinus) : diagonalElements(aDiagonalElements), flexLinearOperator<T>(static_cast<int>(aDiagonalElements.size()), static_cast<int>(aDiagonalElements.size()), diagonalOp, aMinus)
47  {
48 
49  };
50  #endif
51 
53  {
54  flexDiagonalOperator<T>* A = new flexDiagonalOperator<T>(this->diagonalElements, this->isMinus);
55 
56  return A;
57  }
58 
59  #ifdef __CUDACC__
60  struct flexDiagonalOperatorFunctor
61  {
62  __host__ __device__
63  flexDiagonalOperatorFunctor(const mySign _s) : s(_s){}
64 
65  template <typename Tuple>
66  __host__ __device__
67  void operator()(Tuple t)
68  {
69  switch (this->s)
70  {
71  case PLUS:
72  {
73  thrust::get<0>(t) += thrust::get<1>(t) * thrust::get<2>(t);
74  break;
75  }
76  case MINUS:
77  {
78  thrust::get<0>(t) -= thrust::get<1>(t) * thrust::get<2>(t);
79  break;
80  }
81  case EQUALS:
82  {
83  thrust::get<0>(t) = thrust::get<1>(t) * thrust::get<2>(t);
84  break;
85  }
86  }
87  }
88 
89  mySign s;
90  };
91  #endif
92 
93 
94 
95 
96 
97  //apply linear operator to vector
98  void times(bool transposed, const Tdata &input, Tdata &output)
99  {
100  this->doTimes(input,output,EQUALS);
101  }
102 
103  void timesPlus(bool transposed, const Tdata &input, Tdata &output)
104  {
105  if (this->isMinus)
106  {
107  this->doTimes(input,output, MINUS);
108  }
109  else
110  {
111  this->doTimes(input,output, PLUS);
112  }
113  }
114 
115  void timesMinus(bool transposed, const Tdata &input, Tdata &output)
116  {
117  if (this->isMinus)
118  {
119  this->doTimes(input,output, PLUS);
120  }
121  else
122  {
123  this->doTimes(input,output, MINUS);
124  }
125  }
126 
127  std::vector<T> getAbsRowSum(bool transposed)
128  {
129  std::vector<T> result(this->getNumRows());
130 
131  #pragma omp parallel for
132  for (int k = 0; k < this->getNumRows(); ++k)
133  {
134  result[k] = std::abs(this->diagonalElements[k]);
135  }
136 
137  return result;
138  }
139 
140  T getMaxRowSumAbs(bool transposed)
141  {
142  Tdata diagonalElementsCopy = this->diagonalElements;
143 
144  vectorAbs(diagonalElementsCopy);
145 
146  return vectorMax(diagonalElementsCopy);
147  }
148 
149 
150  #ifdef __CUDACC__
151  thrust::device_vector<T> getAbsRowSumCUDA(bool transposed)
152  {
153  Tdata diagonalElementsCopy = this->diagonalElements;
154 
155  vectorAbs(diagonalElementsCopy);
156 
157  return diagonalElementsCopy;
158  }
159  #endif
160 
161 private:
162  void doTimesCPU(const Tdata &input, Tdata &output,const mySign s)
163  {
164  int numElements = (int)output.size();
165 
166  #pragma omp parallel for
167  for (int i = 0; i < numElements; ++i)
168  {
169  switch (s)
170  {
171  case PLUS:
172  {
173  output[i] += input[i] * this->diagonalElements[i];
174  break;
175  }
176  case MINUS:
177  {
178  output[i] -= input[i] * this->diagonalElements[i];
179  break;
180  }
181  case EQUALS:
182  {
183  output[i] = input[i] * this->diagonalElements[i];
184  break;
185  }
186  }
187  }
188  }
189 
190  void doTimes(const Tdata &input, Tdata &output,const mySign s)
191  {
192  #ifdef __CUDACC__
193  thrust::for_each(
194  thrust::make_zip_iterator(thrust::make_tuple(output.begin(), input.begin(), this->diagonalElements.begin())),
195  thrust::make_zip_iterator(thrust::make_tuple(output.end(), input.end(), this->diagonalElements.end())),
196  flexDiagonalOperatorFunctor(s));
197  #else
198  this->doTimesCPU(input,output,s);
199  #endif
200  }
201 };
202 
203 #endif
int getNumRows() const
returns number of rows of the linear operator
Definition: flexLinearOperator.h:57
flexDiagonalOperator< T > * copy()
copies the linear operator
Definition: flexDiagonalOperator.h:52
void timesPlus(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector and adds its result to y
Definition: flexDiagonalOperator.h:103
bool isMinus
determines if operator is negated
Definition: flexLinearOperator.h:25
void times(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector
Definition: flexDiagonalOperator.h:98
void timesMinus(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector and substracts its result from y
Definition: flexDiagonalOperator.h:115
std::vector< T > getAbsRowSum(bool transposed)
returns a vector of sum of absolute values per row used for preconditioning
Definition: flexDiagonalOperator.h:127
T getMaxRowSumAbs(bool transposed)
returns the maximum sum of absolute values per row used for preconditioning
Definition: flexDiagonalOperator.h:140
flexDiagonalOperator(Tdata aDiagonalElements, bool aMinus)
initializes the concatenation operator for CUDA versions
Definition: flexDiagonalOperator.h:46
thrust::device_vector< T > getAbsRowSumCUDA(bool transposed)
same function as getAbsRowSum() but implemented in CUDA
Definition: flexDiagonalOperator.h:151
mySign
enum representing the type of concatenation
Definition: tools.h:56
flexDiagonalOperator(std::vector< T > aDiagonalElements, bool aMinus)
initializes the concatenation operator for non-CUDA versions
Definition: flexDiagonalOperator.h:27
abstract base class for linear operators
Definition: flexLinearOperator.h:12
represents a diagonal operator
Definition: flexDiagonalOperator.h:9