Escript  Revision_4320
DataAlgorithm.h
Go to the documentation of this file.
1 
2 /*****************************************************************************
3 *
4 * Copyright (c) 2003-2013 by University of Queensland
5 * http://www.uq.edu.au
6 *
7 * Primary Business: Queensland, Australia
8 * Licensed under the Open Software License version 3.0
9 * http://www.opensource.org/licenses/osl-3.0.php
10 *
11 * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 * Development since 2012 by School of Earth Sciences
13 *
14 *****************************************************************************/
15 
16 
17 #if !defined escript_DataAlgorithm_20040714_H
18 #define escript_DataAlgorithm_20040714_H
19 #include "system_dep.h"
20 
21 #include "DataExpanded.h"
22 #include "DataTagged.h"
23 #include "DataConstant.h"
24 
25 #include "DataMaths.h"
26 
27 #include <iostream>
28 #include <algorithm>
29 #include <list>
30 
31 namespace escript {
32 
43 template <class BinaryFunction>
45  public:
46  DataAlgorithmAdapter(double initialValue):
47  m_initialValue(initialValue),
48  m_currentValue(initialValue)
49  {
50  }
54  operation(other.operation)
55  {
56  }
57  inline void operator()(double value)
58  {
60  return;
61  }
62  inline void resetResult()
63  {
65  }
66  inline double getResult() const
67  {
68  return m_currentValue;
69  }
70  private:
71  //
72  // the initial operation value
74  //
75  // the current operation value
77  //
78  // The operation to perform
79  BinaryFunction operation;
80 };
81 
86 struct FMax : public std::binary_function<double,double,double>
87 {
88  inline double operator()(double x, double y) const
89  {
90  return std::max(x,y);
91  }
92 };
93 
98 struct FMin : public std::binary_function<double,double,double>
99 {
100  inline double operator()(double x, double y) const
101  {
102  return std::min(x,y);
103  }
104 };
105 
110 struct AbsMax : public std::binary_function<double,double,double>
111 {
112  inline double operator()(double x, double y) const
113  {
114  return std::max(fabs(x),fabs(y));
115  }
116 };
117 
122 struct AbsMin : public std::binary_function<double,double,double>
123 {
124  inline double operator()(double x, double y) const
125  {
126  return std::min(fabs(x),fabs(y));
127  }
128 };
129 
134 struct Length : public std::binary_function<double,double,double>
135 {
136  inline double operator()(double x, double y) const
137  {
138  return std::sqrt(std::pow(x,2)+std::pow(y,2));
139  }
140 };
141 
146 struct Trace : public std::binary_function<double,double,double>
147 {
148  inline double operator()(double x, double y) const
149  {
150  return x+y;
151  }
152 };
153 
157 struct AbsGT : public std::binary_function<double,double,double>
158 {
159  inline double operator()(double x, double y) const
160  {
161  return fabs(x)>y;
162  }
163 };
164 
168 struct AbsLTE : public std::binary_function<double,double,double>
169 {
170  inline double operator()(double x, double y) const
171  {
172  return fabs(x)<=y;
173  }
174 };
175 
176 
182 template <class BinaryFunction>
183 inline
184 double
186  BinaryFunction operation,
187  double initial_value)
188 {
189  int i,j;
190  int numDPPSample=data.getNumDPPSample();
191  int numSamples=data.getNumSamples();
192  double global_current_value=initial_value;
193  double local_current_value;
194 // DataArrayView dataView=data.getPointDataView();
195  const DataTypes::ValueType& vec=data.getVectorRO();
196  const DataTypes::ShapeType& shape=data.getShape();
197  // calculate the reduction operation value for each data point
198  // reducing the result for each data-point into the current_value variables
199  #pragma omp parallel private(local_current_value)
200  {
201  local_current_value=initial_value;
202  #pragma omp for private(i,j) schedule(static)
203  for (i=0;i<numSamples;i++) {
204  for (j=0;j<numDPPSample;j++) {
205 /* local_current_value=operation(local_current_value,dataView.reductionOp(data.getPointOffset(i,j),operation,initial_value));*/
206  local_current_value=operation(local_current_value,DataMaths::reductionOp(vec,shape,data.getPointOffset(i,j),operation,initial_value));
207 
208  }
209  }
210  #pragma omp critical
211  global_current_value=operation(global_current_value,local_current_value);
212  }
213  return global_current_value;
214 }
215 
216 // It is important that the algorithm only be applied to tags which are actually in use.
217 template <class BinaryFunction>
218 inline
219 double
221  BinaryFunction operation,
222  double initial_value)
223 {
224  double current_value=initial_value;
225 
226  const DataTypes::ValueType& vec=data.getVectorRO();
227  const DataTypes::ShapeType& shape=data.getShape();
228  const DataTagged::DataMapType& lookup=data.getTagLookup();
229  const std::list<int> used=data.getFunctionSpace().getListOfTagsSTL();
230  for (std::list<int>::const_iterator i=used.begin();i!=used.end();++i)
231  {
232  int tag=*i;
233  if (tag==0) // check for the default tag
234  {
235  current_value=operation(current_value,DataMaths::reductionOp(vec,shape,data.getDefaultOffset(),operation,initial_value));
236  }
237  else
238  {
239  DataTagged::DataMapType::const_iterator it=lookup.find(tag);
240  if (it!=lookup.end())
241  {
242  current_value=operation(current_value,DataMaths::reductionOp(vec,shape,it->second,operation,initial_value));
243  }
244  }
245  }
246  return current_value;
247 }
248 
249 template <class BinaryFunction>
250 inline
251 double
253  BinaryFunction operation,
254  double initial_value)
255 {
256  return DataMaths::reductionOp(data.getVectorRO(),data.getShape(),0,operation,initial_value);
257 }
258 
270 template <class BinaryFunction>
271 inline
272 void
274  DataExpanded& result,
275  BinaryFunction operation,
276  double initial_value)
277 {
278  int i,j;
279  int numSamples=data.getNumSamples();
280  int numDPPSample=data.getNumDPPSample();
281 // DataArrayView dataView=data.getPointDataView();
282 // DataArrayView resultView=result.getPointDataView();
283  const DataTypes::ValueType& dataVec=data.getVectorRO();
284  const DataTypes::ShapeType& shape=data.getShape();
285  DataTypes::ValueType& resultVec=result.getVectorRW();
286  // perform the operation on each data-point and assign
287  // this to the corresponding element in result
288  #pragma omp parallel for private(i,j) schedule(static)
289  for (i=0;i<numSamples;i++) {
290  for (j=0;j<numDPPSample;j++) {
291 /* resultView.getData(result.getPointOffset(i,j)) =
292  dataView.reductionOp(data.getPointOffset(i,j),operation,initial_value);*/
293  resultVec[result.getPointOffset(i,j)] =
294  DataMaths::reductionOp(dataVec, shape, data.getPointOffset(i,j),operation,initial_value);
295 
296  }
297  }
298 }
299 
300 template <class BinaryFunction>
301 inline
302 void
304  DataTagged& result,
305  BinaryFunction operation,
306  double initial_value)
307 {
308  // perform the operation on each tagged value in data
309  // and assign this to the corresponding element in result
310  const DataTypes::ShapeType& shape=data.getShape();
311  const DataTypes::ValueType& vec=data.getVectorRO();
312  const DataTagged::DataMapType& lookup=data.getTagLookup();
313  for (DataTagged::DataMapType::const_iterator i=lookup.begin(); i!=lookup.end(); i++) {
314  result.getDataByTagRW(i->first,0) =
315  DataMaths::reductionOp(vec,shape,data.getOffsetForTag(i->first),operation,initial_value);
316  }
317  // perform the operation on the default data value
318  // and assign this to the default element in result
319  result.getVectorRW()[result.getDefaultOffset()] = DataMaths::reductionOp(data.getVectorRO(),data.getShape(),data.getDefaultOffset(),operation,initial_value);
320 }
321 
322 template <class BinaryFunction>
323 inline
324 void
326  DataConstant& result,
327  BinaryFunction operation,
328  double initial_value)
329 {
330  // perform the operation on the data value
331  // and assign this to the element in result
332  result.getVectorRW()[0] =
333  DataMaths::reductionOp(data.getVectorRO(),data.getShape(),0,operation,initial_value);
334 }
335 
336 } // end of namespace
337 
338 #endif