escript  Revision_
BinaryOp.h
Go to the documentation of this file.
00001 
00002 /*****************************************************************************
00003 *
00004 * Copyright (c) 2003-2014 by University of Queensland
00005 * http://www.uq.edu.au
00006 *
00007 * Primary Business: Queensland, Australia
00008 * Licensed under the Open Software License version 3.0
00009 * http://www.opensource.org/licenses/osl-3.0.php
00010 *
00011 * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
00012 * Development 2012-2013 by School of Earth Sciences
00013 * Development from 2014 by Centre for Geoscience Computing (GeoComp)
00014 *
00015 *****************************************************************************/
00016 
00017 
00018 #if !defined  escript_BinaryOp_20040315_H
00019 #define escript_BinaryOp_20040315_H
00020 #include "system_dep.h"
00021 
00022 #include "DataTypes.h"
00023 #include "DataConstant.h"
00024 #include "DataTagged.h"
00025 #include "DataExpanded.h"
00026 #include "DataMaths.h"
00027 
00036 namespace escript {
00044 template <class BinaryFunction>
00045 inline void binaryOp(DataTagged& left, const DataConstant& right, 
00046              BinaryFunction operation)
00047 {
00048 //  binaryOp(left,right.getPointDataView(),operation);
00049   //
00050   // perform the operation on each tagged value
00051   const DataTagged::DataMapType& lookup=left.getTagLookup();
00052   DataTagged::DataMapType::const_iterator i;
00053   DataTagged::DataMapType::const_iterator lookupEnd=lookup.end();
00054   DataTypes::ValueType& leftVec=left.getVectorRW();
00055   const DataTypes::ShapeType& leftShape=left.getShape();
00056   const DataTypes::ShapeType& rightShape=right.getShape();
00057   double rvalue=right.getVectorRO()[0];     // for rank==0
00058   const DataTypes::ValueType& rightVec=right.getVectorRO();   // for rank>0
00059   if (right.getRank()==0) {
00060     for (i=lookup.begin();i!=lookupEnd;i++) {
00061       DataMaths::binaryOp(leftVec,leftShape,i->second,rvalue,operation);
00062     }
00063   } else {
00064     for (i=lookup.begin();i!=lookupEnd;i++) {
00065       DataMaths::binaryOp(leftVec, leftShape, i->second,rightVec,rightShape,0,operation);
00066     }
00067   }
00068   //
00069   // finally perform the operation on the default value
00070   if (right.getRank()==0) {
00071     DataMaths::binaryOp(leftVec,leftShape,left.getDefaultOffset(),rvalue,operation);
00072   } else {
00073     DataMaths::binaryOp(leftVec,leftShape,left.getDefaultOffset(),rightVec,rightShape,0,operation);
00074   }
00075 }
00076 
00082 template <class BinaryFunction>
00083 inline void binaryOp(DataTagged& left, const DataTypes::ValueType& right, 
00084              const DataTypes::ShapeType& shape,
00085              BinaryFunction operation)
00086 {
00087   //
00088   // perform the operation on each tagged value
00089   const DataTagged::DataMapType& lookup=left.getTagLookup();
00090   DataTagged::DataMapType::const_iterator i;
00091   DataTagged::DataMapType::const_iterator lookupEnd=lookup.end();
00092   DataTypes::ValueType& lvec=left.getVectorRW();
00093   const DataTypes::ShapeType& lshape=left.getShape();
00094   if (DataTypes::getRank(shape)==0) {
00095     for (i=lookup.begin();i!=lookupEnd;i++) {
00096       DataMaths::binaryOp(lvec, lshape,i->second,right[0],operation);
00097     }
00098   } else {
00099     for (i=lookup.begin();i!=lookupEnd;i++) {
00100       DataMaths::binaryOp(lvec, lshape, i->second,right,shape,0,operation);
00101     }
00102   }
00103   //
00104   // finally perform the operation on the default value
00105   if (DataTypes::getRank(shape)==0) {
00106     DataMaths::binaryOp(lvec,lshape,left.getDefaultOffset(),right[0],operation);
00107   } else {
00108     DataMaths::binaryOp(lvec,lshape,left.getDefaultOffset(),right, shape,0,operation);
00109   }
00110 }
00111 
00112 
00113 
00114 
00115 template <class BinaryFunction>
00116 inline void binaryOp(DataTagged& left, const DataTagged& right, 
00117              BinaryFunction operation)
00118 {
00119   using namespace DataMaths;
00120 
00121   int right_rank=right.getRank();
00122   //
00123   // Add the right hand tag keys which can't currently be found on the left
00124   const DataTagged::DataMapType& rightLookup=right.getTagLookup();
00125   DataTagged::DataMapType::const_iterator i;
00126   DataTagged::DataMapType::const_iterator rightLookupEnd=rightLookup.end();
00127   for (i=rightLookup.begin();i!=rightLookupEnd;i++) {
00128     //
00129     // If the left does not already have a value assigned to this tag,
00130     // add the right hand tag to the left hand tag list and assign
00131     // the left's default value.
00132     if (!left.isCurrentTag(i->first)) {
00133       left.addTag(i->first);
00134     }
00135   }
00136   DataTypes::ValueType& leftVec=left.getVectorRW();
00137   const DataTypes::ShapeType& leftShape=left.getShape();
00138   //
00139   // Perform the operation.
00140   const DataTagged::DataMapType& leftLookup=left.getTagLookup();
00141   DataTagged::DataMapType::const_iterator leftLookupEnd=leftLookup.end();
00142   for (i=leftLookup.begin();i!=leftLookupEnd;i++) {
00143     if (right_rank==0) {
00144        binaryOp(leftVec,leftShape,i->second, right.getDataByTagRO(i->first,0),operation);
00145 
00146     } else {    // rank>0
00147        binaryOp(leftVec,leftShape,left.getOffsetForTag(i->first),right.getVectorRO(), right.getShape(), right.getOffsetForTag(i->first), operation);
00148     }
00149   }
00150   //
00151   // finally perform the operation on the default value
00152   if (right_rank==0) {
00153      binaryOp(leftVec,leftShape, left.getDefaultOffset(), right.getVectorRO()[0],operation);
00154   } else {
00155      binaryOp(leftVec,leftShape, left.getDefaultOffset(), right.getVectorRO(), right.getShape(), right.getDefaultOffset(), operation);
00156   }
00157 }
00158 
00159 template <class BinaryFunction>
00160 inline void binaryOp(DataConstant& left, const DataConstant& right, 
00161              BinaryFunction operation)
00162 {
00163   if (right.getRank()==0) {
00164     double r=right.getVectorRO()[0];
00165     DataMaths::binaryOp(left.getVectorRW(), left.getShape(),0, r,operation);
00166   } else {
00167     DataMaths::binaryOp(left.getVectorRW(), left.getShape(),0, right.getVectorRO(),right.getShape(),0,operation);
00168   }
00169 
00170 }
00171 
00172 
00173 
00174 template <class BinaryFunction>
00175 inline void binaryOp(DataExpanded& left, const DataReady& right, 
00176              BinaryFunction operation)
00177 {
00178   int i,j;
00179   DataTypes::ValueType::size_type numDPPSample=left.getNumDPPSample();
00180   DataTypes::ValueType::size_type numSamples=left.getNumSamples();
00181   if (right.getRank()==0) {
00182 
00183     const DataTypes::ShapeType& leftShape=left.getShape();
00184     DataTypes::ValueType& leftVec=left.getVectorRW();
00185     //
00186     // This will call the double version of binaryOp
00187     #pragma omp parallel for private(i,j) schedule(static)
00188     for (i=0;i<numSamples;i++) {
00189       for (j=0;j<numDPPSample;j++) {
00190     DataMaths::binaryOp(leftVec,leftShape,left.getPointOffset(i,j), right.getVectorRO()[right.getPointOffset(i,j)]  ,operation);
00191       }
00192     }
00193   } else {
00194     #pragma omp parallel for private(i,j) schedule(static)
00195     for (i=0;i<numSamples;i++) {
00196       for (j=0;j<numDPPSample;j++) {
00197     DataMaths::binaryOp(left.getVectorRW(),left.getShape(),left.getPointOffset(i,j), right.getVectorRO(), right.getShape(),right.getPointOffset(i,j), operation);
00198       }
00199     }
00200   }
00201 }
00202 
00203 
00204 } // end of namespace
00205 
00206 #endif