1 |
// $Id$ |
2 |
/* |
3 |
****************************************************************************** |
4 |
* * |
5 |
* COPYRIGHT ACcESS 2004 - All Rights Reserved * |
6 |
* * |
7 |
* This software is the property of ACcESS. No part of this code * |
8 |
* may be copied in any form or by any means without the expressed written * |
9 |
* consent of ACcESS. Copying, use or modification of this software * |
10 |
* by any unauthorised person is illegal unless that person has a software * |
11 |
* license agreement with ACcESS. * |
12 |
* * |
13 |
****************************************************************************** |
14 |
*/ |
15 |
|
16 |
#if !defined escript_DataAlgorithm_20040714_H |
17 |
#define escript_DataAlgorithm_20040714_H |
18 |
|
19 |
#include "DataArrayView.h" |
20 |
#include "DataExpanded.h" |
21 |
#include "DataTagged.h" |
22 |
#include "DataConstant.h" |
23 |
|
24 |
#include <iostream> |
25 |
#include <algorithm> |
26 |
#include <math.h> |
27 |
|
28 |
namespace escript { |
29 |
|
30 |
/** |
31 |
\brief |
32 |
Adapt binary algorithms so they may be used in DataArrayView reduction operations. |
33 |
|
34 |
Description: |
35 |
This functor adapts the given BinaryFunction operation by starting with the |
36 |
given inital value applying this operation to successive values, storing the |
37 |
rolling result in m_currentValue - which can be accessed or reset by getResult |
38 |
and resetResult respectively. |
39 |
*/ |
40 |
template <class BinaryFunction> |
41 |
class DataAlgorithmAdapter { |
42 |
public: |
43 |
DataAlgorithmAdapter(double initialValue): |
44 |
m_initialValue(initialValue), |
45 |
m_currentValue(initialValue) |
46 |
{ |
47 |
} |
48 |
DataAlgorithmAdapter(const DataAlgorithmAdapter& other): |
49 |
m_initialValue(other.m_initialValue), |
50 |
m_currentValue(other.m_initialValue), |
51 |
operation(other.operation) |
52 |
{ |
53 |
} |
54 |
inline void operator()(double value) |
55 |
{ |
56 |
m_currentValue=operation(m_currentValue,value); |
57 |
return; |
58 |
} |
59 |
inline void resetResult() |
60 |
{ |
61 |
m_currentValue=m_initialValue; |
62 |
} |
63 |
inline double getResult() const |
64 |
{ |
65 |
return m_currentValue; |
66 |
} |
67 |
private: |
68 |
// |
69 |
// the initial operation value |
70 |
double m_initialValue; |
71 |
// |
72 |
// the current operation value |
73 |
double m_currentValue; |
74 |
// |
75 |
// The operation to perform |
76 |
BinaryFunction operation; |
77 |
}; |
78 |
|
79 |
/** |
80 |
\brief |
81 |
Return the maximum value of the two given values. |
82 |
*/ |
83 |
struct FMax : public std::binary_function<double,double,double> |
84 |
{ |
85 |
inline double operator()(double x, double y) const |
86 |
{ |
87 |
return std::max(x,y); |
88 |
} |
89 |
}; |
90 |
|
91 |
/** |
92 |
\brief |
93 |
Return the minimum value of the two given values. |
94 |
*/ |
95 |
struct FMin : public std::binary_function<double,double,double> |
96 |
{ |
97 |
inline double operator()(double x, double y) const |
98 |
{ |
99 |
return std::min(x,y); |
100 |
} |
101 |
}; |
102 |
|
103 |
/** |
104 |
\brief |
105 |
Return the absolute maximum value of the two given values. |
106 |
*/ |
107 |
struct AbsMax : public std::binary_function<double,double,double> |
108 |
{ |
109 |
inline double operator()(double x, double y) const |
110 |
{ |
111 |
return std::max(fabs(x),fabs(y)); |
112 |
} |
113 |
}; |
114 |
|
115 |
/** |
116 |
\brief |
117 |
Return the absolute minimum value of the two given values. |
118 |
*/ |
119 |
struct AbsMin : public std::binary_function<double,double,double> |
120 |
{ |
121 |
inline double operator()(double x, double y) const |
122 |
{ |
123 |
return std::min(fabs(x),fabs(y)); |
124 |
} |
125 |
}; |
126 |
|
127 |
/** |
128 |
\brief |
129 |
Return the length between the two given values. |
130 |
*/ |
131 |
struct Length : public std::binary_function<double,double,double> |
132 |
{ |
133 |
inline double operator()(double x, double y) const |
134 |
{ |
135 |
return std::sqrt(std::pow(x,2)+std::pow(y,2)); |
136 |
} |
137 |
}; |
138 |
|
139 |
/** |
140 |
\brief |
141 |
Return the trace of the two given values. |
142 |
*/ |
143 |
struct Trace : public std::binary_function<double,double,double> |
144 |
{ |
145 |
inline double operator()(double x, double y) const |
146 |
{ |
147 |
return x+y; |
148 |
} |
149 |
}; |
150 |
|
151 |
/** |
152 |
\brief |
153 |
Perform the given operation upon all values in all data-points in the |
154 |
given Data object and return the final result. |
155 |
|
156 |
Calls DataArrayView::reductionOp |
157 |
*/ |
158 |
template <class BinaryFunction> |
159 |
inline |
160 |
double |
161 |
algorithm(DataExpanded& data, |
162 |
BinaryFunction operation, |
163 |
double initial_value) |
164 |
{ |
165 |
int i,j; |
166 |
int numDPPSample=data.getNumDPPSample(); |
167 |
int numSamples=data.getNumSamples(); |
168 |
double global_current_value=initial_value; |
169 |
double local_current_value; |
170 |
DataArrayView dataView=data.getPointDataView(); |
171 |
// calculate the reduction operation value for each data point |
172 |
// reducing the result for each data-point into the current_value variables |
173 |
#pragma omp parallel private(local_current_value) |
174 |
{ |
175 |
local_current_value=initial_value; |
176 |
#pragma omp for private(i,j) schedule(static) |
177 |
for (i=0;i<numSamples;i++) { |
178 |
for (j=0;j<numDPPSample;j++) { |
179 |
local_current_value=operation(local_current_value,dataView.reductionOp(data.getPointOffset(i,j),operation,initial_value)); |
180 |
} |
181 |
} |
182 |
#pragma omp critical |
183 |
global_current_value=operation(global_current_value,local_current_value); |
184 |
} |
185 |
return global_current_value; |
186 |
} |
187 |
|
188 |
template <class BinaryFunction> |
189 |
inline |
190 |
double |
191 |
algorithm(DataTagged& data, |
192 |
BinaryFunction operation, |
193 |
double initial_value) |
194 |
{ |
195 |
double current_value=initial_value; |
196 |
// perform the operation on each tagged value |
197 |
DataArrayView& dataView=data.getPointDataView(); |
198 |
const DataTagged::DataMapType& lookup=data.getTagLookup(); |
199 |
for (DataTagged::DataMapType::const_iterator i=lookup.begin(); i!=lookup.end(); i++) { |
200 |
current_value=operation(current_value,dataView.reductionOp(i->second,operation,initial_value)); |
201 |
} |
202 |
// perform the operation on the default value |
203 |
current_value=operation(current_value,data.getDefaultValue().reductionOp(operation,initial_value)); |
204 |
return current_value; |
205 |
} |
206 |
|
207 |
template <class BinaryFunction> |
208 |
inline |
209 |
double |
210 |
algorithm(DataConstant& data, |
211 |
BinaryFunction operation, |
212 |
double initial_value) |
213 |
{ |
214 |
return data.getPointDataView().reductionOp(operation,initial_value); |
215 |
} |
216 |
|
217 |
/** |
218 |
\brief |
219 |
Perform the given data-point reduction operation on all data-points |
220 |
in data, storing results in corresponding data-points of result. |
221 |
|
222 |
Objects data and result must be of the same type, and have the same number |
223 |
of data points, but where data has data points of rank n, result must have |
224 |
data points of rank 0. |
225 |
|
226 |
Calls DataArrayView::reductionOp |
227 |
*/ |
228 |
template <class BinaryFunction> |
229 |
inline |
230 |
void |
231 |
dp_algorithm(DataExpanded& data, |
232 |
DataExpanded& result, |
233 |
BinaryFunction operation, |
234 |
double initial_value) |
235 |
{ |
236 |
int i,j; |
237 |
int numSamples=data.getNumSamples(); |
238 |
int numDPPSample=data.getNumDPPSample(); |
239 |
DataArrayView dataView=data.getPointDataView(); |
240 |
DataArrayView resultView=result.getPointDataView(); |
241 |
// perform the operation on each data-point and assign |
242 |
// this to the corresponding element in result |
243 |
#pragma omp parallel for private(i,j) schedule(static) |
244 |
for (i=0;i<numSamples;i++) { |
245 |
for (j=0;j<numDPPSample;j++) { |
246 |
resultView.getData(result.getPointOffset(i,j)) = |
247 |
dataView.reductionOp(data.getPointOffset(i,j),operation,initial_value); |
248 |
} |
249 |
} |
250 |
} |
251 |
|
252 |
template <class BinaryFunction> |
253 |
inline |
254 |
void |
255 |
dp_algorithm(DataTagged& data, |
256 |
DataTagged& result, |
257 |
BinaryFunction operation, |
258 |
double initial_value) |
259 |
{ |
260 |
// perform the operation on each tagged value in data |
261 |
// and assign this to the corresponding element in result |
262 |
const DataTagged::DataMapType& lookup=data.getTagLookup(); |
263 |
for (DataTagged::DataMapType::const_iterator i=lookup.begin(); i!=lookup.end(); i++) { |
264 |
result.getDataPointByTag(i->first).getData(0) = |
265 |
data.getDataPointByTag(i->first).reductionOp(operation,initial_value); |
266 |
} |
267 |
// perform the operation on the default data value |
268 |
// and assign this to the default element in result |
269 |
result.getDefaultValue().getData(0) = |
270 |
data.getDefaultValue().reductionOp(operation,initial_value); |
271 |
} |
272 |
|
273 |
template <class BinaryFunction> |
274 |
inline |
275 |
void |
276 |
dp_algorithm(DataConstant& data, |
277 |
DataConstant& result, |
278 |
BinaryFunction operation, |
279 |
double initial_value) |
280 |
{ |
281 |
// perform the operation on the data value |
282 |
// and assign this to the element in result |
283 |
result.getPointDataView().getData(0) = |
284 |
data.getPointDataView().reductionOp(operation,initial_value); |
285 |
} |
286 |
|
287 |
} // end of namespace |
288 |
|
289 |
#endif |