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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 117 - (show annotations)
Fri Apr 1 05:48:57 2005 UTC (14 years, 8 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/DataArrayView.h
File MIME type: text/plain
File size: 34432 byte(s)
*** empty log message ***

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 "esysUtils/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 \description
501
502 The slice object is a tuple of n python slice specifiers, where
503 n <= the rank of this Data object. Each slice specifier specifies the
504 range of indexes to be sliced from the corresponding dimension. The
505 first specifier corresponds to the first dimension, the second to the
506 second and so on. Where n < the rank, the remaining dimensions are
507 sliced across the full range of their indicies.
508
509 Each slice specifier is of the form "a:b", which specifies a slice
510 from index a, up to but not including index b. Where index a is ommitted
511 a is assumed to be 0. Where index b is ommitted, b is assumed to be the
512 length of this dimension. Where both are ommitted (eg: ":") the slice is
513 assumed to encompass that entire dimension.
514
515 Where one of the slice specifiers is a single integer, eg: [1], we
516 want to generate a rank-1 dimension object, as opposed to eg: [1,2]
517 which implies we want to take a rank dimensional object with one
518 dimension of size 1.
519
520 The return value is a vector of pairs with length equal to the rank of
521 this object. Each pair corresponds to the range of indicies from the
522 corresponding dimension to be sliced from, as specified in the input
523 slice object.
524
525 Examples:
526
527 For a rank 1 object of shape(5):
528
529 getSliceRegion(:) => < <0,5> >
530 getSliceRegion(2:3) => < <2,3> >
531 getSliceRegion(:3) => < <0,3> >
532 getSliceRegion(2:) => < <2,5> >
533
534 For a rank 2 object of shape(4,5):
535
536 getSliceRegion(2:3) => < <2,3> <0,5> >
537 getSliceRegion(2) => < <2,3> <0,5> >
538 NB: but return object requested will have rank 1, shape(5), with
539 values taken from index 2 of this object's first dimension.
540
541 For a rank 3 object of shape (2,4,6):
542
543 getSliceRegion(0:2,0:4,0:6) => < <0,2> <0,4> <0,6> >
544 getSliceRegion(:,:,:) => < <0,2> <0,4> <0,6> >
545 getSliceRegion(0:1) => < <0,1> <0,4> <0,6> >
546 getSliceRegion(:1,0:2) => < <0,1> <0,2> <0,6> >
547
548 */
549 RegionType
550 getSliceRegion(const boost::python::object& key) const;
551
552 /**
553 \brief
554 Copy a data slice specified by the given region from the given view
555 into this view, using the default offsets in both views.
556
557 \param other - Input -
558 View to copy data from.
559 \param region - Input -
560 Region in other view to copy data from.
561 */
562 void
563 copySlice(const DataArrayView& other,
564 const RegionLoopRangeType& region);
565
566 /**
567 \brief
568 Copy a data slice specified by the given region and offset from the
569 given view into this view at the given offset.
570
571 \param thisOffset - Input -
572 Copy the slice to this offset in this view.
573 \param other - Input -
574 View to copy data from.
575 \param otherOffset - Input -
576 Copy the slice from this offset in the given view.
577 \param region - Input -
578 Region in other view to copy data from.
579 */
580 void
581 copySlice(ValueType::size_type thisOffset,
582 const DataArrayView& other,
583 ValueType::size_type otherOffset,
584 const RegionLoopRangeType& region);
585
586 /**
587 \brief
588 Copy data into a slice specified by the given region in this view from
589 the given view, using the default offsets in both views.
590
591 \param other - Input -
592 View to copy data from.
593 \param region - Input -
594 Region in this view to copy data to.
595 */
596 void
597 copySliceFrom(const DataArrayView& other,
598 const RegionLoopRangeType& region);
599
600 /**
601 \brief
602 Copy data into a slice specified by the given region and offset in
603 this view from the given view at the given offset.
604
605 \param thisOffset - Input -
606 Copy the slice to this offset in this view.
607 \param other - Input -
608 View to copy data from.
609 \param otherOffset - Input -
610 Copy the slice from this offset in the given view.
611 \param region - Input -
612 Region in this view to copy data to.
613 */
614 void
615 copySliceFrom(ValueType::size_type thisOffset,
616 const DataArrayView& other,
617 ValueType::size_type otherOffset,
618 const RegionLoopRangeType& region);
619
620 /**
621 \brief
622 Perform the unary operation on the data point specified by the view's
623 default offset. Applies the specified operation to each value in the data
624 point.
625
626 Called by escript::unaryOp.
627
628 \param operation - Input -
629 Operation to apply. Operation must be a pointer to a function.
630 */
631 template <class UnaryFunction>
632 void
633 unaryOp(UnaryFunction operation);
634
635 /**
636 \brief
637 Perform the unary operation on the data point specified by the given
638 offset. Applies the specified operation to each value in the data
639 point. Operation must be a pointer to a function.
640
641 Called by escript::unaryOp.
642
643 \param offset - Input -
644 Apply the operation to data starting at this offset in this view.
645 \param operation - Input -
646 Operation to apply. Must be a pointer to a function.
647 */
648 template <class UnaryFunction>
649 void
650 unaryOp(ValueType::size_type offset,
651 UnaryFunction operation);
652
653 /**
654 \brief
655 Perform the binary operation on the data points specified by the default
656 offsets in this view and in view "right". Applies the specified operation
657 to corresponding values in both data points. Operation must be a pointer
658 to a function.
659
660 Called by escript::binaryOp.
661
662 \param right - Input -
663 View to act as RHS in given binary operation.
664 \param operation - Input -
665 Operation to apply. Must be a pointer to a function.
666 */
667 template <class BinaryFunction>
668 void
669 binaryOp(const DataArrayView& right,
670 BinaryFunction operation);
671
672 /**
673 \brief
674 Perform the binary operation on the data points specified by the given
675 offsets in this view and in view "right". Applies the specified operation
676 to corresponding values in both data points. Operation must be a pointer
677 to a function.
678
679 Called by escript::binaryOp.
680
681 \param leftOffset - Input -
682 Apply the operation to data starting at this offset in this view.
683 \param right - Input -
684 View to act as RHS in given binary operation.
685 \param rightOffset - Input -
686 Apply the operation to data starting at this offset in right.
687 \param operation - Input -
688 Operation to apply. Must be a pointer to a function.
689 */
690 template <class BinaryFunction>
691 void
692 binaryOp(ValueType::size_type leftOffset,
693 const DataArrayView& right,
694 ValueType::size_type rightOffset,
695 BinaryFunction operation);
696
697 /**
698 \brief
699 Perform the binary operation on the data point specified by the default
700 offset in this view using the scalar value "right". Applies the specified
701 operation to values in the data point. Operation must be a pointer to
702 a function.
703
704 Called by escript::binaryOp.
705
706 \param right - Input -
707 Value to act as RHS in given binary operation.
708 \param operation - Input -
709 Operation to apply. Must be a pointer to a function.
710 */
711 template <class BinaryFunction>
712 void
713 binaryOp(double right,
714 BinaryFunction operation);
715
716 /**
717 \brief
718 Perform the binary operation on the data point specified by the given
719 offset in this view using the scalar value "right". Applies the specified
720 operation to values in the data point. Operation must be a pointer
721 to a function.
722
723 Called by escript::binaryOp.
724
725 \param offset - Input -
726 Apply the operation to data starting at this offset in this view.
727 \param right - Input -
728 Value to act as RHS in given binary operation.
729 \param operation - Input -
730 Operation to apply. Must be a pointer to a function.
731 */
732 template <class BinaryFunction>
733 void
734 binaryOp(ValueType::size_type offset,
735 double right,
736 BinaryFunction operation);
737
738 /**
739 \brief
740 Perform the given data point reduction operation on the data point
741 specified by the default offset into the view. Reduces all elements of
742 the data point using the given operation, returning the result as a
743 scalar. Operation must be a pointer to a function.
744
745 Called by escript::algorithm.
746
747 \param operation - Input -
748 Operation to apply. Must be a pointer to a function.
749 */
750 template <class UnaryFunction>
751 double
752 reductionOp(UnaryFunction operation) const;
753
754 /**
755 \brief
756 Perform the given data point reduction operation on the data point
757 specified by the given offset into the view. Reduces all elements of
758 the data point using the given operation, returning the result as a
759 scalar. Operation must be a pointer to a function.
760
761 Called by escript::algorithm.
762
763 \param offset - Input -
764 Apply the operation to data starting at this offset in this view.
765 \param operation - Input -
766 Operation to apply. Must be a pointer to a function.
767 */
768 template <class UnaryFunction>
769 double
770 reductionOp(ValueType::size_type offset,
771 UnaryFunction operation) 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 \param left - Input - The left hand side.
779 \param right - Input - The right hand side.
780 \param result - Output - The result of the operation.
781 */
782 static
783 void
784 matMult(const DataArrayView& left,
785 const DataArrayView& right,
786 DataArrayView& result);
787
788 /**
789 \brief
790 Determine the shape of the result array for a matrix multiplication
791 of the given views.
792 This is purely a utility method and has no bearing on this view.
793 */
794 static
795 ShapeType
796 determineResultShape(const DataArrayView& left,
797 const DataArrayView& right);
798
799 protected:
800
801 private:
802
803 //
804 // The maximum rank allowed for the shape of any view.
805 static const int m_maxRank=4;
806
807 //
808 // The data values for the view.
809 // NOTE: This points to data external to the view.
810 // This is just a pointer to an array of ValueType.
811 ValueType* m_data;
812
813 //
814 // The offset into the data array used by different views.
815 // This is simply an integer specifying a position in the data array
816 // pointed to by m_data.
817 ValueType::size_type m_offset;
818
819 //
820 // The shape of the data.
821 // This is simply an STL vector specifying the lengths of each dimension
822 // of the shape as ints.
823 ShapeType m_shape;
824
825 //
826 // The number of values needed for the array.
827 // This can be derived from m_shape by multiplying the size of each dimension, but
828 // is stored here for convenience.
829 int m_noValues;
830
831 };
832
833 bool operator==(const DataArrayView& left, const DataArrayView& right);
834 bool operator!=(const DataArrayView& left, const DataArrayView& right);
835
836 /**
837 \brief
838 Modify region to copy from in order to
839 deal with the case where one range in the region contains identical indexes,
840 eg: <<1,1><0,3><0,3>>
841 This situation implies we want to copy from an object with rank greater than that of this
842 object. eg: we want to copy the values from a two dimensional slice out of a three
843 dimensional object into a two dimensional object.
844 We do this by taking a slice from the other object where one dimension of
845 the slice region is of size 1. So in the above example, we modify the above
846 region like so: <<1,2><0,3><0,3>> and take this slice.
847 */
848 DataArrayView::RegionLoopRangeType
849 getSliceRegionLoopRange(const DataArrayView::RegionType& region);
850
851 /**
852 \brief
853 Calculate the slice range from the given python key object
854 Used by DataArrayView::getSliceRegion.
855 Returns the python slice object key as a pair of ints where the first
856 member is the start and the second member is the end. the presence of a possible
857 step attribute with value different from one will throw an exception
858
859 /param key - Input - key object specifying slice range.
860 */
861 std::pair<int,int>
862 getSliceRange(const boost::python::object& key,
863 const int shape);
864
865 /**
866 Inline function definitions.
867 */
868
869 template <class UnaryFunction>
870 inline
871 void
872 DataArrayView::unaryOp(UnaryFunction operation)
873 {
874 unaryOp(m_offset,operation);
875 }
876
877 template <class UnaryFunction>
878 inline
879 void
880 DataArrayView::unaryOp(ValueType::size_type offset,
881 UnaryFunction operation)
882 {
883 EsysAssert((!isEmpty()&&checkOffset(offset)),
884 "Error - Couldn't perform unaryOp due to insufficient storage.");
885 for (ValueType::size_type i=0;i<noValues();i++) {
886 (*m_data)[offset+i]=operation((*m_data)[offset+i]);
887 }
888 }
889
890 template <class BinaryFunction>
891 inline
892 void
893 DataArrayView::binaryOp(const DataArrayView& right,
894 BinaryFunction operation)
895 {
896 binaryOp(m_offset,right,right.getOffset(),operation);
897 }
898
899 template <class BinaryFunction>
900 inline
901 void
902 DataArrayView::binaryOp(ValueType::size_type leftOffset,
903 const DataArrayView& right,
904 ValueType::size_type rightOffset,
905 BinaryFunction operation)
906 {
907 EsysAssert(getShape()==right.getShape(),
908 "Error - Couldn't perform binaryOp due to shape mismatch,");
909 EsysAssert((!isEmpty()&&checkOffset(leftOffset)),
910 "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
911 EsysAssert((!right.isEmpty()&&right.checkOffset(rightOffset)),
912 "Error - Couldn't perform binaryOp due to insufficient storage in right object.");
913 for (ValueType::size_type i=0;i<noValues();i++) {
914 (*m_data)[leftOffset+i]=operation((*m_data)[leftOffset+i],(*right.m_data)[rightOffset+i]);
915 }
916 }
917
918 template <class BinaryFunction>
919 inline
920 void
921 DataArrayView::binaryOp(double right,
922 BinaryFunction operation)
923 {
924 binaryOp(m_offset,right,operation);
925 }
926
927 template <class BinaryFunction>
928 inline
929 void
930 DataArrayView::binaryOp(ValueType::size_type offset,
931 double right,
932 BinaryFunction operation)
933 {
934 EsysAssert((!isEmpty()&&checkOffset(offset)),
935 "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
936 for (ValueType::size_type i=0;i<noValues();i++) {
937 (*m_data)[offset+i]=operation((*m_data)[offset+i],right);
938 }
939 }
940
941 template <class UnaryFunction>
942 inline
943 double
944 DataArrayView::reductionOp(UnaryFunction operation) const
945 {
946 return reductionOp(m_offset,operation);
947 }
948
949 template <class UnaryFunction>
950 inline
951 double
952 DataArrayView::reductionOp(ValueType::size_type offset,
953 UnaryFunction operation) const
954 {
955 EsysAssert((!isEmpty()&&checkOffset(offset)),
956 "Error - Couldn't perform reductionOp due to insufficient storage.");
957 operation.resetResult();
958 for (ValueType::size_type i=0;i<noValues();i++) {
959 operation((*m_data)[offset+i]);
960 }
961 return operation.getResult();
962 }
963
964 inline
965 DataArrayView::ValueType::size_type
966 DataArrayView::relIndex() const
967 {
968 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
969 return 0;
970 }
971
972 inline
973 DataArrayView::ValueType::size_type
974 DataArrayView::index() const
975 {
976 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
977 return (m_offset);
978 }
979
980 inline
981 DataArrayView::ValueType::size_type
982 DataArrayView::relIndex(ValueType::size_type i) const
983 {
984 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
985 EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
986 return i;
987 }
988
989 inline
990 DataArrayView::ValueType::size_type
991 DataArrayView::index(ValueType::size_type i) const
992 {
993 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
994 EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
995 return (m_offset+i);
996 }
997
998 inline
999 DataArrayView::ValueType::size_type
1000 DataArrayView::relIndex(ValueType::size_type i,
1001 ValueType::size_type j) const
1002 {
1003 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1004 ValueType::size_type temp=i+j*m_shape[0];
1005 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1006 return temp;
1007 }
1008
1009 inline
1010 DataArrayView::ValueType::size_type
1011 DataArrayView::index(ValueType::size_type i,
1012 ValueType::size_type j) const
1013 {
1014 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1015 ValueType::size_type temp=i+j*m_shape[0];
1016 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1017 return (m_offset+temp);
1018 }
1019
1020 inline
1021 DataArrayView::ValueType::size_type
1022 DataArrayView::relIndex(ValueType::size_type i,
1023 ValueType::size_type j,
1024 ValueType::size_type k) const
1025 {
1026 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1027 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1028 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1029 return temp;
1030 }
1031
1032 inline
1033 DataArrayView::ValueType::size_type
1034 DataArrayView::index(ValueType::size_type i,
1035 ValueType::size_type j,
1036 ValueType::size_type k) const
1037 {
1038 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1039 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1040 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1041 return (m_offset+temp);
1042 }
1043
1044 inline
1045 DataArrayView::ValueType::size_type
1046 DataArrayView::relIndex(ValueType::size_type i,
1047 ValueType::size_type j,
1048 ValueType::size_type k,
1049 ValueType::size_type m) const
1050 {
1051 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1052 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];
1053 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1054 return temp;
1055 }
1056
1057 inline
1058 DataArrayView::ValueType::size_type
1059 DataArrayView::index(ValueType::size_type i,
1060 ValueType::size_type j,
1061 ValueType::size_type k,
1062 ValueType::size_type m) const
1063 {
1064 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1065 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];
1066 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1067 return (m_offset+temp);
1068 }
1069
1070 inline
1071 DataArrayView::ValueType::reference
1072 DataArrayView::operator()()
1073 {
1074 return (*m_data)[index()];
1075 }
1076
1077 inline
1078 DataArrayView::ValueType::const_reference
1079 DataArrayView::operator()() const
1080 {
1081 return (*m_data)[index()];
1082 }
1083
1084 inline
1085 DataArrayView::ValueType::reference
1086 DataArrayView::operator()(ValueType::size_type i)
1087 {
1088 return (*m_data)[index(i)];
1089 }
1090
1091 inline
1092 DataArrayView::ValueType::const_reference
1093 DataArrayView::operator()(ValueType::size_type i) const
1094 {
1095 return (*m_data)[index(i)];
1096 }
1097
1098 inline
1099 DataArrayView::ValueType::reference
1100 DataArrayView::operator()(ValueType::size_type i,
1101 ValueType::size_type j)
1102 {
1103 return (*m_data)[index(i,j)];
1104 }
1105
1106 inline
1107 DataArrayView::ValueType::const_reference
1108 DataArrayView::operator()(ValueType::size_type i,
1109 ValueType::size_type j) const
1110 {
1111 return (*m_data)[index(i,j)];
1112 }
1113
1114 inline
1115 DataArrayView::ValueType::reference
1116 DataArrayView::operator()(ValueType::size_type i,
1117 ValueType::size_type j,
1118 ValueType::size_type k)
1119 {
1120 return (*m_data)[index(i,j,k)];
1121 }
1122
1123 inline
1124 DataArrayView::ValueType::const_reference
1125 DataArrayView::operator()(ValueType::size_type i,
1126 ValueType::size_type j,
1127 ValueType::size_type k) const
1128 {
1129 return (*m_data)[index(i,j,k)];
1130 }
1131
1132 inline
1133 DataArrayView::ValueType::reference
1134 DataArrayView::operator()(ValueType::size_type i,
1135 ValueType::size_type j,
1136 ValueType::size_type k,
1137 ValueType::size_type m)
1138 {
1139 return (*m_data)[index(i,j,k,m)];
1140 }
1141
1142 inline
1143 DataArrayView::ValueType::const_reference
1144 DataArrayView::operator()(ValueType::size_type i,
1145 ValueType::size_type j,
1146 ValueType::size_type k,
1147 ValueType::size_type m) const
1148 {
1149 return (*m_data)[index(i,j,k,m)];
1150 }
1151
1152 } // end of namespace
1153
1154 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26