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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26