00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #if !defined escript_DataAlgorithm_20040714_H
00016 #define escript_DataAlgorithm_20040714_H
00017 #include "system_dep.h"
00018
00019 #include "DataExpanded.h"
00020 #include "DataTagged.h"
00021 #include "DataConstant.h"
00022
00023 #include "DataMaths.h"
00024
00025 #include <iostream>
00026 #include <algorithm>
00027 #include <list>
00028
00029 namespace escript {
00030
00041 template <class BinaryFunction>
00042 class DataAlgorithmAdapter {
00043 public:
00044 DataAlgorithmAdapter(double initialValue):
00045 m_initialValue(initialValue),
00046 m_currentValue(initialValue)
00047 {
00048 }
00049 DataAlgorithmAdapter(const DataAlgorithmAdapter& other):
00050 m_initialValue(other.m_initialValue),
00051 m_currentValue(other.m_initialValue),
00052 operation(other.operation)
00053 {
00054 }
00055 inline void operator()(double value)
00056 {
00057 m_currentValue=operation(m_currentValue,value);
00058 return;
00059 }
00060 inline void resetResult()
00061 {
00062 m_currentValue=m_initialValue;
00063 }
00064 inline double getResult() const
00065 {
00066 return m_currentValue;
00067 }
00068 private:
00069
00070
00071 double m_initialValue;
00072
00073
00074 double m_currentValue;
00075
00076
00077 BinaryFunction operation;
00078 };
00079
00084 struct FMax : public std::binary_function<double,double,double>
00085 {
00086 inline double operator()(double x, double y) const
00087 {
00088 return std::max(x,y);
00089 }
00090 };
00091
00096 struct FMin : public std::binary_function<double,double,double>
00097 {
00098 inline double operator()(double x, double y) const
00099 {
00100 return std::min(x,y);
00101 }
00102 };
00103
00108 struct AbsMax : public std::binary_function<double,double,double>
00109 {
00110 inline double operator()(double x, double y) const
00111 {
00112 return std::max(fabs(x),fabs(y));
00113 }
00114 };
00115
00120 struct AbsMin : public std::binary_function<double,double,double>
00121 {
00122 inline double operator()(double x, double y) const
00123 {
00124 return std::min(fabs(x),fabs(y));
00125 }
00126 };
00127
00132 struct Length : public std::binary_function<double,double,double>
00133 {
00134 inline double operator()(double x, double y) const
00135 {
00136 return std::sqrt(std::pow(x,2)+std::pow(y,2));
00137 }
00138 };
00139
00144 struct Trace : public std::binary_function<double,double,double>
00145 {
00146 inline double operator()(double x, double y) const
00147 {
00148 return x+y;
00149 }
00150 };
00151
00155 struct AbsGT : public std::binary_function<double,double,double>
00156 {
00157 inline double operator()(double x, double y) const
00158 {
00159 return fabs(x)>y;
00160 }
00161 };
00162
00166 struct AbsLTE : public std::binary_function<double,double,double>
00167 {
00168 inline double operator()(double x, double y) const
00169 {
00170 return fabs(x)<=y;
00171 }
00172 };
00173
00174
00180 template <class BinaryFunction>
00181 inline
00182 double
00183 algorithm(const DataExpanded& data,
00184 BinaryFunction operation,
00185 double initial_value)
00186 {
00187 int i,j;
00188 int numDPPSample=data.getNumDPPSample();
00189 int numSamples=data.getNumSamples();
00190 double global_current_value=initial_value;
00191 double local_current_value;
00192
00193 const DataTypes::ValueType& vec=data.getVectorRO();
00194 const DataTypes::ShapeType& shape=data.getShape();
00195
00196
00197 #pragma omp parallel private(local_current_value)
00198 {
00199 local_current_value=initial_value;
00200 #pragma omp for private(i,j) schedule(static)
00201 for (i=0;i<numSamples;i++) {
00202 for (j=0;j<numDPPSample;j++) {
00203
00204 local_current_value=operation(local_current_value,DataMaths::reductionOp(vec,shape,data.getPointOffset(i,j),operation,initial_value));
00205
00206 }
00207 }
00208 #pragma omp critical
00209 global_current_value=operation(global_current_value,local_current_value);
00210 }
00211 return global_current_value;
00212 }
00213
00214
00215 template <class BinaryFunction>
00216 inline
00217 double
00218 algorithm(DataTagged& data,
00219 BinaryFunction operation,
00220 double initial_value)
00221 {
00222 double current_value=initial_value;
00223
00224 const DataTypes::ValueType& vec=data.getVectorRO();
00225 const DataTypes::ShapeType& shape=data.getShape();
00226 const DataTagged::DataMapType& lookup=data.getTagLookup();
00227 const std::list<int> used=data.getFunctionSpace().getListOfTagsSTL();
00228 for (std::list<int>::const_iterator i=used.begin();i!=used.end();++i)
00229 {
00230 int tag=*i;
00231 if (tag==0)
00232 {
00233 current_value=operation(current_value,DataMaths::reductionOp(vec,shape,data.getDefaultOffset(),operation,initial_value));
00234 }
00235 else
00236 {
00237 DataTagged::DataMapType::const_iterator it=lookup.find(tag);
00238 if (it!=lookup.end())
00239 {
00240 current_value=operation(current_value,DataMaths::reductionOp(vec,shape,it->second,operation,initial_value));
00241 }
00242 }
00243 }
00244 return current_value;
00245 }
00246
00247 template <class BinaryFunction>
00248 inline
00249 double
00250 algorithm(DataConstant& data,
00251 BinaryFunction operation,
00252 double initial_value)
00253 {
00254 return DataMaths::reductionOp(data.getVectorRO(),data.getShape(),0,operation,initial_value);
00255 }
00256
00268 template <class BinaryFunction>
00269 inline
00270 void
00271 dp_algorithm(const DataExpanded& data,
00272 DataExpanded& result,
00273 BinaryFunction operation,
00274 double initial_value)
00275 {
00276 int i,j;
00277 int numSamples=data.getNumSamples();
00278 int numDPPSample=data.getNumDPPSample();
00279
00280
00281 const DataTypes::ValueType& dataVec=data.getVectorRO();
00282 const DataTypes::ShapeType& shape=data.getShape();
00283 DataTypes::ValueType& resultVec=result.getVectorRW();
00284
00285
00286 #pragma omp parallel for private(i,j) schedule(static)
00287 for (i=0;i<numSamples;i++) {
00288 for (j=0;j<numDPPSample;j++) {
00289
00290
00291 resultVec[result.getPointOffset(i,j)] =
00292 DataMaths::reductionOp(dataVec, shape, data.getPointOffset(i,j),operation,initial_value);
00293
00294 }
00295 }
00296 }
00297
00298 template <class BinaryFunction>
00299 inline
00300 void
00301 dp_algorithm(const DataTagged& data,
00302 DataTagged& result,
00303 BinaryFunction operation,
00304 double initial_value)
00305 {
00306
00307
00308 const DataTypes::ShapeType& shape=data.getShape();
00309 const DataTypes::ValueType& vec=data.getVectorRO();
00310 const DataTagged::DataMapType& lookup=data.getTagLookup();
00311 for (DataTagged::DataMapType::const_iterator i=lookup.begin(); i!=lookup.end(); i++) {
00312 result.getDataByTagRW(i->first,0) =
00313 DataMaths::reductionOp(vec,shape,data.getOffsetForTag(i->first),operation,initial_value);
00314 }
00315
00316
00317 result.getVectorRW()[result.getDefaultOffset()] = DataMaths::reductionOp(data.getVectorRO(),data.getShape(),data.getDefaultOffset(),operation,initial_value);
00318 }
00319
00320 template <class BinaryFunction>
00321 inline
00322 void
00323 dp_algorithm(DataConstant& data,
00324 DataConstant& result,
00325 BinaryFunction operation,
00326 double initial_value)
00327 {
00328
00329
00330 result.getVectorRW()[0] =
00331 DataMaths::reductionOp(data.getVectorRO(),data.getShape(),0,operation,initial_value);
00332 }
00333
00334 }
00335
00336 #endif