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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26