/[escript]/trunk/escript/src/DataArrayView.h
ViewVC logotype

Contents of /trunk/escript/src/DataArrayView.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 474 - (show annotations)
Mon Jan 30 04:23:44 2006 UTC (14 years ago) by jgs
File MIME type: text/plain
File size: 34818 byte(s)
restructure escript source tree
move src/Data/* -> src
remove inc
modify #includes and cpppath settings accordingly

1 // $Id$
2
3 /*
4 ******************************************************************************
5 * *
6 * COPYRIGHT ACcESS 2004 - All Rights Reserved *
7 * *
8 * This software is the property of ACcESS. No part of this code *
9 * may be copied in any form or by any means without the expressed written *
10 * consent of ACcESS. Copying, use or modification of this software *
11 * by any unauthorised person is illegal unless that person has a software *
12 * license agreement with ACcESS. *
13 * *
14 ******************************************************************************
15 */
16
17 #if !defined escript_DataArrayView_20040323_H
18 #define escript_DataArrayView_20040323_H
19
20 #include "EsysAssert.h"
21
22 #include "DataException.h"
23 #include "DataVector.h"
24
25 #include <boost/python/extract.hpp>
26 #include <boost/python/numeric.hpp>
27 #include <boost/python/object.hpp>
28 #include <boost/shared_ptr.hpp>
29
30 #include <iostream>
31 #include <sstream>
32 #include <vector>
33 #include <iostream>
34
35 namespace escript {
36
37 /**
38 \brief
39 DataArrayView provides a view of external data, configured according
40 to the given shape information and offset.
41
42 Description:
43 DataArrayView provides a view of data allocated externally. The
44 external data should provide sufficient values so that the dimensions
45 specified for the view shape will be satisfied. The viewer can update
46 values within the external data but cannot resize the external data.
47
48 The view provided represents a single n-dimensional data-point
49 comprised of values taken from the given data array, starting at the
50 specified offset and extending for as many values as are necessary to
51 satisfy the given shape. The default offset can be changed, or different
52 offsets specified, in order to provide views of other data-points in
53 the underlying data array.
54 */
55
56 class DataArrayView {
57
58 friend bool operator==(const DataArrayView& left, const DataArrayView& right);
59 friend bool operator!=(const DataArrayView& left, const DataArrayView& right);
60
61 public:
62
63 //
64 // Some basic types which define the data values and view shapes.
65 typedef DataVector ValueType;
66 //typedef std::vector<double> ValueType;
67 typedef std::vector<int> ShapeType;
68 typedef std::vector<std::pair<int, int> > RegionType;
69 typedef std::vector<std::pair<int, int> > RegionLoopRangeType;
70
71 /**
72 \brief
73 Default constructor for DataArrayView.
74
75 Description:
76 Default constructor for DataArrayView.
77 Creates an empty view with no associated data array.
78
79 This is essentially useless but here for completeness.
80 */
81 DataArrayView();
82
83 /**
84 \brief
85 Constructor for DataArrayView.
86
87 Description:
88 Constructor for DataArrayView.
89
90 \param data - Input -
91 Array holding data to be viewed. This must be large enough
92 to supply sufficient values for the specified shape starting at
93 the given offset.
94 \param viewShape - Input -
95 The shape of the view to create.
96 \param offset - Input -
97 Offset into the data at which view should start.
98 */
99 DataArrayView(ValueType& data,
100 const ShapeType& viewShape,
101 int offset=0);
102
103 /**
104 \brief
105 Copy constructor for DataArrayView.
106
107 Description:
108 Copy constructor for DataArrayView.
109
110 \param other - Input -
111 DataArrayView to copy.
112
113 NOTE: The copy references the same data array.
114 */
115 DataArrayView(const DataArrayView& other);
116
117 /**
118 \brief
119 Copy from a numarray into the data array viewed by this.
120 This must have same shape as the given value - will throw if not.
121 */
122 void
123 copy(const boost::python::numeric::array& value);
124
125 /**
126 \brief
127 Copy data from another DataArrayView into the data array viewed by this
128 starting at the default offset in both views.
129 The shapes of both views must be the same - will throw if not.
130 NB: views may or may not reference same underlying data array!
131 */
132 void
133 copy(const DataArrayView& other);
134
135 /**
136 \brief
137 Copy data from another DataArrayView into this view starting at the
138 given offset in this view and the default offset in the other view.
139 The shapes of both views must be the same - will throw if not.
140 NB: views may or may not reference same underlying data array!
141 */
142 void
143 copy(ValueType::size_type offset,
144 const DataArrayView& other);
145
146 /**
147 \brief
148 Copy data from another DataArrayView into this view starting at the
149 given offsets in each view.
150 The shapes of both views must be compatible - will throw if not.
151 NB: views may or may not reference same underlying data array!
152
153 \param thisOffset - Input -
154 Offset into this view's data array to copy to.
155 \param other - Input -
156 View to copy data from.
157 \param otherOffset - Input -
158 Offset into the other view's data array to copy from.
159 */
160 void
161 copy(ValueType::size_type thisOffset,
162 const DataArrayView& other,
163 ValueType::size_type otherOffset);
164
165 /**
166 \brief
167 Copy the given single value over the entire view starting at the given
168 offset in the view's data array.
169
170 \param offset - Input -
171 Offset into this view's data array to copy to.
172 \param value - Input -
173 Value to copy.
174 */
175 void
176 copy(ValueType::size_type offset,
177 ValueType::value_type value);
178
179 /**
180 \brief
181 Check if view is empty. ie: does not point to any actual data.
182 */
183 bool
184 isEmpty() const;
185
186 /**
187 \brief
188 Return this view's offset into the viewed data array.
189 */
190 ValueType::size_type
191 getOffset() const;
192
193 /**
194 \brief
195 Set the offset into the data array at which this view is to start.
196 This could be used to step through the underlying data array by incrementing
197 the offset by noValues successively. Thus this view would provide a moving
198 window on the underlying data with the given shape.
199 */
200 void
201 setOffset(ValueType::size_type offset);
202
203 /**
204 \brief
205 Increment the offset by the number of values in the shape, if possible. Thus
206 moving the view onto the next data point of the given shape in the underlying
207 data array.
208 */
209 void
210 incrOffset();
211
212 /**
213 \brief
214 Check the (given) offset will not result in two few values being available in
215 the underlying data array for this view's shape.
216 */
217 bool
218 checkOffset() const;
219
220 bool
221 checkOffset(ValueType::size_type offset) const;
222
223 /**
224 \brief
225 Return the rank of the shape of this view.
226 */
227 int
228 getRank() const;
229
230 /**
231 \brief
232 Return the number of values for the shape of this view.
233 */
234 int
235 noValues() const;
236
237 /**
238 \brief
239 Calculate the number of values for the given shape or region.
240 This is purely a utility method and has no bearing on this view.
241 */
242 static
243 int
244 noValues(const ShapeType& shape);
245
246 static
247 int
248 noValues(const RegionLoopRangeType& region);
249
250 /**
251 \brief
252 Return a reference to the underlying data array.
253 */
254 ValueType&
255 getData() const;
256
257 /**
258 \brief
259 Return a reference to the data value with the given
260 index in this view. This takes into account the offset.
261 */
262 ValueType::reference
263 getData(ValueType::size_type i) const;
264
265 /**
266 \brief
267 Return the shape of this view.
268 */
269 const
270 ShapeType&
271 getShape() const;
272
273 /**
274 \brief
275 Return true if the given shape is the same as this view's shape.
276 */
277 bool
278 checkShape(const ShapeType& other) const;
279
280 /**
281 \brief
282 Create a shape error message. Normally used when there is a shape
283 mismatch between this shape and the other shape.
284
285 \param messagePrefix - Input -
286 First part of the error message.
287 \param other - Input -
288 The other shape.
289 */
290 std::string
291 createShapeErrorMessage(const std::string& messagePrefix,
292 const ShapeType& other) const;
293
294 /**
295 \brief
296 Return the viewed data as a formatted string.
297 Not recommended for very large objects!
298
299 \param suffix - Input -
300 Suffix appended to index display.
301 */
302 std::string
303 toString(const std::string& suffix=std::string("")) const;
304
305 /**
306 \brief
307 Return the given shape as a string.
308 This is purely a utility method and has no bearing on this view.
309
310 \param shape - Input.
311 */
312 static
313 std::string
314 shapeToString(const ShapeType& shape);
315
316 /**
317 \brief
318 Return the 1 dimensional index into the data array of the only element
319 in the view, *ignoring the offset*.
320 Assumes a rank 0 view.
321 */
322 ValueType::size_type
323 relIndex() const;
324
325 /**
326 \brief
327 Return the 1 dimensional index into the data array of the element at
328 position i in the view, *ignoring the offset*.
329 Assumes a rank 1 view.
330 */
331 ValueType::size_type
332 relIndex(ValueType::size_type i) const;
333
334 /**
335 \brief
336 Return the 1 dimensional index into the data array of the element at
337 position i,j in the view, *ignoring the offset*.
338 Assumes a rank 2 view.
339 */
340 ValueType::size_type
341 relIndex(ValueType::size_type i,
342 ValueType::size_type j) const;
343
344 /**
345 \brief
346 Return the 1 dimensional index into the data array of the element at
347 position i,j,k in the view, *ignoring the offset*.
348 Assumes a rank 3 view.
349 */
350 ValueType::size_type
351 relIndex(ValueType::size_type i,
352 ValueType::size_type j,
353 ValueType::size_type k) const;
354
355 /**
356 \brief
357 Return the 1 dimensional index into the data array of the element at
358 position i,j,k,m in the view, *ignoring the offset*.
359 Assumes a rank 4 view.
360 */
361 ValueType::size_type
362 relIndex(ValueType::size_type i,
363 ValueType::size_type j,
364 ValueType::size_type k,
365 ValueType::size_type m) const;
366
367 /**
368 \brief
369 Return the 1 dimensional index into the data array of the only element
370 in the view.
371 Assumes a rank 0 view.
372 */
373 ValueType::size_type
374 index() const;
375
376 /**
377 \brief
378 Return the 1 dimensional index into the data array of the element at
379 position i in the view.
380 Assumes a rank 1 view.
381 */
382 ValueType::size_type
383 index(ValueType::size_type i) const;
384
385 /**
386 \brief
387 Return the 1 dimensional index into the data array of the element at
388 position i,j in the view.
389 Assumes a rank 2 view.
390 */
391 ValueType::size_type
392 index(ValueType::size_type i,
393 ValueType::size_type j) const;
394
395 /**
396 \brief
397 Return the 1 dimensional index into the data array of the element at
398 position i,j,k in the view.
399 Assumes a rank 3 view.
400 */
401 ValueType::size_type
402 index(ValueType::size_type i,
403 ValueType::size_type j,
404 ValueType::size_type k) const;
405
406 /**
407 \brief
408 Return the 1 dimensional index into the data array of the element at
409 position i,j,k,m in the view.
410 Assumes a rank 4 view.
411 */
412 ValueType::size_type
413 index(ValueType::size_type i,
414 ValueType::size_type j,
415 ValueType::size_type k,
416 ValueType::size_type m) const;
417
418 /**
419 \brief
420 Return a reference for the only element in the view.
421 Assumes a rank 0 view.
422 */
423 ValueType::reference
424 operator()();
425
426 ValueType::const_reference
427 operator()() const;
428
429 /**
430 \brief
431 Return a reference to the element at position i in the view.
432 Assumes a rank 1 view.
433 */
434 ValueType::reference
435 operator()(ValueType::size_type i);
436
437 ValueType::const_reference
438 operator()(ValueType::size_type i) const;
439
440 /**
441 \brief
442 Return a reference to the element at position i,j in the view.
443 Assumes a rank 2 view.
444 */
445 ValueType::reference
446 operator()(ValueType::size_type i,
447 ValueType::size_type j);
448
449 ValueType::const_reference
450 operator()(ValueType::size_type i,
451 ValueType::size_type j) const;
452
453 /**
454 \brief
455 Return a reference to the element at position i,j,k in the view.
456 Assumes a rank 3 view.
457 */
458 ValueType::reference
459 operator()(ValueType::size_type i,
460 ValueType::size_type j,
461 ValueType::size_type k);
462
463 ValueType::const_reference
464 operator()(ValueType::size_type i,
465 ValueType::size_type j,
466 ValueType::size_type k) const;
467
468 /**
469 \brief
470 Return a reference to the element at position i,j,k,m in the view.
471 Assumes a rank 4 view.
472 */
473 ValueType::reference
474 operator()(ValueType::size_type i,
475 ValueType::size_type j,
476 ValueType::size_type k,
477 ValueType::size_type m);
478
479 ValueType::const_reference
480 operator()(ValueType::size_type i,
481 ValueType::size_type j,
482 ValueType::size_type k,
483 ValueType::size_type m) const;
484
485 /**
486 \brief
487 Determine the shape of the specified slice region.
488 This is purely a utility method and has no bearing on this view.
489
490 \param region - Input -
491 Slice region.
492 */
493 static
494 ShapeType
495 getResultSliceShape(const RegionType& region);
496
497 /**
498 \brief
499 Determine the region specified by the given python slice object.
500
501 \param key - Input -
502 python slice object specifying region to be returned.
503
504 The slice object is a tuple of n python slice specifiers, where
505 n <= the rank of this Data object. Each slice specifier specifies the
506 range of indexes to be sliced from the corresponding dimension. The
507 first specifier corresponds to the first dimension, the second to the
508 second and so on. Where n < the rank, the remaining dimensions are
509 sliced across the full range of their indicies.
510
511 Each slice specifier is of the form "a:b", which specifies a slice
512 from index a, up to but not including index b. Where index a is ommitted
513 a is assumed to be 0. Where index b is ommitted, b is assumed to be the
514 length of this dimension. Where both are ommitted (eg: ":") the slice is
515 assumed to encompass that entire dimension.
516
517 Where one of the slice specifiers is a single integer, eg: [1], we
518 want to generate a rank-1 dimension object, as opposed to eg: [1,2]
519 which implies we want to take a rank dimensional object with one
520 dimension of size 1.
521
522 The return value is a vector of pairs with length equal to the rank of
523 this object. Each pair corresponds to the range of indicies from the
524 corresponding dimension to be sliced from, as specified in the input
525 slice object.
526
527 Examples:
528
529 For a rank 1 object of shape(5):
530
531 getSliceRegion(:) => < <0,5> >
532 getSliceRegion(2:3) => < <2,3> >
533 getSliceRegion(:3) => < <0,3> >
534 getSliceRegion(2:) => < <2,5> >
535
536 For a rank 2 object of shape(4,5):
537
538 getSliceRegion(2:3) => < <2,3> <0,5> >
539 getSliceRegion(2) => < <2,3> <0,5> >
540 NB: but return object requested will have rank 1, shape(5), with
541 values taken from index 2 of this object's first dimension.
542
543 For a rank 3 object of shape (2,4,6):
544
545 getSliceRegion(0:2,0:4,0:6) => < <0,2> <0,4> <0,6> >
546 getSliceRegion(:,:,:) => < <0,2> <0,4> <0,6> >
547 getSliceRegion(0:1) => < <0,1> <0,4> <0,6> >
548 getSliceRegion(:1,0:2) => < <0,1> <0,2> <0,6> >
549
550 */
551 RegionType
552 getSliceRegion(const boost::python::object& key) const;
553
554 /**
555 \brief
556 Copy a data slice specified by the given region from the given view
557 into this view, using the default offsets in both views.
558
559 \param other - Input -
560 View to copy data from.
561 \param region - Input -
562 Region in other view to copy data from.
563 */
564 void
565 copySlice(const DataArrayView& other,
566 const RegionLoopRangeType& region);
567
568 /**
569 \brief
570 Copy a data slice specified by the given region and offset from the
571 given view into this view at the given offset.
572
573 \param thisOffset - Input -
574 Copy the slice to this offset in this view.
575 \param other - Input -
576 View to copy data from.
577 \param otherOffset - Input -
578 Copy the slice from this offset in the given view.
579 \param region - Input -
580 Region in other view to copy data from.
581 */
582 void
583 copySlice(ValueType::size_type thisOffset,
584 const DataArrayView& other,
585 ValueType::size_type otherOffset,
586 const RegionLoopRangeType& region);
587
588 /**
589 \brief
590 Copy data into a slice specified by the given region in this view from
591 the given view, using the default offsets in both views.
592
593 \param other - Input -
594 View to copy data from.
595 \param region - Input -
596 Region in this view to copy data to.
597 */
598 void
599 copySliceFrom(const DataArrayView& other,
600 const RegionLoopRangeType& region);
601
602 /**
603 \brief
604 Copy data into a slice specified by the given region and offset in
605 this view from the given view at the given offset.
606
607 \param thisOffset - Input -
608 Copy the slice to this offset in this view.
609 \param other - Input -
610 View to copy data from.
611 \param otherOffset - Input -
612 Copy the slice from this offset in the given view.
613 \param region - Input -
614 Region in this view to copy data to.
615 */
616 void
617 copySliceFrom(ValueType::size_type thisOffset,
618 const DataArrayView& other,
619 ValueType::size_type otherOffset,
620 const RegionLoopRangeType& region);
621
622 /**
623 \brief
624 Perform the unary operation on the data point specified by the view's
625 default offset. Applies the specified operation to each value in the data
626 point.
627
628 Called by escript::unaryOp.
629
630 \param operation - Input -
631 Operation to apply. Operation must be a pointer to a function.
632 */
633 template <class UnaryFunction>
634 void
635 unaryOp(UnaryFunction operation);
636
637 /**
638 \brief
639 Perform the unary operation on the data point specified by the given
640 offset. Applies the specified operation to each value in the data
641 point. Operation must be a pointer to a function.
642
643 Called by escript::unaryOp.
644
645 \param offset - Input -
646 Apply the operation to data starting at this offset in this view.
647 \param operation - Input -
648 Operation to apply. Must be a pointer to a function.
649 */
650 template <class UnaryFunction>
651 void
652 unaryOp(ValueType::size_type offset,
653 UnaryFunction operation);
654
655 /**
656 \brief
657 Perform the binary operation on the data points specified by the default
658 offsets in this view and in view "right". Applies the specified operation
659 to corresponding values in both data points. Operation must be a pointer
660 to a function.
661
662 Called by escript::binaryOp.
663
664 \param right - Input -
665 View to act as RHS in given binary operation.
666 \param operation - Input -
667 Operation to apply. Must be a pointer to a function.
668 */
669 template <class BinaryFunction>
670 void
671 binaryOp(const DataArrayView& right,
672 BinaryFunction operation);
673
674 /**
675 \brief
676 Perform the binary operation on the data points specified by the given
677 offsets in this view and in view "right". Applies the specified operation
678 to corresponding values in both data points. Operation must be a pointer
679 to a function.
680
681 Called by escript::binaryOp.
682
683 \param leftOffset - Input -
684 Apply the operation to data starting at this offset in this view.
685 \param right - Input -
686 View to act as RHS in given binary operation.
687 \param rightOffset - Input -
688 Apply the operation to data starting at this offset in right.
689 \param operation - Input -
690 Operation to apply. Must be a pointer to a function.
691 */
692 template <class BinaryFunction>
693 void
694 binaryOp(ValueType::size_type leftOffset,
695 const DataArrayView& right,
696 ValueType::size_type rightOffset,
697 BinaryFunction operation);
698
699 /**
700 \brief
701 Perform the binary operation on the data point specified by the default
702 offset in this view using the scalar value "right". Applies the specified
703 operation to values in the data point. Operation must be a pointer to
704 a function.
705
706 Called by escript::binaryOp.
707
708 \param right - Input -
709 Value to act as RHS in given binary operation.
710 \param operation - Input -
711 Operation to apply. Must be a pointer to a function.
712 */
713 template <class BinaryFunction>
714 void
715 binaryOp(double right,
716 BinaryFunction operation);
717
718 /**
719 \brief
720 Perform the binary operation on the data point specified by the given
721 offset in this view using the scalar value "right". Applies the specified
722 operation to values in the data point. Operation must be a pointer
723 to a function.
724
725 Called by escript::binaryOp.
726
727 \param offset - Input -
728 Apply the operation to data starting at this offset in this view.
729 \param right - Input -
730 Value to act as RHS in given binary operation.
731 \param operation - Input -
732 Operation to apply. Must be a pointer to a function.
733 */
734 template <class BinaryFunction>
735 void
736 binaryOp(ValueType::size_type offset,
737 double right,
738 BinaryFunction operation);
739
740 /**
741 \brief
742 Perform the given data point reduction operation on the data point
743 specified by the default offset into the view. Reduces all elements of
744 the data point using the given operation, returning the result as a
745 scalar. Operation must be a pointer to a function.
746
747 Called by escript::algorithm.
748
749 \param operation - Input -
750 Operation to apply. Must be a pointer to a function.
751 */
752 template <class BinaryFunction>
753 double
754 reductionOp(BinaryFunction operation,
755 double initial_value) const;
756
757 /**
758 \brief
759 Perform the given data point reduction operation on the data point
760 specified by the given offset into the view. Reduces all elements of
761 the data point using the given operation, returning the result as a
762 scalar. Operation must be a pointer to a function.
763
764 Called by escript::algorithm.
765
766 \param offset - Input -
767 Apply the operation to data starting at this offset in this view.
768 \param operation - Input -
769 Operation to apply. Must be a pointer to a function.
770 */
771 template <class BinaryFunction>
772 double
773 reductionOp(ValueType::size_type offset,
774 BinaryFunction operation,
775 double initial_value) const;
776
777 /**
778 \brief
779 Perform a matrix multiply of the given views.
780 This is purely a utility method and has no bearing on this view.
781
782 NB: Only multiplies together the two given views, ie: two data-points,
783 would need to call this over all data-points to multiply the entire
784 Data objects involved.
785
786 \param left - Input - The left hand side.
787 \param right - Input - The right hand side.
788 \param result - Output - The result of the operation.
789 */
790 static
791 void
792 matMult(const DataArrayView& left,
793 const DataArrayView& right,
794 DataArrayView& result);
795
796 /**
797 \brief
798 Determine the shape of the result array for a matrix multiplication
799 of the given views.
800 This is purely a utility method and has no bearing on this view.
801 */
802 static
803 ShapeType
804 determineResultShape(const DataArrayView& left,
805 const DataArrayView& right);
806
807 protected:
808
809 private:
810
811 //
812 // The maximum rank allowed for the shape of any view.
813 static const int m_maxRank=4;
814
815 //
816 // The data values for the view.
817 // NOTE: This points to data external to the view.
818 // This is just a pointer to an array of ValueType.
819 ValueType* m_data;
820
821 //
822 // The offset into the data array used by different views.
823 // This is simply an integer specifying a position in the data array
824 // pointed to by m_data.
825 ValueType::size_type m_offset;
826
827 //
828 // The shape of the data.
829 // This is simply an STL vector specifying the lengths of each dimension
830 // of the shape as ints.
831 ShapeType m_shape;
832
833 //
834 // The number of values needed for the array.
835 // This can be derived from m_shape by multiplying the size of each dimension, but
836 // is stored here for convenience.
837 int m_noValues;
838
839 };
840
841 bool operator==(const DataArrayView& left, const DataArrayView& right);
842 bool operator!=(const DataArrayView& left, const DataArrayView& right);
843
844 /**
845 \brief
846 Modify region to copy from in order to
847 deal with the case where one range in the region contains identical indexes,
848 eg: <<1,1><0,3><0,3>>
849 This situation implies we want to copy from an object with rank greater than that of this
850 object. eg: we want to copy the values from a two dimensional slice out of a three
851 dimensional object into a two dimensional object.
852 We do this by taking a slice from the other object where one dimension of
853 the slice region is of size 1. So in the above example, we modify the above
854 region like so: <<1,2><0,3><0,3>> and take this slice.
855 */
856 DataArrayView::RegionLoopRangeType
857 getSliceRegionLoopRange(const DataArrayView::RegionType& region);
858
859 /**
860 \brief
861 Calculate the slice range from the given python key object
862 Used by DataArrayView::getSliceRegion.
863 Returns the python slice object key as a pair of ints where the first
864 member is the start and the second member is the end. the presence of a possible
865 step attribute with value different from one will throw an exception
866
867 /param key - Input - key object specifying slice range.
868 */
869 std::pair<int,int>
870 getSliceRange(const boost::python::object& key,
871 const int shape);
872
873 /**
874 Inline function definitions.
875 */
876
877 template <class UnaryFunction>
878 inline
879 void
880 DataArrayView::unaryOp(UnaryFunction operation)
881 {
882 unaryOp(m_offset,operation);
883 }
884
885 template <class UnaryFunction>
886 inline
887 void
888 DataArrayView::unaryOp(ValueType::size_type offset,
889 UnaryFunction operation)
890 {
891 EsysAssert((!isEmpty()&&checkOffset(offset)),
892 "Error - Couldn't perform unaryOp due to insufficient storage.");
893 for (ValueType::size_type i=0;i<noValues();i++) {
894 (*m_data)[offset+i]=operation((*m_data)[offset+i]);
895 }
896 }
897
898 template <class BinaryFunction>
899 inline
900 void
901 DataArrayView::binaryOp(const DataArrayView& right,
902 BinaryFunction operation)
903 {
904 binaryOp(m_offset,right,right.getOffset(),operation);
905 }
906
907 template <class BinaryFunction>
908 inline
909 void
910 DataArrayView::binaryOp(ValueType::size_type leftOffset,
911 const DataArrayView& right,
912 ValueType::size_type rightOffset,
913 BinaryFunction operation)
914 {
915 EsysAssert(getShape()==right.getShape(),
916 "Error - Couldn't perform binaryOp due to shape mismatch,");
917 EsysAssert((!isEmpty()&&checkOffset(leftOffset)),
918 "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
919 EsysAssert((!right.isEmpty()&&right.checkOffset(rightOffset)),
920 "Error - Couldn't perform binaryOp due to insufficient storage in right object.");
921 for (ValueType::size_type i=0;i<noValues();i++) {
922 (*m_data)[leftOffset+i]=operation((*m_data)[leftOffset+i],(*right.m_data)[rightOffset+i]);
923 }
924 }
925
926 template <class BinaryFunction>
927 inline
928 void
929 DataArrayView::binaryOp(double right,
930 BinaryFunction operation)
931 {
932 binaryOp(m_offset,right,operation);
933 }
934
935 template <class BinaryFunction>
936 inline
937 void
938 DataArrayView::binaryOp(ValueType::size_type offset,
939 double right,
940 BinaryFunction operation)
941 {
942 EsysAssert((!isEmpty()&&checkOffset(offset)),
943 "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
944 for (ValueType::size_type i=0;i<noValues();i++) {
945 (*m_data)[offset+i]=operation((*m_data)[offset+i],right);
946 }
947 }
948
949 template <class BinaryFunction>
950 inline
951 double
952 DataArrayView::reductionOp(BinaryFunction operation,
953 double initial_value) const
954 {
955 return reductionOp(m_offset,operation,initial_value);
956 }
957
958 template <class BinaryFunction>
959 inline
960 double
961 DataArrayView::reductionOp(ValueType::size_type offset,
962 BinaryFunction operation,
963 double initial_value) const
964 {
965 EsysAssert((!isEmpty()&&checkOffset(offset)),
966 "Error - Couldn't perform reductionOp due to insufficient storage.");
967 double current_value=initial_value;
968 for (ValueType::size_type i=0;i<noValues();i++) {
969 current_value=operation(current_value,(*m_data)[offset+i]);
970 }
971 return current_value;
972 }
973
974 inline
975 DataArrayView::ValueType::size_type
976 DataArrayView::relIndex() const
977 {
978 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
979 return 0;
980 }
981
982 inline
983 DataArrayView::ValueType::size_type
984 DataArrayView::index() const
985 {
986 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
987 return (m_offset);
988 }
989
990 inline
991 DataArrayView::ValueType::size_type
992 DataArrayView::relIndex(ValueType::size_type i) const
993 {
994 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
995 EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
996 return i;
997 }
998
999 inline
1000 DataArrayView::ValueType::size_type
1001 DataArrayView::index(ValueType::size_type i) const
1002 {
1003 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
1004 EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
1005 return (m_offset+i);
1006 }
1007
1008 inline
1009 DataArrayView::ValueType::size_type
1010 DataArrayView::relIndex(ValueType::size_type i,
1011 ValueType::size_type j) const
1012 {
1013 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1014 ValueType::size_type temp=i+j*m_shape[0];
1015 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1016 return temp;
1017 }
1018
1019 inline
1020 DataArrayView::ValueType::size_type
1021 DataArrayView::index(ValueType::size_type i,
1022 ValueType::size_type j) const
1023 {
1024 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1025 ValueType::size_type temp=i+j*m_shape[0];
1026 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1027 return (m_offset+temp);
1028 }
1029
1030 inline
1031 DataArrayView::ValueType::size_type
1032 DataArrayView::relIndex(ValueType::size_type i,
1033 ValueType::size_type j,
1034 ValueType::size_type k) const
1035 {
1036 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1037 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1038 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1039 return temp;
1040 }
1041
1042 inline
1043 DataArrayView::ValueType::size_type
1044 DataArrayView::index(ValueType::size_type i,
1045 ValueType::size_type j,
1046 ValueType::size_type k) const
1047 {
1048 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1049 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1050 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1051 return (m_offset+temp);
1052 }
1053
1054 inline
1055 DataArrayView::ValueType::size_type
1056 DataArrayView::relIndex(ValueType::size_type i,
1057 ValueType::size_type j,
1058 ValueType::size_type k,
1059 ValueType::size_type m) const
1060 {
1061 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1062 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];
1063 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1064 return temp;
1065 }
1066
1067 inline
1068 DataArrayView::ValueType::size_type
1069 DataArrayView::index(ValueType::size_type i,
1070 ValueType::size_type j,
1071 ValueType::size_type k,
1072 ValueType::size_type m) const
1073 {
1074 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1075 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];
1076 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1077 return (m_offset+temp);
1078 }
1079
1080 inline
1081 DataArrayView::ValueType::reference
1082 DataArrayView::operator()()
1083 {
1084 return (*m_data)[index()];
1085 }
1086
1087 inline
1088 DataArrayView::ValueType::const_reference
1089 DataArrayView::operator()() const
1090 {
1091 return (*m_data)[index()];
1092 }
1093
1094 inline
1095 DataArrayView::ValueType::reference
1096 DataArrayView::operator()(ValueType::size_type i)
1097 {
1098 return (*m_data)[index(i)];
1099 }
1100
1101 inline
1102 DataArrayView::ValueType::const_reference
1103 DataArrayView::operator()(ValueType::size_type i) const
1104 {
1105 return (*m_data)[index(i)];
1106 }
1107
1108 inline
1109 DataArrayView::ValueType::reference
1110 DataArrayView::operator()(ValueType::size_type i,
1111 ValueType::size_type j)
1112 {
1113 return (*m_data)[index(i,j)];
1114 }
1115
1116 inline
1117 DataArrayView::ValueType::const_reference
1118 DataArrayView::operator()(ValueType::size_type i,
1119 ValueType::size_type j) const
1120 {
1121 return (*m_data)[index(i,j)];
1122 }
1123
1124 inline
1125 DataArrayView::ValueType::reference
1126 DataArrayView::operator()(ValueType::size_type i,
1127 ValueType::size_type j,
1128 ValueType::size_type k)
1129 {
1130 return (*m_data)[index(i,j,k)];
1131 }
1132
1133 inline
1134 DataArrayView::ValueType::const_reference
1135 DataArrayView::operator()(ValueType::size_type i,
1136 ValueType::size_type j,
1137 ValueType::size_type k) const
1138 {
1139 return (*m_data)[index(i,j,k)];
1140 }
1141
1142 inline
1143 DataArrayView::ValueType::reference
1144 DataArrayView::operator()(ValueType::size_type i,
1145 ValueType::size_type j,
1146 ValueType::size_type k,
1147 ValueType::size_type m)
1148 {
1149 return (*m_data)[index(i,j,k,m)];
1150 }
1151
1152 inline
1153 DataArrayView::ValueType::const_reference
1154 DataArrayView::operator()(ValueType::size_type i,
1155 ValueType::size_type j,
1156 ValueType::size_type k,
1157 ValueType::size_type m) const
1158 {
1159 return (*m_data)[index(i,j,k,m)];
1160 }
1161
1162 } // end of namespace
1163
1164 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26