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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 474 - (hide annotations)
Mon Jan 30 04:23:44 2006 UTC (13 years, 10 months ago) by jgs
File MIME type: text/plain
File size: 34818 byte(s)
restructure escript source tree
move src/Data/* -> src
remove inc
modify #includes and cpppath settings accordingly

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26