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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 108 - (show annotations)
Thu Jan 27 06:21:59 2005 UTC (15 years ago) by jgs
Original Path: trunk/esys2/escript/src/Data/DataArrayView.h
File MIME type: text/plain
File size: 36099 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::dp_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 dp_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::dp_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 dp_reductionOp(ValueType::size_type offset,
762 UnaryFunction operation) const;
763
764 /**
765 \brief
766 Perform the given reduction operation on the data point
767 specified by the default offset into the view. Reduces all elements of
768 the data point using the given operation, returning the result as a
769 scalar. Operation must be a pointer to a function.
770
771 Called by escript::algorithm.
772
773 \param operation - Input -
774 Operation to apply. Must be a pointer to a function.
775 */
776 template <class UnaryFunction>
777 double
778 reductionOp(UnaryFunction operation) const;
779
780 /**
781 \brief
782 Perform the given reduction operation on the data point
783 specified by the given offset into the view. Reduces all elements of
784 the data point using the given operation, returning the result as a
785 scalar. Operation must be a pointer to a function.
786
787 Called by escript::algorithm.
788
789 \param offset - Input -
790 Apply the operation to data starting at this offset in this view.
791 \param operation - Input -
792 Operation to apply. Must be a pointer to a function.
793 */
794 template <class UnaryFunction>
795 double
796 reductionOp(ValueType::size_type offset,
797 UnaryFunction operation) const;
798
799 /**
800 \brief
801 Perform matrix multiply.
802
803 Description:
804 Perform matrix multiply.
805
806 \param left - Input - The left hand side.
807 \param right - Input - The right hand side.
808 \param result - Output - The result of the operation.
809 */
810 static void
811 matMult(const DataArrayView& left,
812 const DataArrayView& right,
813 DataArrayView& result);
814
815 /**
816 \brief
817 Determine the shape of the result array for a matrix multiplication
818 of the given views.
819 This is purely a utility method and has no bearing on this view.
820 */
821 static ShapeType
822 determineResultShape(const DataArrayView& left,
823 const DataArrayView& right);
824
825 protected:
826
827 private:
828
829 //
830 // The maximum rank allowed for the shape of any view.
831 static const int m_maxRank=4;
832
833 //
834 // The data values for the view.
835 // NOTE: This points to data external to the view.
836 // This is just a pointer to a simple STL vector of doubles.
837 ValueType* m_data;
838
839 //
840 // The offset into the data array used by different views.
841 // This is simply an integer specifying a position in the data array
842 // pointed to by m_data.
843 ValueType::size_type m_offset;
844
845 //
846 // The shape of the data.
847 // This is simply an STL vector specifying the lengths of each dimension
848 // of the shape as ints.
849 ShapeType m_shape;
850
851 //
852 // The number of values needed for the array.
853 // This can be derived from m_shape by multiplying the size of each dimension, but
854 // is stored here for convenience.
855 int m_noValues;
856
857 };
858
859 bool operator==(const DataArrayView& left, const DataArrayView& right);
860 bool operator!=(const DataArrayView& left, const DataArrayView& right);
861
862 /**
863 \brief
864 Modify region to copy from in order to
865 deal with the case where one range in the region contains identical indexes,
866 eg: <<1,1><0,3><0,3>>
867 This situation implies we want to copy from an object with rank greater than that of this
868 object. eg: we want to copy the values from a two dimensional slice out of a three
869 dimensional object into a two dimensional object.
870 We do this by taking a slice from the other object where one dimension of
871 the slice region is of size 1. So in the above example, we modify the above
872 region like so: <<1,2><0,3><0,3>> and take this slice.
873 */
874 DataArrayView::RegionLoopRangeType
875 getSliceRegionLoopRange(const DataArrayView::RegionType& region);
876
877 /**
878 \brief
879 Calculate the slice range from the given python key object
880 Used by DataArrayView::getSliceRegion.
881 Returns the python slice object key as a pair of ints where the first
882 member is the start and the second member is the end. the presence of a possible
883 step attribute with value different from one will throw an exception
884
885 /param key - Input - key object specifying slice range.
886 */
887 std::pair<int,int>
888 getSliceRange(const boost::python::object& key,
889 const int shape);
890
891 /**
892 Inline function definitions.
893 */
894
895 template <class UnaryFunction>
896 inline
897 void
898 DataArrayView::unaryOp(UnaryFunction operation)
899 {
900 unaryOp(m_offset,operation);
901 }
902
903 template <class UnaryFunction>
904 inline
905 void
906 DataArrayView::unaryOp(ValueType::size_type offset,
907 UnaryFunction operation)
908 {
909 EsysAssert((!isEmpty()&&checkOffset(offset)),
910 "Error - Couldn't perform unaryOp due to insufficient storage.");
911 for (ValueType::size_type i=0;i<noValues();i++) {
912 (*m_data)[offset+i]=operation((*m_data)[offset+i]);
913 }
914 }
915
916 template <class BinaryFunction>
917 inline
918 void
919 DataArrayView::binaryOp(const DataArrayView& right,
920 BinaryFunction operation)
921 {
922 binaryOp(m_offset,right,right.getOffset(),operation);
923 }
924
925 template <class BinaryFunction>
926 inline
927 void
928 DataArrayView::binaryOp(ValueType::size_type leftOffset,
929 const DataArrayView& right,
930 ValueType::size_type rightOffset,
931 BinaryFunction operation)
932 {
933 EsysAssert(getShape()==right.getShape(),
934 "Error - Couldn't perform binaryOp due to shape mismatch,");
935 EsysAssert((!isEmpty()&&checkOffset(leftOffset)),
936 "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
937 EsysAssert((!right.isEmpty()&&right.checkOffset(rightOffset)),
938 "Error - Couldn't perform binaryOp due to insufficient storage in right object.");
939 for (ValueType::size_type i=0;i<noValues();i++) {
940 (*m_data)[leftOffset+i]=operation((*m_data)[leftOffset+i],(*right.m_data)[rightOffset+i]);
941 }
942 }
943
944 template <class BinaryFunction>
945 inline
946 void
947 DataArrayView::binaryOp(double right,
948 BinaryFunction operation)
949 {
950 binaryOp(m_offset,right,operation);
951 }
952
953 template <class BinaryFunction>
954 inline
955 void
956 DataArrayView::binaryOp(ValueType::size_type offset,
957 double right,
958 BinaryFunction operation)
959 {
960 EsysAssert((!isEmpty()&&checkOffset(offset)),
961 "Error - Couldn't perform binaryOp due to insufficient storage.");
962 for (ValueType::size_type i=0;i<noValues();i++) {
963 (*m_data)[offset+i]=operation((*m_data)[offset+i],right);
964 }
965 }
966
967 template <class UnaryFunction>
968 inline
969 double
970 DataArrayView::dp_reductionOp(UnaryFunction operation) const
971 {
972 return dp_reductionOp(m_offset,operation);
973 }
974
975 template <class UnaryFunction>
976 inline
977 double
978 DataArrayView::dp_reductionOp(ValueType::size_type offset,
979 UnaryFunction operation) const
980 {
981 EsysAssert((!isEmpty()&&checkOffset(offset)),
982 "Error - Couldn't perform dp_reductionOp due to insufficient storage.");
983 operation.resetResult();
984 for (ValueType::size_type i=0;i<noValues();i++) {
985 operation((*m_data)[offset+i]);
986 }
987 return operation.getResult();
988 }
989
990 template <class UnaryFunction>
991 inline
992 double
993 DataArrayView::reductionOp(UnaryFunction operation) const
994 {
995 return reductionOp(m_offset,operation);
996 }
997
998 template <class UnaryFunction>
999 inline
1000 double
1001 DataArrayView::reductionOp(ValueType::size_type offset,
1002 UnaryFunction operation) const
1003 {
1004 EsysAssert((!isEmpty()&&checkOffset(offset)),
1005 "Error - Couldn't perform reductionOp due to insufficient storage.");
1006 for (ValueType::size_type i=0;i<noValues();i++) {
1007 operation((*m_data)[offset+i]);
1008 }
1009 return operation.getResult();
1010 }
1011
1012 inline
1013 DataArrayView::ValueType::size_type
1014 DataArrayView::relIndex() const
1015 {
1016 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
1017 return 0;
1018 }
1019
1020 inline
1021 DataArrayView::ValueType::size_type
1022 DataArrayView::index() const
1023 {
1024 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
1025 return (m_offset);
1026 }
1027
1028 inline
1029 DataArrayView::ValueType::size_type
1030 DataArrayView::relIndex(ValueType::size_type i) const
1031 {
1032 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
1033 EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
1034 return i;
1035 }
1036
1037 inline
1038 DataArrayView::ValueType::size_type
1039 DataArrayView::index(ValueType::size_type i) const
1040 {
1041 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
1042 EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
1043 return (m_offset+i);
1044 }
1045
1046 inline
1047 DataArrayView::ValueType::size_type
1048 DataArrayView::relIndex(ValueType::size_type i,
1049 ValueType::size_type j) const
1050 {
1051 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1052 ValueType::size_type temp=i+j*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) const
1061 {
1062 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1063 ValueType::size_type temp=i+j*m_shape[0];
1064 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1065 return (m_offset+temp);
1066 }
1067
1068 inline
1069 DataArrayView::ValueType::size_type
1070 DataArrayView::relIndex(ValueType::size_type i,
1071 ValueType::size_type j,
1072 ValueType::size_type k) const
1073 {
1074 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1075 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1076 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1077 return temp;
1078 }
1079
1080 inline
1081 DataArrayView::ValueType::size_type
1082 DataArrayView::index(ValueType::size_type i,
1083 ValueType::size_type j,
1084 ValueType::size_type k) const
1085 {
1086 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1087 ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1088 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1089 return (m_offset+temp);
1090 }
1091
1092 inline
1093 DataArrayView::ValueType::size_type
1094 DataArrayView::relIndex(ValueType::size_type i,
1095 ValueType::size_type j,
1096 ValueType::size_type k,
1097 ValueType::size_type m) const
1098 {
1099 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1100 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];
1101 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1102 return temp;
1103 }
1104
1105 inline
1106 DataArrayView::ValueType::size_type
1107 DataArrayView::index(ValueType::size_type i,
1108 ValueType::size_type j,
1109 ValueType::size_type k,
1110 ValueType::size_type m) const
1111 {
1112 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1113 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];
1114 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1115 return (m_offset+temp);
1116 }
1117
1118 inline
1119 DataArrayView::ValueType::reference
1120 DataArrayView::operator()()
1121 {
1122 return (*m_data)[index()];
1123 }
1124
1125 inline
1126 DataArrayView::ValueType::const_reference
1127 DataArrayView::operator()() const
1128 {
1129 return (*m_data)[index()];
1130 }
1131
1132 inline
1133 DataArrayView::ValueType::reference
1134 DataArrayView::operator()(ValueType::size_type i)
1135 {
1136 return (*m_data)[index(i)];
1137 }
1138
1139 inline
1140 DataArrayView::ValueType::const_reference
1141 DataArrayView::operator()(ValueType::size_type i) const
1142 {
1143 return (*m_data)[index(i)];
1144 }
1145
1146 inline
1147 DataArrayView::ValueType::reference
1148 DataArrayView::operator()(ValueType::size_type i,
1149 ValueType::size_type j)
1150 {
1151 return (*m_data)[index(i,j)];
1152 }
1153
1154 inline
1155 DataArrayView::ValueType::const_reference
1156 DataArrayView::operator()(ValueType::size_type i,
1157 ValueType::size_type j) const
1158 {
1159 return (*m_data)[index(i,j)];
1160 }
1161
1162 inline
1163 DataArrayView::ValueType::reference
1164 DataArrayView::operator()(ValueType::size_type i,
1165 ValueType::size_type j,
1166 ValueType::size_type k)
1167 {
1168 return (*m_data)[index(i,j,k)];
1169 }
1170
1171 inline
1172 DataArrayView::ValueType::const_reference
1173 DataArrayView::operator()(ValueType::size_type i,
1174 ValueType::size_type j,
1175 ValueType::size_type k) const
1176 {
1177 return (*m_data)[index(i,j,k)];
1178 }
1179
1180 inline
1181 DataArrayView::ValueType::reference
1182 DataArrayView::operator()(ValueType::size_type i,
1183 ValueType::size_type j,
1184 ValueType::size_type k,
1185 ValueType::size_type m)
1186 {
1187 return (*m_data)[index(i,j,k,m)];
1188 }
1189
1190 inline
1191 DataArrayView::ValueType::const_reference
1192 DataArrayView::operator()(ValueType::size_type i,
1193 ValueType::size_type j,
1194 ValueType::size_type k,
1195 ValueType::size_type m) const
1196 {
1197 return (*m_data)[index(i,j,k,m)];
1198 }
1199
1200 } // end of namespace
1201
1202 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26