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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26