1 |
jgs |
82 |
/* |
2 |
|
|
****************************************************************************** |
3 |
|
|
* * |
4 |
|
|
* COPYRIGHT ACcESS 2004 - All Rights Reserved * |
5 |
|
|
* * |
6 |
|
|
* This software is the property of ACcESS. No part of this code * |
7 |
|
|
* may be copied in any form or by any means without the expressed written * |
8 |
|
|
* consent of ACcESS. Copying, use or modification of this software * |
9 |
|
|
* by any unauthorised person is illegal unless that person has a software * |
10 |
|
|
* license agreement with ACcESS. * |
11 |
|
|
* * |
12 |
|
|
****************************************************************************** |
13 |
|
|
*/ |
14 |
|
|
|
15 |
|
|
#if !defined escript_DataArrayView_20040323_H |
16 |
|
|
#define escript_DataArrayView_20040323_H |
17 |
|
|
|
18 |
|
|
#include "esysUtils/EsysAssert.h" |
19 |
|
|
|
20 |
|
|
#include <vector> |
21 |
|
|
#include <boost/python/numeric.hpp> |
22 |
|
|
#include <boost/python/object.hpp> |
23 |
|
|
#include <boost/shared_ptr.hpp> |
24 |
|
|
|
25 |
|
|
namespace escript { |
26 |
|
|
|
27 |
|
|
/** |
28 |
|
|
\brief |
29 |
|
|
DataArrayView provides a view of data allocated externally. |
30 |
|
|
|
31 |
|
|
Description: |
32 |
|
|
DataArrayView provides a view of data allocated externally. The |
33 |
|
|
external data should provide sufficient values so that the dimensions |
34 |
|
|
specified for the view will be satisfied. The viewer can update |
35 |
|
|
values within the external data but cannot resize the external data. |
36 |
|
|
*/ |
37 |
|
|
|
38 |
|
|
class DataArrayView { |
39 |
|
|
|
40 |
|
|
friend bool operator==(const DataArrayView& left, const DataArrayView& right); |
41 |
|
|
friend bool operator!=(const DataArrayView& left, const DataArrayView& right); |
42 |
|
|
|
43 |
|
|
public: |
44 |
|
|
|
45 |
|
|
typedef std::vector<double> ValueType; |
46 |
|
|
typedef std::vector<int> ShapeType; |
47 |
|
|
typedef std::vector<std::pair<int, int> > RegionType; |
48 |
|
|
|
49 |
|
|
/** |
50 |
|
|
\brief |
51 |
|
|
Default constructor for DataArrayView. |
52 |
|
|
|
53 |
|
|
Description: |
54 |
|
|
Default constructor for DataArrayView. Creates an |
55 |
|
|
empty view with no associated data. |
56 |
|
|
*/ |
57 |
|
|
DataArrayView(); |
58 |
|
|
|
59 |
|
|
/** |
60 |
|
|
\brief |
61 |
|
|
Constructor for DataArrayView. |
62 |
|
|
|
63 |
|
|
Description: |
64 |
|
|
Constructor for DataArrayView. |
65 |
|
|
|
66 |
|
|
\param data - Input - Container holding data to be viewed. This must |
67 |
|
|
be large enough for the specified shape. |
68 |
|
|
\param viewShape - Input - The shape of the view. |
69 |
|
|
\param offset - Input - Offset into the data at which view should start. |
70 |
|
|
*/ |
71 |
|
|
DataArrayView(ValueType& data, |
72 |
|
|
const ShapeType& viewShape, |
73 |
|
|
int offset=0); |
74 |
|
|
|
75 |
|
|
/** |
76 |
|
|
\brief |
77 |
|
|
Copy constructor for DataArrayView. |
78 |
|
|
|
79 |
|
|
Description: |
80 |
|
|
Copy constructor for DataArrayView. |
81 |
|
|
|
82 |
|
|
\param other - Input - DataArrayView to copy. |
83 |
|
|
|
84 |
|
|
NOTE: The copy references the same data container. |
85 |
|
|
*/ |
86 |
|
|
DataArrayView(const DataArrayView& other); |
87 |
|
|
|
88 |
|
|
/** |
89 |
|
|
\brief |
90 |
|
|
Check if view is empty. |
91 |
|
|
*/ |
92 |
|
|
bool |
93 |
|
|
isEmpty() const; |
94 |
|
|
|
95 |
|
|
/** |
96 |
|
|
\brief |
97 |
|
|
Copy from a numarray into the data managed by DataArrayView. |
98 |
|
|
*/ |
99 |
|
|
void |
100 |
|
|
copy(const boost::python::numeric::array& value); |
101 |
|
|
|
102 |
|
|
/** |
103 |
|
|
\brief |
104 |
|
|
Copy from another DataArrayViewinto the data managed by this |
105 |
|
|
DataArrayView at the default offset. |
106 |
|
|
*/ |
107 |
|
|
void |
108 |
|
|
copy(const DataArrayView& other); |
109 |
|
|
|
110 |
|
|
/** |
111 |
|
|
\brief |
112 |
|
|
Copy from another DataArrayView into this view at the |
113 |
|
|
given offset. |
114 |
|
|
*/ |
115 |
|
|
void |
116 |
|
|
copy(ValueType::size_type offset, |
117 |
|
|
const DataArrayView& other); |
118 |
|
|
|
119 |
|
|
/** |
120 |
|
|
\brief |
121 |
|
|
Copy from another DataArrayView into this view at the |
122 |
|
|
given offsets. |
123 |
|
|
|
124 |
|
|
\param thisOffset - Input - Offset into this view's data array to copy to. |
125 |
|
|
\param other - Input - View for the data to copy. |
126 |
|
|
\param otherOffset - Input - Offset into the other view to copy data from. |
127 |
|
|
*/ |
128 |
|
|
void |
129 |
|
|
copy(ValueType::size_type thisOffset, |
130 |
|
|
const DataArrayView& other, |
131 |
|
|
ValueType::size_type otherOffset); |
132 |
|
|
|
133 |
|
|
/** |
134 |
|
|
\brief |
135 |
|
|
Copy the given single value over the entire view. |
136 |
|
|
|
137 |
|
|
\param offset - Input - Offset into this view's data array to copy to. |
138 |
|
|
\param value - Input - Value to copy. |
139 |
|
|
*/ |
140 |
|
|
void |
141 |
|
|
copy(ValueType::size_type offset, |
142 |
|
|
ValueType::value_type value); |
143 |
|
|
|
144 |
|
|
/** |
145 |
|
|
\brief |
146 |
|
|
Return this view's offset to the start of data. |
147 |
|
|
*/ |
148 |
|
|
ValueType::size_type |
149 |
|
|
getOffset() const; |
150 |
|
|
|
151 |
|
|
/** |
152 |
|
|
\brief |
153 |
|
|
Return the rank of the data. |
154 |
|
|
*/ |
155 |
|
|
int |
156 |
|
|
getRank() const; |
157 |
|
|
|
158 |
|
|
/** |
159 |
|
|
\brief |
160 |
|
|
Return the shape of the data. |
161 |
|
|
*/ |
162 |
|
|
const ShapeType& |
163 |
|
|
getShape() const; |
164 |
|
|
|
165 |
|
|
/** |
166 |
|
|
\brief |
167 |
|
|
Calculate the number of values for the given shape. |
168 |
|
|
*/ |
169 |
|
|
static int |
170 |
|
|
noValues(const ShapeType& shape); |
171 |
|
|
|
172 |
|
|
/** |
173 |
|
|
\brief |
174 |
|
|
Return the number of values for the current view. |
175 |
|
|
*/ |
176 |
|
|
int |
177 |
|
|
noValues() const; |
178 |
|
|
|
179 |
|
|
/** |
180 |
|
|
\brief |
181 |
jgs |
100 |
Return true if the shapes are the same. |
182 |
jgs |
82 |
*/ |
183 |
|
|
bool |
184 |
|
|
checkShape(const DataArrayView::ShapeType& other) const; |
185 |
|
|
|
186 |
|
|
/** |
187 |
|
|
\brief |
188 |
|
|
Return a reference to the underlying data. |
189 |
|
|
*/ |
190 |
|
|
ValueType& |
191 |
|
|
getData() const; |
192 |
|
|
|
193 |
|
|
/** |
194 |
|
|
\brief |
195 |
|
|
Return the value with the given index for the view. This takes into account |
196 |
|
|
the offset. Effectively this returns each value of the view in sequential order. |
197 |
|
|
*/ |
198 |
|
|
ValueType::reference |
199 |
|
|
getData(ValueType::size_type i) const; |
200 |
|
|
|
201 |
|
|
/** |
202 |
|
|
\brief |
203 |
|
|
Create a shape error message. Normally used when there is a shape |
204 |
|
|
mismatch. |
205 |
|
|
|
206 |
|
|
\param messagePrefix - Input - First part of the error message. |
207 |
|
|
\param other - Input - The other shape. |
208 |
|
|
*/ |
209 |
|
|
std::string |
210 |
|
|
createShapeErrorMessage(const std::string& messagePrefix, |
211 |
|
|
const DataArrayView::ShapeType& other) const; |
212 |
|
|
|
213 |
|
|
/** |
214 |
|
|
\brief |
215 |
|
|
Set the offset into the array. |
216 |
|
|
*/ |
217 |
|
|
void |
218 |
|
|
setOffset(ValueType::size_type offset); |
219 |
|
|
|
220 |
|
|
/** |
221 |
|
|
\brief |
222 |
|
|
Return the shape of a data view following the slice specified. |
223 |
|
|
|
224 |
|
|
\param region - Input - Slice region. |
225 |
|
|
*/ |
226 |
|
|
static DataArrayView::ShapeType |
227 |
|
|
getResultSliceShape(const RegionType& region); |
228 |
|
|
|
229 |
|
|
/** |
230 |
|
|
\brief |
231 |
jgs |
100 |
Copy a slice from the given view. This view must be the right shape for the slice. |
232 |
jgs |
82 |
|
233 |
jgs |
100 |
\param other - Input - Data to copy from. |
234 |
|
|
\param region - Input - Slice region. |
235 |
jgs |
82 |
*/ |
236 |
|
|
void |
237 |
|
|
copySlice(const DataArrayView& other, |
238 |
|
|
const RegionType& region); |
239 |
|
|
|
240 |
|
|
/** |
241 |
|
|
\brief |
242 |
jgs |
100 |
Copy a slice from the given view. This view must be the right shape for the slice. |
243 |
jgs |
82 |
|
244 |
jgs |
100 |
\param thisOffset - Input - use this view offset instead of the default. |
245 |
|
|
\param other - Input - Data to copy from. |
246 |
|
|
\param otherOffset - Input - use this slice offset instead of the default. |
247 |
|
|
\param region - Input - Slice region. |
248 |
jgs |
82 |
*/ |
249 |
|
|
void |
250 |
|
|
copySlice(ValueType::size_type thisOffset, |
251 |
|
|
const DataArrayView& other, |
252 |
|
|
ValueType::size_type otherOffset, |
253 |
|
|
const RegionType& region); |
254 |
|
|
|
255 |
|
|
/** |
256 |
|
|
\brief |
257 |
jgs |
100 |
Copy into a slice from the given view. This view must have the same rank as the slice region. |
258 |
jgs |
82 |
|
259 |
|
|
\param other - Input - Data to copy from. |
260 |
|
|
\param region - Input - Slice region. |
261 |
|
|
*/ |
262 |
|
|
void |
263 |
|
|
copySliceFrom(const DataArrayView& other, |
264 |
|
|
const RegionType& region); |
265 |
|
|
|
266 |
|
|
/** |
267 |
|
|
\brief |
268 |
jgs |
100 |
Copy into a slice from the given value. This view must have the same rank as the slice region. |
269 |
jgs |
82 |
|
270 |
|
|
\param thisOffset - Input - use this view offset instead of the default. |
271 |
|
|
\param other - Input - Data to copy from. |
272 |
|
|
\param otherOffset - Input - use this slice offset instead of the default. |
273 |
|
|
\param region - Input - Slice region. |
274 |
|
|
*/ |
275 |
|
|
void |
276 |
|
|
copySliceFrom(ValueType::size_type thisOffset, |
277 |
|
|
const DataArrayView& other, |
278 |
|
|
ValueType::size_type otherOffset, |
279 |
|
|
const RegionType& region); |
280 |
|
|
|
281 |
|
|
/** |
282 |
|
|
\brief |
283 |
|
|
Determine the shape of the result array for a matrix multiplication. |
284 |
|
|
*/ |
285 |
|
|
static ShapeType |
286 |
|
|
determineResultShape(const DataArrayView& left, |
287 |
|
|
const DataArrayView& right); |
288 |
|
|
|
289 |
|
|
/** |
290 |
|
|
\brief |
291 |
jgs |
100 |
Returns the range for the slices defined by the key which is a Python |
292 |
|
|
slice object or a tuple of Python slice object. |
293 |
jgs |
82 |
*/ |
294 |
|
|
DataArrayView::RegionType |
295 |
|
|
getSliceRegion(const boost::python::object& key) const; |
296 |
jgs |
100 |
/* |
297 |
|
|
DataArrayView::RegionType |
298 |
|
|
getSliceRegion2(const boost::python::object& key) const; |
299 |
|
|
*/ |
300 |
jgs |
82 |
|
301 |
|
|
// ******************************************************************* |
302 |
|
|
// NOTE: The following relIndex functions are a hack. The indexing |
303 |
|
|
// mechanism should be split out from DataArrayView to get the flexability |
304 |
|
|
// needed. |
305 |
|
|
|
306 |
|
|
/** |
307 |
|
|
\brief |
308 |
|
|
Return the 1 dimensional index of the element at position i,j,k,m |
309 |
|
|
ignoring the offset. |
310 |
|
|
*/ |
311 |
|
|
ValueType::size_type |
312 |
|
|
relIndex(ValueType::size_type i, |
313 |
|
|
ValueType::size_type j, |
314 |
|
|
ValueType::size_type k, |
315 |
|
|
ValueType::size_type m) const; |
316 |
|
|
|
317 |
|
|
/** |
318 |
|
|
\brief |
319 |
|
|
Return the 1 dimensional index of the element at position i,j,k |
320 |
|
|
ignoring the offset. |
321 |
|
|
*/ |
322 |
|
|
ValueType::size_type |
323 |
|
|
relIndex(ValueType::size_type i, |
324 |
|
|
ValueType::size_type j, |
325 |
|
|
ValueType::size_type k) const; |
326 |
|
|
|
327 |
|
|
/** |
328 |
|
|
\brief |
329 |
|
|
Return the 1 dimensional index of the element at position i,j |
330 |
|
|
ignoring the offset. |
331 |
|
|
*/ |
332 |
|
|
ValueType::size_type |
333 |
|
|
relIndex(ValueType::size_type i, |
334 |
|
|
ValueType::size_type j) const; |
335 |
|
|
|
336 |
|
|
// ******************************************************************** |
337 |
|
|
|
338 |
|
|
/** |
339 |
|
|
\brief |
340 |
|
|
Return the 1 dimensional index of the element at position i,j,k,m. |
341 |
|
|
*/ |
342 |
|
|
ValueType::size_type |
343 |
|
|
index(ValueType::size_type i, |
344 |
|
|
ValueType::size_type j, |
345 |
|
|
ValueType::size_type k, |
346 |
|
|
ValueType::size_type m) const; |
347 |
|
|
|
348 |
|
|
/** |
349 |
|
|
\brief |
350 |
|
|
Return the 1 dimensional index of the element at position i,j,k. |
351 |
|
|
*/ |
352 |
|
|
ValueType::size_type |
353 |
|
|
index(ValueType::size_type i, |
354 |
|
|
ValueType::size_type j, |
355 |
|
|
ValueType::size_type k) const; |
356 |
|
|
|
357 |
|
|
/** |
358 |
|
|
\brief |
359 |
|
|
Return the 1 dimensional index of the element at position i,j. |
360 |
|
|
*/ |
361 |
|
|
ValueType::size_type |
362 |
|
|
index(ValueType::size_type i, |
363 |
|
|
ValueType::size_type j) const; |
364 |
|
|
|
365 |
|
|
/** |
366 |
|
|
\brief |
367 |
|
|
Return the 1 dimensional index of the element at position i. |
368 |
|
|
*/ |
369 |
|
|
ValueType::size_type |
370 |
|
|
index(ValueType::size_type i) const; |
371 |
|
|
|
372 |
|
|
/** |
373 |
|
|
\brief |
374 |
|
|
Return a reference to the element at position i. |
375 |
|
|
*/ |
376 |
|
|
ValueType::reference |
377 |
|
|
operator()(ValueType::size_type i); |
378 |
|
|
|
379 |
|
|
ValueType::const_reference |
380 |
|
|
operator()(ValueType::size_type i) const; |
381 |
|
|
|
382 |
|
|
/** |
383 |
|
|
\brief |
384 |
|
|
Return a reference to the element at position i,j. |
385 |
|
|
*/ |
386 |
|
|
ValueType::reference |
387 |
|
|
operator()(ValueType::size_type i, |
388 |
|
|
ValueType::size_type j); |
389 |
|
|
|
390 |
|
|
ValueType::const_reference |
391 |
|
|
operator()(ValueType::size_type i, |
392 |
|
|
ValueType::size_type j) const; |
393 |
|
|
|
394 |
|
|
/** |
395 |
|
|
\brief |
396 |
|
|
Return a reference to the element at position i,j,k. |
397 |
|
|
*/ |
398 |
|
|
ValueType::reference |
399 |
|
|
operator()(ValueType::size_type i, |
400 |
|
|
ValueType::size_type j, |
401 |
|
|
ValueType::size_type k); |
402 |
|
|
|
403 |
|
|
ValueType::const_reference |
404 |
|
|
operator()(ValueType::size_type i, |
405 |
|
|
ValueType::size_type j, |
406 |
|
|
ValueType::size_type k) const; |
407 |
|
|
|
408 |
|
|
/** |
409 |
|
|
\brief |
410 |
|
|
Return a reference to the element at position i,j,k,m. |
411 |
|
|
*/ |
412 |
|
|
ValueType::reference |
413 |
|
|
operator()(ValueType::size_type i, |
414 |
|
|
ValueType::size_type j, |
415 |
|
|
ValueType::size_type k, |
416 |
|
|
ValueType::size_type m); |
417 |
|
|
|
418 |
|
|
ValueType::const_reference |
419 |
|
|
operator()(ValueType::size_type i, |
420 |
|
|
ValueType::size_type j, |
421 |
|
|
ValueType::size_type k, |
422 |
|
|
ValueType::size_type m) const; |
423 |
|
|
|
424 |
|
|
/** |
425 |
|
|
\brief |
426 |
|
|
Return a reference for the only element, assuming rank 0. |
427 |
|
|
*/ |
428 |
|
|
ValueType::reference |
429 |
|
|
operator()(); |
430 |
|
|
|
431 |
|
|
ValueType::const_reference |
432 |
|
|
operator()() const; |
433 |
|
|
|
434 |
|
|
/** |
435 |
|
|
\brief |
436 |
|
|
Perform the unary operation using the given offset |
437 |
|
|
instead of the offset defined within the view. |
438 |
|
|
*/ |
439 |
|
|
template <class UnaryFunction> |
440 |
|
|
void |
441 |
|
|
unaryOp(ValueType::size_type leftOffset, |
442 |
|
|
UnaryFunction operation); |
443 |
|
|
|
444 |
|
|
/** |
445 |
|
|
\brief |
446 |
|
|
Perform the unary operation using the view's offset. |
447 |
|
|
*/ |
448 |
|
|
template <class UnaryFunction> |
449 |
|
|
void |
450 |
|
|
unaryOp(UnaryFunction operation); |
451 |
|
|
|
452 |
|
|
/** |
453 |
|
|
\brief |
454 |
|
|
Perform the given operation and return a result. |
455 |
|
|
*/ |
456 |
|
|
template <class UnaryFunction> |
457 |
|
|
double |
458 |
|
|
algorithm(ValueType::size_type leftOffset, |
459 |
|
|
UnaryFunction operation) const; |
460 |
|
|
|
461 |
|
|
/** |
462 |
|
|
\brief |
463 |
|
|
Perform the given operation and return a result. Use the default offset. |
464 |
|
|
*/ |
465 |
|
|
template <class UnaryFunction> |
466 |
|
|
double |
467 |
|
|
algorithm(UnaryFunction operation) const; |
468 |
|
|
|
469 |
|
|
/** |
470 |
|
|
\brief |
471 |
|
|
Perform the binary operation. Version which applies a double value |
472 |
|
|
to all values within the view. The given offset is used instead of |
473 |
|
|
the default offset specified within the view. |
474 |
|
|
*/ |
475 |
|
|
template <class BinaryFunction> |
476 |
|
|
void |
477 |
|
|
binaryOp(ValueType::size_type leftOffset, |
478 |
|
|
double right, |
479 |
|
|
BinaryFunction operation); |
480 |
|
|
|
481 |
|
|
/** |
482 |
|
|
\brief |
483 |
|
|
Perform the binary operation. Version which applies a double value |
484 |
|
|
to all values within the view. |
485 |
|
|
*/ |
486 |
|
|
template <class BinaryFunction> |
487 |
|
|
void |
488 |
|
|
binaryOp(double right, |
489 |
|
|
BinaryFunction operation); |
490 |
|
|
|
491 |
|
|
/** |
492 |
|
|
\brief |
493 |
|
|
Perform the binary operation. The given offsets override the default |
494 |
|
|
offsets specified within the views. |
495 |
|
|
*/ |
496 |
|
|
template <class BinaryFunction> |
497 |
|
|
void |
498 |
|
|
binaryOp(ValueType::size_type leftOffset, |
499 |
|
|
const DataArrayView& right, |
500 |
|
|
ValueType::size_type rightOffset, |
501 |
|
|
BinaryFunction operation); |
502 |
|
|
|
503 |
|
|
/** |
504 |
|
|
\brief |
505 |
|
|
Perform the binary operation. |
506 |
|
|
*/ |
507 |
|
|
template <class BinaryFunction> |
508 |
|
|
void |
509 |
|
|
binaryOp(const DataArrayView& right, |
510 |
|
|
BinaryFunction operation); |
511 |
|
|
|
512 |
|
|
/** |
513 |
|
|
\brief |
514 |
|
|
Return the data as a string. Not recommended for very large objects. |
515 |
|
|
\param suffix - Input - Suffix appended to index display. |
516 |
|
|
*/ |
517 |
|
|
std::string |
518 |
|
|
toString(const std::string& suffix=std::string("")) const; |
519 |
|
|
|
520 |
|
|
/** |
521 |
|
|
\brief |
522 |
|
|
Return the given shape as a string. |
523 |
|
|
|
524 |
|
|
\param shape - Input. |
525 |
|
|
*/ |
526 |
|
|
static std::string |
527 |
|
|
shapeToString(const DataArrayView::ShapeType& shape); |
528 |
|
|
|
529 |
|
|
/** |
530 |
|
|
\brief |
531 |
|
|
Perform matrix multiply. |
532 |
|
|
|
533 |
|
|
Description: |
534 |
|
|
Perform matrix multiply. |
535 |
|
|
|
536 |
|
|
\param left - Input - The left hand side. |
537 |
|
|
\param right - Input - The right hand side. |
538 |
|
|
\param result - Output - The result of the operation. |
539 |
|
|
*/ |
540 |
|
|
static void |
541 |
|
|
matMult(const DataArrayView& left, |
542 |
|
|
const DataArrayView& right, |
543 |
|
|
DataArrayView& result); |
544 |
|
|
|
545 |
|
|
protected: |
546 |
|
|
|
547 |
|
|
private: |
548 |
|
|
|
549 |
|
|
// |
550 |
|
|
static const int m_maxRank=4; |
551 |
|
|
|
552 |
|
|
// |
553 |
|
|
// The data values for the view. NOTE: This points to data external to the view. |
554 |
|
|
ValueType* m_data; |
555 |
|
|
|
556 |
|
|
// |
557 |
|
|
// The offset into the data array used by different views. |
558 |
|
|
ValueType::size_type m_offset; |
559 |
|
|
|
560 |
|
|
// |
561 |
|
|
// The shape of the data. |
562 |
|
|
ShapeType m_shape; |
563 |
|
|
|
564 |
|
|
// |
565 |
|
|
// The number of values needed for the array. |
566 |
|
|
int m_noValues; |
567 |
|
|
|
568 |
|
|
}; |
569 |
|
|
|
570 |
|
|
inline |
571 |
|
|
DataArrayView::ValueType::size_type |
572 |
|
|
DataArrayView::getOffset() const |
573 |
|
|
{ |
574 |
|
|
return m_offset; |
575 |
|
|
} |
576 |
|
|
|
577 |
|
|
inline |
578 |
|
|
DataArrayView::ValueType& |
579 |
|
|
DataArrayView::getData() const |
580 |
|
|
{ |
581 |
|
|
EsysAssert(!isEmpty(),"Error - View is empty"); |
582 |
|
|
return *m_data; |
583 |
|
|
} |
584 |
|
|
|
585 |
|
|
inline |
586 |
|
|
DataArrayView::ValueType::reference |
587 |
|
|
DataArrayView::getData(ValueType::size_type i) const |
588 |
|
|
{ |
589 |
|
|
// |
590 |
|
|
// don't do any checking to allow one past the end of the vector providing |
591 |
|
|
// the equivalent of end() |
592 |
|
|
return (*m_data)[i+m_offset]; |
593 |
|
|
} |
594 |
|
|
|
595 |
|
|
template <class UnaryFunction> |
596 |
|
|
inline |
597 |
|
|
void |
598 |
|
|
DataArrayView::unaryOp(ValueType::size_type leftOffset, |
599 |
|
|
UnaryFunction operation) |
600 |
|
|
{ |
601 |
jgs |
100 |
for (ValueType::size_type i=0;i<(noValues(m_shape));++i) { |
602 |
jgs |
82 |
(*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset]); |
603 |
|
|
} |
604 |
|
|
} |
605 |
|
|
|
606 |
|
|
template <class UnaryFunction> |
607 |
|
|
inline |
608 |
|
|
void |
609 |
|
|
DataArrayView::unaryOp(UnaryFunction operation) |
610 |
|
|
{ |
611 |
|
|
unaryOp(m_offset,operation); |
612 |
|
|
} |
613 |
|
|
|
614 |
|
|
template <class UnaryFunction> |
615 |
|
|
inline |
616 |
|
|
double |
617 |
|
|
DataArrayView::algorithm(ValueType::size_type leftOffset, |
618 |
|
|
UnaryFunction operation) const |
619 |
|
|
{ |
620 |
|
|
for (ValueType::size_type i=0;i<(noValues(m_shape));++i) { |
621 |
|
|
operation((*m_data)[i+leftOffset]); |
622 |
|
|
} |
623 |
|
|
return operation.getResult(); |
624 |
|
|
} |
625 |
|
|
|
626 |
|
|
template <class UnaryFunction> |
627 |
|
|
inline |
628 |
|
|
double |
629 |
|
|
DataArrayView::algorithm(UnaryFunction operation) const |
630 |
|
|
{ |
631 |
|
|
return algorithm(m_offset,operation); |
632 |
|
|
} |
633 |
|
|
|
634 |
|
|
template <class BinaryFunction> |
635 |
|
|
inline |
636 |
|
|
void |
637 |
|
|
DataArrayView::binaryOp(ValueType::size_type leftOffset, |
638 |
|
|
const DataArrayView& right, |
639 |
|
|
ValueType::size_type rightOffset, |
640 |
|
|
BinaryFunction operation) |
641 |
|
|
{ |
642 |
|
|
EsysAssert(getShape()==right.getShape(), |
643 |
|
|
"Error - Right hand shape: " << shapeToString(right.getShape()) << " doesn't match the left: " << shapeToString(getShape())); |
644 |
|
|
for (ValueType::size_type i=0;i<noValues();++i) { |
645 |
|
|
(*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset],(*right.m_data)[i+rightOffset]); |
646 |
|
|
} |
647 |
|
|
} |
648 |
|
|
|
649 |
|
|
template <class BinaryFunction> |
650 |
|
|
inline |
651 |
|
|
void |
652 |
|
|
DataArrayView::binaryOp(const DataArrayView& right, |
653 |
|
|
BinaryFunction operation) |
654 |
|
|
{ |
655 |
|
|
// |
656 |
|
|
// version using the offsets specified within the view |
657 |
|
|
binaryOp(m_offset,right,right.getOffset(),operation); |
658 |
|
|
} |
659 |
|
|
|
660 |
|
|
template <class BinaryFunction> |
661 |
|
|
inline |
662 |
|
|
void |
663 |
|
|
DataArrayView::binaryOp(ValueType::size_type leftOffset, |
664 |
|
|
double right, |
665 |
|
|
BinaryFunction operation) |
666 |
|
|
{ |
667 |
|
|
// |
668 |
|
|
// If a scalar is to be applied to the entire array force the caller to |
669 |
|
|
// explicitly specify a single value |
670 |
|
|
for (ValueType::size_type i=0;i<(noValues(m_shape));++i) { |
671 |
|
|
(*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset],right); |
672 |
|
|
} |
673 |
|
|
} |
674 |
|
|
|
675 |
|
|
template <class BinaryFunction> |
676 |
|
|
inline |
677 |
|
|
void |
678 |
|
|
DataArrayView::binaryOp(double right, |
679 |
|
|
BinaryFunction operation) |
680 |
|
|
{ |
681 |
|
|
// |
682 |
|
|
// use the default offset |
683 |
|
|
binaryOp(m_offset,right,operation); |
684 |
|
|
} |
685 |
|
|
|
686 |
|
|
inline |
687 |
|
|
DataArrayView::ValueType::size_type |
688 |
|
|
DataArrayView::index(ValueType::size_type i) const |
689 |
|
|
{ |
690 |
|
|
//EsysAssert((i >= 0) && (i < noValues(m_shape)), "Invalid index."); |
691 |
|
|
EsysAssert((i < noValues(m_shape)), "Invalid index."); |
692 |
|
|
return (i+m_offset); |
693 |
|
|
} |
694 |
|
|
|
695 |
|
|
inline |
696 |
|
|
DataArrayView::ValueType::size_type |
697 |
|
|
DataArrayView::relIndex(ValueType::size_type i, |
698 |
|
|
ValueType::size_type j) const |
699 |
|
|
{ |
700 |
|
|
ValueType::size_type temp=i+j*m_shape[0]; |
701 |
|
|
//EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index."); |
702 |
|
|
EsysAssert((temp < noValues(m_shape)), "Invalid index."); |
703 |
|
|
// |
704 |
|
|
// no offset |
705 |
|
|
return temp; |
706 |
|
|
} |
707 |
|
|
|
708 |
|
|
inline |
709 |
|
|
DataArrayView::ValueType::size_type |
710 |
|
|
DataArrayView::index(ValueType::size_type i, |
711 |
|
|
ValueType::size_type j) const |
712 |
|
|
{ |
713 |
|
|
ValueType::size_type temp=i+j*m_shape[0]; |
714 |
|
|
//EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index."); |
715 |
|
|
EsysAssert((temp < noValues(m_shape)), "Invalid index."); |
716 |
|
|
return (temp+m_offset); |
717 |
|
|
} |
718 |
|
|
|
719 |
|
|
inline |
720 |
|
|
DataArrayView::ValueType::size_type |
721 |
|
|
DataArrayView::relIndex(ValueType::size_type i, |
722 |
|
|
ValueType::size_type j, |
723 |
|
|
ValueType::size_type k) const |
724 |
|
|
{ |
725 |
|
|
ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0]; |
726 |
|
|
//EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index."); |
727 |
|
|
EsysAssert((temp < noValues(m_shape)), "Invalid index."); |
728 |
|
|
// |
729 |
|
|
// no offset |
730 |
|
|
return temp; |
731 |
|
|
} |
732 |
|
|
|
733 |
|
|
inline |
734 |
|
|
DataArrayView::ValueType::size_type |
735 |
|
|
DataArrayView::index(ValueType::size_type i, |
736 |
|
|
ValueType::size_type j, |
737 |
|
|
ValueType::size_type k) const |
738 |
|
|
{ |
739 |
|
|
ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0]; |
740 |
|
|
//EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index."); |
741 |
|
|
EsysAssert((temp < noValues(m_shape)), "Invalid index."); |
742 |
|
|
return (temp+m_offset); |
743 |
|
|
} |
744 |
|
|
|
745 |
|
|
inline |
746 |
|
|
DataArrayView::ValueType::size_type |
747 |
|
|
DataArrayView::relIndex(ValueType::size_type i, |
748 |
|
|
ValueType::size_type j, |
749 |
|
|
ValueType::size_type k, |
750 |
|
|
ValueType::size_type m) const |
751 |
|
|
{ |
752 |
|
|
ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0]+m*m_shape[2]*m_shape[1]*m_shape[0]; |
753 |
|
|
//EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index."); |
754 |
|
|
EsysAssert((temp < noValues(m_shape)), "Invalid index."); |
755 |
|
|
// |
756 |
|
|
// no offset |
757 |
|
|
return temp; |
758 |
|
|
} |
759 |
|
|
|
760 |
|
|
inline |
761 |
|
|
DataArrayView::ValueType::size_type |
762 |
|
|
DataArrayView::index(ValueType::size_type i, |
763 |
|
|
ValueType::size_type j, |
764 |
|
|
ValueType::size_type k, |
765 |
|
|
ValueType::size_type m) const |
766 |
|
|
{ |
767 |
|
|
ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0]+m*m_shape[2]*m_shape[1]*m_shape[0]; |
768 |
|
|
//EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index."); |
769 |
|
|
EsysAssert((temp < noValues(m_shape)), "Invalid index."); |
770 |
|
|
return (temp+m_offset); |
771 |
|
|
} |
772 |
|
|
|
773 |
|
|
inline |
774 |
|
|
DataArrayView::ValueType::reference |
775 |
|
|
DataArrayView::operator()(ValueType::size_type i, |
776 |
|
|
ValueType::size_type j, |
777 |
|
|
ValueType::size_type k, |
778 |
|
|
ValueType::size_type m) |
779 |
|
|
{ |
780 |
|
|
EsysAssert((getRank()==4), |
781 |
|
|
"Incorrect number of indices for the rank of this object."); |
782 |
|
|
return (*m_data)[index(i,j,k,m)]; |
783 |
|
|
} |
784 |
|
|
|
785 |
|
|
inline |
786 |
|
|
DataArrayView::ValueType::const_reference |
787 |
|
|
DataArrayView::operator()(ValueType::size_type i, |
788 |
|
|
ValueType::size_type j, |
789 |
|
|
ValueType::size_type k, |
790 |
|
|
ValueType::size_type m) const |
791 |
|
|
{ |
792 |
|
|
EsysAssert((getRank()==4), |
793 |
|
|
"Incorrect number of indices for the rank of this object."); |
794 |
|
|
return (*m_data)[index(i,j,k,m)]; |
795 |
|
|
} |
796 |
|
|
|
797 |
|
|
inline |
798 |
|
|
DataArrayView::ValueType::reference |
799 |
|
|
DataArrayView::operator()(ValueType::size_type i, |
800 |
|
|
ValueType::size_type j, |
801 |
|
|
ValueType::size_type k) |
802 |
|
|
{ |
803 |
|
|
EsysAssert((getRank()==3), |
804 |
|
|
"Incorrect number of indices for the rank of this object."); |
805 |
|
|
return (*m_data)[index(i,j,k)]; |
806 |
|
|
} |
807 |
|
|
|
808 |
|
|
inline |
809 |
|
|
DataArrayView::ValueType::const_reference |
810 |
|
|
DataArrayView::operator()(ValueType::size_type i, |
811 |
|
|
ValueType::size_type j, |
812 |
|
|
ValueType::size_type k) const |
813 |
|
|
{ |
814 |
|
|
EsysAssert((getRank()==3), |
815 |
|
|
"Incorrect number of indices for the rank of this object."); |
816 |
|
|
return (*m_data)[index(i,j,k)]; |
817 |
|
|
} |
818 |
|
|
|
819 |
|
|
inline |
820 |
|
|
DataArrayView::ValueType::reference |
821 |
|
|
DataArrayView::operator()(ValueType::size_type i, |
822 |
|
|
ValueType::size_type j) |
823 |
|
|
{ |
824 |
|
|
EsysAssert((getRank()==2), |
825 |
|
|
"Incorrect number of indices for the rank of this object."); |
826 |
|
|
return (*m_data)[index(i,j)]; |
827 |
|
|
} |
828 |
|
|
|
829 |
|
|
inline |
830 |
|
|
DataArrayView::ValueType::const_reference |
831 |
|
|
DataArrayView::operator()(ValueType::size_type i, |
832 |
|
|
ValueType::size_type j) const |
833 |
|
|
{ |
834 |
|
|
EsysAssert((getRank()==2), |
835 |
|
|
"Incorrect number of indices for the rank of this object."); |
836 |
|
|
return (*m_data)[index(i,j)]; |
837 |
|
|
} |
838 |
|
|
|
839 |
|
|
inline |
840 |
|
|
DataArrayView::ValueType::reference |
841 |
|
|
DataArrayView::operator()(ValueType::size_type i) |
842 |
|
|
{ |
843 |
|
|
EsysAssert((getRank()==1), |
844 |
|
|
"Incorrect number of indices for the rank of this object."); |
845 |
|
|
return (*m_data)[index(i)]; |
846 |
|
|
} |
847 |
|
|
|
848 |
|
|
inline |
849 |
|
|
DataArrayView::ValueType::const_reference |
850 |
|
|
DataArrayView::operator()(ValueType::size_type i) const |
851 |
|
|
{ |
852 |
|
|
EsysAssert((getRank()==1), |
853 |
|
|
"Incorrect number of indices for the rank of this object."); |
854 |
|
|
return (*m_data)[index(i)]; |
855 |
|
|
} |
856 |
|
|
|
857 |
|
|
inline |
858 |
|
|
DataArrayView::ValueType::reference |
859 |
|
|
DataArrayView::operator()() |
860 |
|
|
{ |
861 |
|
|
EsysAssert((getRank()==0), |
862 |
|
|
"Incorrect number of indices for the rank of this object."); |
863 |
|
|
return (*m_data)[m_offset]; |
864 |
|
|
} |
865 |
|
|
|
866 |
|
|
inline |
867 |
|
|
DataArrayView::ValueType::const_reference |
868 |
|
|
DataArrayView::operator()() const |
869 |
|
|
{ |
870 |
|
|
EsysAssert((getRank()==0), |
871 |
|
|
"Incorrect number of indices for the rank of this object."); |
872 |
|
|
return (*m_data)[m_offset]; |
873 |
|
|
} |
874 |
|
|
|
875 |
|
|
bool operator==(const DataArrayView& left, const DataArrayView& right); |
876 |
|
|
bool operator!=(const DataArrayView& left, const DataArrayView& right); |
877 |
|
|
|
878 |
jgs |
100 |
/* returns the python slice object key as a pair of ints where the first |
879 |
|
|
member is the start and the second member is the end. the presence of a possible |
880 |
|
|
step attribute with value different from one will truow an exception */ |
881 |
|
|
std::pair<int,int> |
882 |
|
|
getSliceRange(const int s, |
883 |
|
|
const boost::python::object& key); |
884 |
|
|
|
885 |
jgs |
82 |
} // end of namespace |
886 |
|
|
|
887 |
|
|
#endif |