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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 478 - (show annotations)
Tue Jan 31 02:21:49 2006 UTC (13 years, 6 months ago) by jgs
File MIME type: text/plain
File size: 34664 byte(s)
rationalise #includes

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26