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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 147 - (hide annotations)
Fri Aug 12 01:45:47 2005 UTC (13 years, 10 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/DataArrayView.h
File MIME type: text/plain
File size: 34814 byte(s)
erge of development branch dev-02 back to main trunk on 2005-08-12

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     The slice object is a tuple of n python slice specifiers, where
501     n <= the rank of this Data object. Each slice specifier specifies the
502     range of indexes to be sliced from the corresponding dimension. The
503     first specifier corresponds to the first dimension, the second to the
504     second and so on. Where n < the rank, the remaining dimensions are
505     sliced across the full range of their indicies.
506    
507     Each slice specifier is of the form "a:b", which specifies a slice
508     from index a, up to but not including index b. Where index a is ommitted
509     a is assumed to be 0. Where index b is ommitted, b is assumed to be the
510     length of this dimension. Where both are ommitted (eg: ":") the slice is
511     assumed to encompass that entire dimension.
512    
513     Where one of the slice specifiers is a single integer, eg: [1], we
514     want to generate a rank-1 dimension object, as opposed to eg: [1,2]
515     which implies we want to take a rank dimensional object with one
516     dimension of size 1.
517    
518     The return value is a vector of pairs with length equal to the rank of
519     this object. Each pair corresponds to the range of indicies from the
520     corresponding dimension to be sliced from, as specified in the input
521     slice object.
522    
523     Examples:
524    
525     For a rank 1 object of shape(5):
526    
527     getSliceRegion(:) => < <0,5> >
528     getSliceRegion(2:3) => < <2,3> >
529     getSliceRegion(:3) => < <0,3> >
530     getSliceRegion(2:) => < <2,5> >
531    
532     For a rank 2 object of shape(4,5):
533    
534     getSliceRegion(2:3) => < <2,3> <0,5> >
535     getSliceRegion(2) => < <2,3> <0,5> >
536     NB: but return object requested will have rank 1, shape(5), with
537     values taken from index 2 of this object's first dimension.
538    
539     For a rank 3 object of shape (2,4,6):
540    
541     getSliceRegion(0:2,0:4,0:6) => < <0,2> <0,4> <0,6> >
542     getSliceRegion(:,:,:) => < <0,2> <0,4> <0,6> >
543     getSliceRegion(0:1) => < <0,1> <0,4> <0,6> >
544     getSliceRegion(:1,0:2) => < <0,1> <0,2> <0,6> >
545    
546     */
547 jgs 117 RegionType
548 jgs 108 getSliceRegion(const boost::python::object& key) const;
549    
550 jgs 82 /**
551     \brief
552 jgs 108 Copy a data slice specified by the given region from the given view
553     into this view, using the default offsets in both views.
554    
555     \param other - Input -
556     View to copy data from.
557     \param region - Input -
558     Region in other view to copy data from.
559 jgs 82 */
560     void
561 jgs 108 copySlice(const DataArrayView& other,
562     const RegionLoopRangeType& region);
563 jgs 82
564     /**
565     \brief
566 jgs 108 Copy a data slice specified by the given region and offset from the
567     given view into this view at the given offset.
568    
569     \param thisOffset - Input -
570     Copy the slice to this offset in this view.
571     \param other - Input -
572     View to copy data from.
573     \param otherOffset - Input -
574     Copy the slice from this offset in the given view.
575     \param region - Input -
576     Region in other view to copy data from.
577 jgs 82 */
578     void
579 jgs 108 copySlice(ValueType::size_type thisOffset,
580     const DataArrayView& other,
581     ValueType::size_type otherOffset,
582     const RegionLoopRangeType& region);
583 jgs 82
584     /**
585     \brief
586 jgs 108 Copy data into a slice specified by the given region in this view from
587     the given view, using the default offsets in both views.
588 jgs 102
589 jgs 108 \param other - Input -
590     View to copy data from.
591     \param region - Input -
592     Region in this view to copy data to.
593 jgs 102 */
594 jgs 108 void
595     copySliceFrom(const DataArrayView& other,
596     const RegionLoopRangeType& region);
597 jgs 102
598     /**
599     \brief
600 jgs 108 Copy data into a slice specified by the given region and offset in
601     this view from the given view at the given offset.
602 jgs 102
603 jgs 108 \param thisOffset - Input -
604     Copy the slice to this offset in this view.
605     \param other - Input -
606     View to copy data from.
607     \param otherOffset - Input -
608     Copy the slice from this offset in the given view.
609     \param region - Input -
610     Region in this view to copy data to.
611 jgs 102 */
612 jgs 108 void
613     copySliceFrom(ValueType::size_type thisOffset,
614     const DataArrayView& other,
615     ValueType::size_type otherOffset,
616     const RegionLoopRangeType& region);
617 jgs 102
618     /**
619     \brief
620 jgs 108 Perform the unary operation on the data point specified by the view's
621     default offset. Applies the specified operation to each value in the data
622     point.
623    
624     Called by escript::unaryOp.
625    
626     \param operation - Input -
627     Operation to apply. Operation must be a pointer to a function.
628 jgs 82 */
629     template <class UnaryFunction>
630 jgs 108 void
631     unaryOp(UnaryFunction operation);
632 jgs 82
633     /**
634     \brief
635 jgs 108 Perform the unary operation on the data point specified by the given
636     offset. Applies the specified operation to each value in the data
637     point. Operation must be a pointer to a function.
638    
639     Called by escript::unaryOp.
640    
641     \param offset - Input -
642     Apply the operation to data starting at this offset in this view.
643     \param operation - Input -
644     Operation to apply. Must be a pointer to a function.
645 jgs 82 */
646     template <class UnaryFunction>
647 jgs 108 void
648     unaryOp(ValueType::size_type offset,
649     UnaryFunction operation);
650 jgs 82
651     /**
652     \brief
653 jgs 108 Perform the binary operation on the data points specified by the default
654     offsets in this view and in view "right". Applies the specified operation
655     to corresponding values in both data points. Operation must be a pointer
656     to a function.
657    
658     Called by escript::binaryOp.
659    
660     \param right - Input -
661     View to act as RHS in given binary operation.
662     \param operation - Input -
663     Operation to apply. Must be a pointer to a function.
664 jgs 82 */
665     template <class BinaryFunction>
666     void
667 jgs 108 binaryOp(const DataArrayView& right,
668 jgs 82 BinaryFunction operation);
669    
670     /**
671     \brief
672 jgs 108 Perform the binary operation on the data points specified by the given
673     offsets in this view and in view "right". Applies the specified operation
674     to corresponding values in both data points. Operation must be a pointer
675     to a function.
676    
677     Called by escript::binaryOp.
678    
679     \param leftOffset - Input -
680     Apply the operation to data starting at this offset in this view.
681     \param right - Input -
682     View to act as RHS in given binary operation.
683     \param rightOffset - Input -
684     Apply the operation to data starting at this offset in right.
685     \param operation - Input -
686     Operation to apply. Must be a pointer to a function.
687 jgs 82 */
688     template <class BinaryFunction>
689     void
690 jgs 108 binaryOp(ValueType::size_type leftOffset,
691     const DataArrayView& right,
692     ValueType::size_type rightOffset,
693 jgs 82 BinaryFunction operation);
694    
695     /**
696     \brief
697 jgs 108 Perform the binary operation on the data point specified by the default
698     offset in this view using the scalar value "right". Applies the specified
699     operation to values in the data point. Operation must be a pointer to
700     a function.
701    
702     Called by escript::binaryOp.
703    
704     \param right - Input -
705     Value to act as RHS in given binary operation.
706     \param operation - Input -
707     Operation to apply. Must be a pointer to a function.
708 jgs 82 */
709     template <class BinaryFunction>
710     void
711 jgs 108 binaryOp(double right,
712 jgs 82 BinaryFunction operation);
713    
714     /**
715     \brief
716 jgs 108 Perform the binary operation on the data point specified by the given
717     offset in this view using the scalar value "right". Applies the specified
718     operation to values in the data point. Operation must be a pointer
719     to a function.
720    
721     Called by escript::binaryOp.
722    
723     \param offset - Input -
724     Apply the operation to data starting at this offset in this view.
725     \param right - Input -
726     Value to act as RHS in given binary operation.
727     \param operation - Input -
728     Operation to apply. Must be a pointer to a function.
729 jgs 82 */
730     template <class BinaryFunction>
731     void
732 jgs 108 binaryOp(ValueType::size_type offset,
733     double right,
734 jgs 82 BinaryFunction operation);
735    
736     /**
737     \brief
738 jgs 108 Perform the given data point reduction operation on the data point
739     specified by the default offset into the view. Reduces all elements of
740     the data point using the given operation, returning the result as a
741     scalar. Operation must be a pointer to a function.
742    
743     Called by escript::algorithm.
744    
745     \param operation - Input -
746     Operation to apply. Must be a pointer to a function.
747     */
748 jgs 147 template <class BinaryFunction>
749 jgs 108 double
750 jgs 147 reductionOp(BinaryFunction operation,
751     double initial_value) const;
752 jgs 108
753     /**
754     \brief
755 jgs 113 Perform the given data point reduction operation on the data point
756 jgs 108 specified by the given offset into the view. Reduces all elements of
757     the data point using the given operation, returning the result as a
758     scalar. Operation must be a pointer to a function.
759    
760     Called by escript::algorithm.
761    
762     \param offset - Input -
763     Apply the operation to data starting at this offset in this view.
764     \param operation - Input -
765     Operation to apply. Must be a pointer to a function.
766     */
767 jgs 147 template <class BinaryFunction>
768 jgs 108 double
769     reductionOp(ValueType::size_type offset,
770 jgs 147 BinaryFunction operation,
771     double initial_value) const;
772 jgs 108
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 jgs 126 NB: Only multiplies together the two given views, ie: two data-points,
779     would need to call this over all data-points to multiply the entire
780     Data objects involved.
781    
782 jgs 82 \param left - Input - The left hand side.
783     \param right - Input - The right hand side.
784     \param result - Output - The result of the operation.
785     */
786 jgs 117 static
787     void
788 jgs 82 matMult(const DataArrayView& left,
789     const DataArrayView& right,
790     DataArrayView& result);
791    
792 jgs 108 /**
793     \brief
794     Determine the shape of the result array for a matrix multiplication
795     of the given views.
796     This is purely a utility method and has no bearing on this view.
797     */
798 jgs 117 static
799     ShapeType
800 jgs 108 determineResultShape(const DataArrayView& left,
801     const DataArrayView& right);
802    
803 jgs 82 protected:
804    
805     private:
806    
807     //
808 jgs 108 // The maximum rank allowed for the shape of any view.
809 jgs 82 static const int m_maxRank=4;
810    
811     //
812 jgs 108 // The data values for the view.
813     // NOTE: This points to data external to the view.
814 jgs 117 // This is just a pointer to an array of ValueType.
815 jgs 82 ValueType* m_data;
816    
817     //
818     // The offset into the data array used by different views.
819 jgs 108 // This is simply an integer specifying a position in the data array
820     // pointed to by m_data.
821 jgs 82 ValueType::size_type m_offset;
822    
823     //
824     // The shape of the data.
825 jgs 108 // This is simply an STL vector specifying the lengths of each dimension
826     // of the shape as ints.
827 jgs 82 ShapeType m_shape;
828    
829     //
830     // The number of values needed for the array.
831 jgs 108 // This can be derived from m_shape by multiplying the size of each dimension, but
832     // is stored here for convenience.
833 jgs 82 int m_noValues;
834    
835     };
836    
837 jgs 108 bool operator==(const DataArrayView& left, const DataArrayView& right);
838     bool operator!=(const DataArrayView& left, const DataArrayView& right);
839    
840 jgs 102 /**
841     \brief
842 jgs 108 Modify region to copy from in order to
843     deal with the case where one range in the region contains identical indexes,
844     eg: <<1,1><0,3><0,3>>
845     This situation implies we want to copy from an object with rank greater than that of this
846     object. eg: we want to copy the values from a two dimensional slice out of a three
847     dimensional object into a two dimensional object.
848     We do this by taking a slice from the other object where one dimension of
849     the slice region is of size 1. So in the above example, we modify the above
850     region like so: <<1,2><0,3><0,3>> and take this slice.
851     */
852     DataArrayView::RegionLoopRangeType
853     getSliceRegionLoopRange(const DataArrayView::RegionType& region);
854    
855     /**
856     \brief
857 jgs 102 Calculate the slice range from the given python key object
858     Used by DataArrayView::getSliceRegion.
859     Returns the python slice object key as a pair of ints where the first
860     member is the start and the second member is the end. the presence of a possible
861     step attribute with value different from one will throw an exception
862    
863     /param key - Input - key object specifying slice range.
864     */
865     std::pair<int,int>
866     getSliceRange(const boost::python::object& key,
867     const int shape);
868    
869 jgs 108 /**
870     Inline function definitions.
871     */
872    
873     template <class UnaryFunction>
874 jgs 82 inline
875 jgs 108 void
876     DataArrayView::unaryOp(UnaryFunction operation)
877 jgs 82 {
878 jgs 108 unaryOp(m_offset,operation);
879 jgs 82 }
880    
881 jgs 108 template <class UnaryFunction>
882 jgs 82 inline
883 jgs 108 void
884     DataArrayView::unaryOp(ValueType::size_type offset,
885     UnaryFunction operation)
886 jgs 82 {
887 jgs 108 EsysAssert((!isEmpty()&&checkOffset(offset)),
888     "Error - Couldn't perform unaryOp due to insufficient storage.");
889     for (ValueType::size_type i=0;i<noValues();i++) {
890     (*m_data)[offset+i]=operation((*m_data)[offset+i]);
891     }
892 jgs 82 }
893    
894 jgs 108 template <class BinaryFunction>
895 jgs 82 inline
896 jgs 108 void
897     DataArrayView::binaryOp(const DataArrayView& right,
898     BinaryFunction operation)
899 jgs 82 {
900 jgs 108 binaryOp(m_offset,right,right.getOffset(),operation);
901 jgs 82 }
902    
903 jgs 108 template <class BinaryFunction>
904 jgs 82 inline
905     void
906 jgs 108 DataArrayView::binaryOp(ValueType::size_type leftOffset,
907     const DataArrayView& right,
908     ValueType::size_type rightOffset,
909     BinaryFunction operation)
910 jgs 82 {
911 jgs 108 EsysAssert(getShape()==right.getShape(),
912     "Error - Couldn't perform binaryOp due to shape mismatch,");
913     EsysAssert((!isEmpty()&&checkOffset(leftOffset)),
914     "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
915     EsysAssert((!right.isEmpty()&&right.checkOffset(rightOffset)),
916     "Error - Couldn't perform binaryOp due to insufficient storage in right object.");
917     for (ValueType::size_type i=0;i<noValues();i++) {
918     (*m_data)[leftOffset+i]=operation((*m_data)[leftOffset+i],(*right.m_data)[rightOffset+i]);
919 jgs 82 }
920     }
921    
922 jgs 108 template <class BinaryFunction>
923 jgs 82 inline
924     void
925 jgs 108 DataArrayView::binaryOp(double right,
926     BinaryFunction operation)
927 jgs 82 {
928 jgs 108 binaryOp(m_offset,right,operation);
929 jgs 82 }
930    
931 jgs 108 template <class BinaryFunction>
932 jgs 82 inline
933 jgs 108 void
934     DataArrayView::binaryOp(ValueType::size_type offset,
935     double right,
936     BinaryFunction operation)
937 jgs 102 {
938 jgs 108 EsysAssert((!isEmpty()&&checkOffset(offset)),
939 jgs 113 "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
940 jgs 108 for (ValueType::size_type i=0;i<noValues();i++) {
941     (*m_data)[offset+i]=operation((*m_data)[offset+i],right);
942 jgs 102 }
943     }
944    
945 jgs 147 template <class BinaryFunction>
946 jgs 102 inline
947     double
948 jgs 147 DataArrayView::reductionOp(BinaryFunction operation,
949     double initial_value) const
950 jgs 82 {
951 jgs 147 return reductionOp(m_offset,operation,initial_value);
952 jgs 82 }
953    
954 jgs 147 template <class BinaryFunction>
955 jgs 82 inline
956 jgs 108 double
957     DataArrayView::reductionOp(ValueType::size_type offset,
958 jgs 147 BinaryFunction operation,
959     double initial_value) const
960 jgs 82 {
961 jgs 108 EsysAssert((!isEmpty()&&checkOffset(offset)),
962     "Error - Couldn't perform reductionOp due to insufficient storage.");
963 jgs 147 double current_value=initial_value;
964 jgs 108 for (ValueType::size_type i=0;i<noValues();i++) {
965 jgs 147 current_value=operation(current_value,(*m_data)[offset+i]);
966 jgs 82 }
967 jgs 147 return current_value;
968 jgs 82 }
969    
970     inline
971 jgs 108 DataArrayView::ValueType::size_type
972     DataArrayView::relIndex() const
973 jgs 82 {
974 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
975     return 0;
976 jgs 82 }
977    
978     inline
979 jgs 108 DataArrayView::ValueType::size_type
980     DataArrayView::index() const
981 jgs 82 {
982 jgs 108 EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
983     return (m_offset);
984 jgs 82 }
985    
986     inline
987 jgs 108 DataArrayView::ValueType::size_type
988     DataArrayView::relIndex(ValueType::size_type i) const
989 jgs 82 {
990 jgs 108 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
991     EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
992     return i;
993 jgs 82 }
994    
995     inline
996     DataArrayView::ValueType::size_type
997     DataArrayView::index(ValueType::size_type i) const
998     {
999 jgs 108 EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
1000     EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
1001     return (m_offset+i);
1002 jgs 82 }
1003    
1004     inline
1005     DataArrayView::ValueType::size_type
1006     DataArrayView::relIndex(ValueType::size_type i,
1007     ValueType::size_type j) const
1008     {
1009 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1010 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1011 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1012 jgs 82 return temp;
1013     }
1014    
1015     inline
1016     DataArrayView::ValueType::size_type
1017     DataArrayView::index(ValueType::size_type i,
1018     ValueType::size_type j) const
1019     {
1020 jgs 108 EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1021 jgs 82 ValueType::size_type temp=i+j*m_shape[0];
1022 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1023     return (m_offset+temp);
1024 jgs 82 }
1025    
1026     inline
1027     DataArrayView::ValueType::size_type
1028     DataArrayView::relIndex(ValueType::size_type i,
1029     ValueType::size_type j,
1030     ValueType::size_type k) const
1031     {
1032 jgs 108 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1033     ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1034     EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1035     return temp;
1036 jgs 82 }
1037    
1038     inline
1039     DataArrayView::ValueType::size_type
1040     DataArrayView::index(ValueType::size_type i,
1041     ValueType::size_type j,
1042     ValueType::size_type k) const
1043     {
1044 jgs 108 EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1045     ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1046     EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1047     return (m_offset+temp);
1048 jgs 82 }
1049    
1050     inline
1051     DataArrayView::ValueType::size_type
1052     DataArrayView::relIndex(ValueType::size_type i,
1053     ValueType::size_type j,
1054     ValueType::size_type k,
1055     ValueType::size_type m) const
1056     {
1057 jgs 108 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1058 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];
1059 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1060 jgs 82 return temp;
1061     }
1062    
1063     inline
1064     DataArrayView::ValueType::size_type
1065     DataArrayView::index(ValueType::size_type i,
1066     ValueType::size_type j,
1067     ValueType::size_type k,
1068     ValueType::size_type m) const
1069     {
1070 jgs 108 EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1071 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];
1072 jgs 108 EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1073     return (m_offset+temp);
1074 jgs 82 }
1075    
1076     inline
1077     DataArrayView::ValueType::reference
1078 jgs 108 DataArrayView::operator()()
1079 jgs 82 {
1080 jgs 108 return (*m_data)[index()];
1081 jgs 82 }
1082    
1083     inline
1084     DataArrayView::ValueType::const_reference
1085 jgs 108 DataArrayView::operator()() const
1086 jgs 82 {
1087 jgs 108 return (*m_data)[index()];
1088 jgs 82 }
1089    
1090     inline
1091     DataArrayView::ValueType::reference
1092 jgs 108 DataArrayView::operator()(ValueType::size_type i)
1093 jgs 82 {
1094 jgs 108 return (*m_data)[index(i)];
1095 jgs 82 }
1096    
1097     inline
1098     DataArrayView::ValueType::const_reference
1099 jgs 108 DataArrayView::operator()(ValueType::size_type i) const
1100 jgs 82 {
1101 jgs 108 return (*m_data)[index(i)];
1102 jgs 82 }
1103    
1104     inline
1105     DataArrayView::ValueType::reference
1106     DataArrayView::operator()(ValueType::size_type i,
1107     ValueType::size_type j)
1108     {
1109 jgs 108 return (*m_data)[index(i,j)];
1110 jgs 82 }
1111    
1112     inline
1113     DataArrayView::ValueType::const_reference
1114     DataArrayView::operator()(ValueType::size_type i,
1115     ValueType::size_type j) const
1116     {
1117 jgs 108 return (*m_data)[index(i,j)];
1118 jgs 82 }
1119    
1120     inline
1121     DataArrayView::ValueType::reference
1122 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1123     ValueType::size_type j,
1124     ValueType::size_type k)
1125 jgs 82 {
1126 jgs 108 return (*m_data)[index(i,j,k)];
1127 jgs 82 }
1128    
1129     inline
1130     DataArrayView::ValueType::const_reference
1131 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1132     ValueType::size_type j,
1133     ValueType::size_type k) const
1134 jgs 82 {
1135 jgs 108 return (*m_data)[index(i,j,k)];
1136 jgs 82 }
1137    
1138     inline
1139     DataArrayView::ValueType::reference
1140 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1141     ValueType::size_type j,
1142     ValueType::size_type k,
1143     ValueType::size_type m)
1144 jgs 82 {
1145 jgs 108 return (*m_data)[index(i,j,k,m)];
1146 jgs 82 }
1147    
1148     inline
1149     DataArrayView::ValueType::const_reference
1150 jgs 108 DataArrayView::operator()(ValueType::size_type i,
1151     ValueType::size_type j,
1152     ValueType::size_type k,
1153     ValueType::size_type m) const
1154 jgs 82 {
1155 jgs 108 return (*m_data)[index(i,j,k,m)];
1156 jgs 82 }
1157    
1158     } // end of namespace
1159    
1160     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26