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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 108 - (hide annotations)
Thu Jan 27 06:21:59 2005 UTC (15 years, 1 month 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 jgs 102 // $Id$
2 jgs 108
3 jgs 82 /*
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 jgs 102 #include <iostream>
27 jgs 108 #include <vector>
28 jgs 102
29 jgs 82 namespace escript {
30    
31     /**
32     \brief
33 jgs 108 DataArrayView provides a view of external data, configured according
34     to the given shape information and offset.
35 jgs 82
36     Description:
37     DataArrayView provides a view of data allocated externally. The
38     external data should provide sufficient values so that the dimensions
39 jgs 108 specified for the view shape will be satisfied. The viewer can update
40 jgs 82 values within the external data but cannot resize the external data.
41 jgs 108
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 jgs 82 */
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 jgs 108 /**
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 jgs 82 typedef std::vector<std::pair<int, int> > RegionType;
61 jgs 108 typedef std::vector<std::pair<int, int> > RegionLoopRangeType;
62 jgs 82
63     /**
64     \brief
65     Default constructor for DataArrayView.
66    
67     Description:
68 jgs 108 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 jgs 82 */
73     DataArrayView();
74    
75     /**
76     \brief
77     Constructor for DataArrayView.
78    
79     Description:
80     Constructor for DataArrayView.
81    
82 jgs 108 \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 jgs 82 */
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 jgs 108 \param other - Input -
103     DataArrayView to copy.
104 jgs 82
105 jgs 108 NOTE: The copy references the same data array.
106 jgs 82 */
107     DataArrayView(const DataArrayView& other);
108    
109     /**
110     \brief
111 jgs 108 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 jgs 82 */
114     void
115     copy(const boost::python::numeric::array& value);
116    
117     /**
118     \brief
119 jgs 108 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 jgs 82 */
124     void
125     copy(const DataArrayView& other);
126    
127     /**
128     \brief
129 jgs 108 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 jgs 82 */
134     void
135     copy(ValueType::size_type offset,
136     const DataArrayView& other);
137    
138     /**
139     \brief
140 jgs 108 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 jgs 82
145 jgs 108 \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 jgs 82 */
152     void
153     copy(ValueType::size_type thisOffset,
154     const DataArrayView& other,
155     ValueType::size_type otherOffset);
156    
157     /**
158     \brief
159 jgs 108 Copy the given single value over the entire view starting at the given
160     offset in the view's data array.
161 jgs 82
162 jgs 108 \param offset - Input -
163     Offset into this view's data array to copy to.
164     \param value - Input -
165     Value to copy.
166 jgs 82 */
167     void
168     copy(ValueType::size_type offset,
169     ValueType::value_type value);
170    
171     /**
172 jgs 108 \brief
173     Check if view is empty. ie: does not point to any actual data.
174     */
175     bool
176     isEmpty() const;
177    
178     /**
179 jgs 82 \brief
180 jgs 108 Return this view's offset into the viewed data array.
181 jgs 82 */
182     ValueType::size_type
183     getOffset() const;
184    
185     /**
186 jgs 108 \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 jgs 82 */
192 jgs 108 void
193     setOffset(ValueType::size_type offset);
194 jgs 82
195     /**
196     \brief
197 jgs 108 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 jgs 82 */
201 jgs 108 void
202     incrOffset();
203 jgs 82
204     /**
205     \brief
206 jgs 108 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 jgs 82 */
209 jgs 108 bool
210     checkOffset() const;
211     bool
212     checkOffset(ValueType::size_type offset) const;
213 jgs 82
214     /**
215 jgs 108 \brief
216     Return the rank of the shape of this view.
217     */
218     int
219     getRank() const;
220    
221     /**
222 jgs 82 \brief
223 jgs 108 Return the number of values for the shape of this view.
224 jgs 82 */
225     int
226     noValues() const;
227    
228     /**
229     \brief
230 jgs 108 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 jgs 82 */
233 jgs 108 static int
234     noValues(const ShapeType& shape);
235     static int
236     noValues(const RegionLoopRangeType& region);
237 jgs 82
238     /**
239     \brief
240 jgs 108 Return a reference to the underlying data array.
241 jgs 82 */
242     ValueType&
243     getData() const;
244    
245     /**
246     \brief
247 jgs 108 Return a reference to the data value with the given
248     index in this view. This takes into account the offset.
249 jgs 82 */
250     ValueType::reference
251     getData(ValueType::size_type i) const;
252    
253     /**
254     \brief
255 jgs 108 Return the shape of this view.
256 jgs 82 */
257 jgs 108 const ShapeType&
258     getShape() const;
259 jgs 82
260     /**
261     \brief
262 jgs 108 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 jgs 82 */
265 jgs 108 bool
266     checkShape(const DataArrayView::ShapeType& other) const;
267 jgs 82
268     /**
269     \brief
270 jgs 108 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 jgs 82
274 jgs 108 \param messagePrefix - Input -
275     First part of the error message.
276     \param other - Input -
277     The other shape.
278 jgs 82 */
279 jgs 108 std::string
280     createShapeErrorMessage(const std::string& messagePrefix,
281     const DataArrayView::ShapeType& other) const;
282 jgs 82
283     /**
284     \brief
285 jgs 108 Return the viewed data as a formatted string.
286     Not recommended for very large objects!
287 jgs 82
288 jgs 108 \param suffix - Input -
289     Suffix appended to index display.
290 jgs 82 */
291 jgs 108 std::string
292     toString(const std::string& suffix=std::string("")) const;
293 jgs 82
294     /**
295     \brief
296 jgs 108 Return the given shape as a string.
297     This is purely a utility method and has no bearing on this view.
298 jgs 82
299 jgs 108 \param shape - Input.
300 jgs 82 */
301 jgs 108 static std::string
302     shapeToString(const DataArrayView::ShapeType& shape);
303 jgs 82
304 jgs 108 /**
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 jgs 82 */
310 jgs 108 ValueType::size_type
311     relIndex() const;
312 jgs 82
313     /**
314 jgs 108 \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 jgs 82 */
319 jgs 108 ValueType::size_type
320     relIndex(ValueType::size_type i) const;
321 jgs 82
322     /**
323 jgs 108 \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 jgs 82 */
328 jgs 108 ValueType::size_type
329     relIndex(ValueType::size_type i,
330     ValueType::size_type j) const;
331 jgs 82
332     /**
333 jgs 108 \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 jgs 82 */
338 jgs 108 ValueType::size_type
339     relIndex(ValueType::size_type i,
340     ValueType::size_type j,
341     ValueType::size_type k) const;
342 jgs 82
343     /**
344     \brief
345 jgs 108 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 jgs 82 */
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 jgs 108 Return the 1 dimensional index into the data array of the only element
358     in the view.
359     Assumes a rank 0 view.
360 jgs 82 */
361     ValueType::size_type
362 jgs 108 index() const;
363 jgs 82
364     /**
365     \brief
366 jgs 108 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 jgs 82 */
370     ValueType::size_type
371 jgs 108 index(ValueType::size_type i) const;
372 jgs 82
373     /**
374     \brief
375 jgs 108 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 jgs 82 */
379     ValueType::size_type
380     index(ValueType::size_type i,
381 jgs 108 ValueType::size_type j) const;
382 jgs 82
383     /**
384     \brief
385 jgs 108 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 jgs 82 */
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 jgs 108 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 jgs 82 */
400     ValueType::size_type
401     index(ValueType::size_type i,
402 jgs 108 ValueType::size_type j,
403     ValueType::size_type k,
404     ValueType::size_type m) const;
405 jgs 82
406     /**
407     \brief
408 jgs 108 Return a reference for the only element in the view.
409     Assumes a rank 0 view.
410 jgs 82 */
411 jgs 108 ValueType::reference
412     operator()();
413 jgs 82
414 jgs 108 ValueType::const_reference
415     operator()() const;
416    
417 jgs 82 /**
418     \brief
419 jgs 108 Return a reference to the element at position i in the view.
420     Assumes a rank 1 view.
421 jgs 82 */
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 jgs 108 Return a reference to the element at position i,j in the view.
431     Assumes a rank 2 view.
432 jgs 82 */
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 jgs 108 Return a reference to the element at position i,j,k in the view.
444     Assumes a rank 3 view.
445 jgs 82 */
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 jgs 108 Return a reference to the element at position i,j,k,m in the view.
459     Assumes a rank 4 view.
460 jgs 82 */
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 jgs 108 \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 jgs 82 */
481 jgs 108 static DataArrayView::ShapeType
482     getResultSliceShape(const RegionType& region);
483 jgs 82
484 jgs 108 /**
485     \brief
486     Determine the region specified by the given python slice object.
487 jgs 82
488 jgs 108 \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 jgs 82 /**
544     \brief
545 jgs 108 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 jgs 82 */
553     void
554 jgs 108 copySlice(const DataArrayView& other,
555     const RegionLoopRangeType& region);
556 jgs 82
557     /**
558     \brief
559 jgs 108 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 jgs 82 */
571     void
572 jgs 108 copySlice(ValueType::size_type thisOffset,
573     const DataArrayView& other,
574     ValueType::size_type otherOffset,
575     const RegionLoopRangeType& region);
576 jgs 82
577     /**
578     \brief
579 jgs 108 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 jgs 102
582 jgs 108 \param other - Input -
583     View to copy data from.
584     \param region - Input -
585     Region in this view to copy data to.
586 jgs 102 */
587 jgs 108 void
588     copySliceFrom(const DataArrayView& other,
589     const RegionLoopRangeType& region);
590 jgs 102
591     /**
592     \brief
593 jgs 108 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 jgs 102
596 jgs 108 \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 jgs 102 */
605 jgs 108 void
606     copySliceFrom(ValueType::size_type thisOffset,
607     const DataArrayView& other,
608     ValueType::size_type otherOffset,
609     const RegionLoopRangeType& region);
610 jgs 102
611     /**
612     \brief
613 jgs 108 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 jgs 82 */
622     template <class UnaryFunction>
623 jgs 108 void
624     unaryOp(UnaryFunction operation);
625 jgs 82
626     /**
627     \brief
628 jgs 108 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 jgs 82 */
639     template <class UnaryFunction>
640 jgs 108 void
641     unaryOp(ValueType::size_type offset,
642     UnaryFunction operation);
643 jgs 82
644     /**
645     \brief
646 jgs 108 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 jgs 82 */
658     template <class BinaryFunction>
659     void
660 jgs 108 binaryOp(const DataArrayView& right,
661 jgs 82 BinaryFunction operation);
662    
663     /**
664     \brief
665 jgs 108 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 jgs 82 */
681     template <class BinaryFunction>
682     void
683 jgs 108 binaryOp(ValueType::size_type leftOffset,
684     const DataArrayView& right,
685     ValueType::size_type rightOffset,
686 jgs 82 BinaryFunction operation);
687    
688     /**
689     \brief
690 jgs 108 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 jgs 82 */
702     template <class BinaryFunction>
703     void
704 jgs 108 binaryOp(double right,
705 jgs 82 BinaryFunction operation);
706    
707     /**
708     \brief
709 jgs 108 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 jgs 82 */
723     template <class BinaryFunction>
724     void
725 jgs 108 binaryOp(ValueType::size_type offset,
726     double right,
727 jgs 82 BinaryFunction operation);
728    
729     /**
730     \brief
731 jgs 108 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 jgs 82 */
741 jgs 108 template <class UnaryFunction>
742     double
743     dp_reductionOp(UnaryFunction operation) const;
744 jgs 82
745     /**
746     \brief
747 jgs 108 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 jgs 82
752 jgs 108 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 jgs 82 */
759 jgs 108 template <class UnaryFunction>
760     double
761     dp_reductionOp(ValueType::size_type offset,
762     UnaryFunction operation) const;
763 jgs 82
764     /**
765     \brief
766 jgs 108 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 jgs 82 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 jgs 108 /**
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 jgs 82 protected:
826    
827     private:
828    
829     //
830 jgs 108 // The maximum rank allowed for the shape of any view.
831 jgs 82 static const int m_maxRank=4;
832    
833     //
834 jgs 108 // 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 jgs 82 ValueType* m_data;
838    
839     //
840     // The offset into the data array used by different views.
841 jgs 108 // This is simply an integer specifying a position in the data array
842     // pointed to by m_data.
843 jgs 82 ValueType::size_type m_offset;
844    
845     //
846     // The shape of the data.
847 jgs 108 // This is simply an STL vector specifying the lengths of each dimension
848     // of the shape as ints.
849 jgs 82 ShapeType m_shape;
850    
851     //
852     // The number of values needed for the array.
853 jgs 108 // This can be derived from m_shape by multiplying the size of each dimension, but
854     // is stored here for convenience.
855 jgs 82 int m_noValues;
856    
857     };
858    
859 jgs 108 bool operator==(const DataArrayView& left, const DataArrayView& right);
860     bool operator!=(const DataArrayView& left, const DataArrayView& right);
861    
862 jgs 102 /**
863     \brief
864 jgs 108 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 jgs 102 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 jgs 108 /**
892     Inline function definitions.
893     */
894    
895     template <class UnaryFunction>
896 jgs 82 inline
897 jgs 108 void
898     DataArrayView::unaryOp(UnaryFunction operation)
899 jgs 82 {
900 jgs 108 unaryOp(m_offset,operation);
901 jgs 82 }
902    
903 jgs 108 template <class UnaryFunction>
904 jgs 82 inline
905 jgs 108 void
906     DataArrayView::unaryOp(ValueType::size_type offset,
907     UnaryFunction operation)
908 jgs 82 {
909 jgs 108 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 jgs 82 }
915    
916 jgs 108 template <class BinaryFunction>
917 jgs 82 inline
918 jgs 108 void
919     DataArrayView::binaryOp(const DataArrayView& right,
920     BinaryFunction operation)
921 jgs 82 {
922 jgs 108 binaryOp(m_offset,right,right.getOffset(),operation);
923 jgs 82 }
924    
925 jgs 108 template <class BinaryFunction>
926 jgs 82 inline
927     void
928 jgs 108 DataArrayView::binaryOp(ValueType::size_type leftOffset,
929     const DataArrayView& right,
930     ValueType::size_type rightOffset,
931     BinaryFunction operation)
932 jgs 82 {
933 jgs 108 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 jgs 82 }
942     }
943    
944 jgs 108 template <class BinaryFunction>
945 jgs 82 inline
946     void
947 jgs 108 DataArrayView::binaryOp(double right,
948     BinaryFunction operation)
949 jgs 82 {
950 jgs 108 binaryOp(m_offset,right,operation);
951 jgs 82 }
952    
953 jgs 108 template <class BinaryFunction>
954 jgs 82 inline
955 jgs 108 void
956     DataArrayView::binaryOp(ValueType::size_type offset,
957     double right,
958     BinaryFunction operation)
959 jgs 102 {
960 jgs 108 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 jgs 102 }
965     }
966    
967     template <class UnaryFunction>
968     inline
969     double
970 jgs 108 DataArrayView::dp_reductionOp(UnaryFunction operation) const
971 jgs 102 {
972 jgs 108 return dp_reductionOp(m_offset,operation);
973 jgs 102 }
974    
975     template <class UnaryFunction>
976     inline
977     double
978 jgs 108 DataArrayView::dp_reductionOp(ValueType::size_type offset,
979     UnaryFunction operation) const
980 jgs 82 {
981 jgs 108 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 jgs 82 }
987     return operation.getResult();
988     }
989    
990     template <class UnaryFunction>
991     inline
992     double
993 jgs 108 DataArrayView::reductionOp(UnaryFunction operation) const
994 jgs 82 {
995 jgs 108 return reductionOp(m_offset,operation);
996 jgs 82 }
997    
998 jgs 108 template <class UnaryFunction>
999 jgs 82 inline
1000 jgs 108 double
1001     DataArrayView::reductionOp(ValueType::size_type offset,
1002     UnaryFunction operation) const
1003 jgs 82 {
1004 jgs 108 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 jgs 82 }
1009 jgs 108 return operation.getResult();
1010 jgs 82 }
1011    
1012     inline
1013 jgs 108 DataArrayView::ValueType::size_type
1014     DataArrayView::relIndex() const
1015 jgs 82 {
1016 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
1017     return 0;
1018 jgs 82 }
1019    
1020     inline
1021 jgs 108 DataArrayView::ValueType::size_type
1022     DataArrayView::index() const
1023 jgs 82 {
1024 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
1025     return (m_offset);
1026 jgs 82 }
1027    
1028     inline
1029 jgs 108 DataArrayView::ValueType::size_type
1030     DataArrayView::relIndex(ValueType::size_type i) const
1031 jgs 82 {
1032 jgs 108 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 jgs 82 }
1036    
1037     inline
1038     DataArrayView::ValueType::size_type
1039     DataArrayView::index(ValueType::size_type i) const
1040     {
1041 jgs 108 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 jgs 82 }
1045    
1046     inline
1047     DataArrayView::ValueType::size_type
1048     DataArrayView::relIndex(ValueType::size_type i,
1049     ValueType::size_type j) const
1050     {
1051 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1052 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1053 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1054 jgs 82 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 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1063 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1064 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1065     return (m_offset+temp);
1066 jgs 82 }
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 jgs 108 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 jgs 82 }
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 jgs 108 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 jgs 82 }
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 jgs 108 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1100 jgs 82 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 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1102 jgs 82 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 jgs 108 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1113 jgs 82 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 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1115     return (m_offset+temp);
1116 jgs 82 }
1117    
1118     inline
1119     DataArrayView::ValueType::reference
1120 jgs 108 DataArrayView::operator()()
1121 jgs 82 {
1122 jgs 108 return (*m_data)[index()];
1123 jgs 82 }
1124    
1125     inline
1126     DataArrayView::ValueType::const_reference
1127 jgs 108 DataArrayView::operator()() const
1128 jgs 82 {
1129 jgs 108 return (*m_data)[index()];
1130 jgs 82 }
1131    
1132     inline
1133     DataArrayView::ValueType::reference
1134 jgs 108 DataArrayView::operator()(ValueType::size_type i)
1135 jgs 82 {
1136 jgs 108 return (*m_data)[index(i)];
1137 jgs 82 }
1138    
1139     inline
1140     DataArrayView::ValueType::const_reference
1141 jgs 108 DataArrayView::operator()(ValueType::size_type i) const
1142 jgs 82 {
1143 jgs 108 return (*m_data)[index(i)];
1144 jgs 82 }
1145    
1146     inline
1147     DataArrayView::ValueType::reference
1148     DataArrayView::operator()(ValueType::size_type i,
1149     ValueType::size_type j)
1150     {
1151 jgs 108 return (*m_data)[index(i,j)];
1152 jgs 82 }
1153    
1154     inline
1155     DataArrayView::ValueType::const_reference
1156     DataArrayView::operator()(ValueType::size_type i,
1157     ValueType::size_type j) const
1158     {
1159 jgs 108 return (*m_data)[index(i,j)];
1160 jgs 82 }
1161    
1162     inline
1163     DataArrayView::ValueType::reference
1164 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1165     ValueType::size_type j,
1166     ValueType::size_type k)
1167 jgs 82 {
1168 jgs 108 return (*m_data)[index(i,j,k)];
1169 jgs 82 }
1170    
1171     inline
1172     DataArrayView::ValueType::const_reference
1173 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1174     ValueType::size_type j,
1175     ValueType::size_type k) const
1176 jgs 82 {
1177 jgs 108 return (*m_data)[index(i,j,k)];
1178 jgs 82 }
1179    
1180     inline
1181     DataArrayView::ValueType::reference
1182 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1183     ValueType::size_type j,
1184     ValueType::size_type k,
1185     ValueType::size_type m)
1186 jgs 82 {
1187 jgs 108 return (*m_data)[index(i,j,k,m)];
1188 jgs 82 }
1189    
1190     inline
1191     DataArrayView::ValueType::const_reference
1192 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1193     ValueType::size_type j,
1194     ValueType::size_type k,
1195     ValueType::size_type m) const
1196 jgs 82 {
1197 jgs 108 return (*m_data)[index(i,j,k,m)];
1198 jgs 82 }
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