Escript  Revision_4320
BinaryOp.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_BinaryOp_20040315_H
18 #define escript_BinaryOp_20040315_H
19 #include "system_dep.h"
20 
21 #include "DataTypes.h"
22 #include "DataConstant.h"
23 #include "DataTagged.h"
24 #include "DataExpanded.h"
25 #include "DataMaths.h"
26 
35 namespace escript {
43 template <class BinaryFunction>
44 inline void binaryOp(DataTagged& left, const DataConstant& right,
45  BinaryFunction operation)
46 {
47 // binaryOp(left,right.getPointDataView(),operation);
48  //
49  // perform the operation on each tagged value
50  const DataTagged::DataMapType& lookup=left.getTagLookup();
51  DataTagged::DataMapType::const_iterator i;
52  DataTagged::DataMapType::const_iterator lookupEnd=lookup.end();
53  DataTypes::ValueType& leftVec=left.getVectorRW();
54  const DataTypes::ShapeType& leftShape=left.getShape();
55  const DataTypes::ShapeType& rightShape=right.getShape();
56  double rvalue=right.getVectorRO()[0]; // for rank==0
57  const DataTypes::ValueType& rightVec=right.getVectorRO(); // for rank>0
58  if (right.getRank()==0) {
59  for (i=lookup.begin();i!=lookupEnd;i++) {
60  DataMaths::binaryOp(leftVec,leftShape,i->second,rvalue,operation);
61  }
62  } else {
63  for (i=lookup.begin();i!=lookupEnd;i++) {
64  DataMaths::binaryOp(leftVec, leftShape, i->second,rightVec,rightShape,0,operation);
65  }
66  }
67  //
68  // finally perform the operation on the default value
69  if (right.getRank()==0) {
70  DataMaths::binaryOp(leftVec,leftShape,left.getDefaultOffset(),rvalue,operation);
71  } else {
72  DataMaths::binaryOp(leftVec,leftShape,left.getDefaultOffset(),rightVec,rightShape,0,operation);
73  }
74 }
75 
81 template <class BinaryFunction>
82 inline void binaryOp(DataTagged& left, const DataTypes::ValueType& right,
83  const DataTypes::ShapeType& shape,
84  BinaryFunction operation)
85 {
86  //
87  // perform the operation on each tagged value
88  const DataTagged::DataMapType& lookup=left.getTagLookup();
89  DataTagged::DataMapType::const_iterator i;
90  DataTagged::DataMapType::const_iterator lookupEnd=lookup.end();
91  DataTypes::ValueType& lvec=left.getVectorRW();
92  const DataTypes::ShapeType& lshape=left.getShape();
93  if (DataTypes::getRank(shape)==0) {
94  for (i=lookup.begin();i!=lookupEnd;i++) {
95  DataMaths::binaryOp(lvec, lshape,i->second,right[0],operation);
96  }
97  } else {
98  for (i=lookup.begin();i!=lookupEnd;i++) {
99  DataMaths::binaryOp(lvec, lshape, i->second,right,shape,0,operation);
100  }
101  }
102  //
103  // finally perform the operation on the default value
104  if (DataTypes::getRank(shape)==0) {
105  DataMaths::binaryOp(lvec,lshape,left.getDefaultOffset(),right[0],operation);
106  } else {
107  DataMaths::binaryOp(lvec,lshape,left.getDefaultOffset(),right, shape,0,operation);
108  }
109 }
110 
111 
112 
113 
114 template <class BinaryFunction>
115 inline void binaryOp(DataTagged& left, const DataTagged& right,
116  BinaryFunction operation)
117 {
118  using namespace DataMaths;
119 
120  int right_rank=right.getRank();
121  //
122  // Add the right hand tag keys which can't currently be found on the left
123  const DataTagged::DataMapType& rightLookup=right.getTagLookup();
124  DataTagged::DataMapType::const_iterator i;
125  DataTagged::DataMapType::const_iterator rightLookupEnd=rightLookup.end();
126  for (i=rightLookup.begin();i!=rightLookupEnd;i++) {
127  //
128  // If the left does not already have a value assigned to this tag,
129  // add the right hand tag to the left hand tag list and assign
130  // the left's default value.
131  if (!left.isCurrentTag(i->first)) {
132  left.addTag(i->first);
133  }
134  }
135  DataTypes::ValueType& leftVec=left.getVectorRW();
136  const DataTypes::ShapeType& leftShape=left.getShape();
137  //
138  // Perform the operation.
139  const DataTagged::DataMapType& leftLookup=left.getTagLookup();
140  DataTagged::DataMapType::const_iterator leftLookupEnd=leftLookup.end();
141  for (i=leftLookup.begin();i!=leftLookupEnd;i++) {
142  if (right_rank==0) {
143  binaryOp(leftVec,leftShape,i->second, right.getDataByTagRO(i->first,0),operation);
144 
145  } else { // rank>0
146  binaryOp(leftVec,leftShape,left.getOffsetForTag(i->first),right.getVectorRO(), right.getShape(), right.getOffsetForTag(i->first), operation);
147  }
148  }
149  //
150  // finally perform the operation on the default value
151  if (right_rank==0) {
152  binaryOp(leftVec,leftShape, left.getDefaultOffset(), right.getVectorRO()[0],operation);
153  } else {
154  binaryOp(leftVec,leftShape, left.getDefaultOffset(), right.getVectorRO(), right.getShape(), right.getDefaultOffset(), operation);
155  }
156 }
157 
158 template <class BinaryFunction>
159 inline void binaryOp(DataConstant& left, const DataConstant& right,
160  BinaryFunction operation)
161 {
162  if (right.getRank()==0) {
163  double r=right.getVectorRO()[0];
164  DataMaths::binaryOp(left.getVectorRW(), left.getShape(),0, r,operation);
165  } else {
166  DataMaths::binaryOp(left.getVectorRW(), left.getShape(),0, right.getVectorRO(),right.getShape(),0,operation);
167  }
168 
169 }
170 
171 
172 
173 template <class BinaryFunction>
174 inline void binaryOp(DataExpanded& left, const DataReady& right,
175  BinaryFunction operation)
176 {
177  int i,j;
180  if (right.getRank()==0) {
181 
182  const DataTypes::ShapeType& leftShape=left.getShape();
183  DataTypes::ValueType& leftVec=left.getVectorRW();
184  //
185  // This will call the double version of binaryOp
186  #pragma omp parallel for private(i,j) schedule(static)
187  for (i=0;i<numSamples;i++) {
188  for (j=0;j<numDPPSample;j++) {
189  DataMaths::binaryOp(leftVec,leftShape,left.getPointOffset(i,j), right.getVectorRO()[right.getPointOffset(i,j)] ,operation);
190  }
191  }
192  } else {
193  #pragma omp parallel for private(i,j) schedule(static)
194  for (i=0;i<numSamples;i++) {
195  for (j=0;j<numDPPSample;j++) {
196  DataMaths::binaryOp(left.getVectorRW(),left.getShape(),left.getPointOffset(i,j), right.getVectorRO(), right.getShape(),right.getPointOffset(i,j), operation);
197  }
198  }
199  }
200 }
201 
202 
203 } // end of namespace
204 
205 #endif