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