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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 106 by jgs, Thu Dec 23 07:20:12 2004 UTC revision 117 by jgs, Fri Apr 1 05:48:57 2005 UTC
# Line 1  Line 1 
1  // $Id$  // $Id$
2    
3  /*  /*
4   ******************************************************************************   ******************************************************************************
5   *                                                                            *   *                                                                            *
# Line 18  Line 19 
19    
20  #include "esysUtils/EsysAssert.h"  #include "esysUtils/EsysAssert.h"
21    
 #include <vector>  
22  #include <boost/python/numeric.hpp>  #include <boost/python/numeric.hpp>
23  #include <boost/python/object.hpp>  #include <boost/python/object.hpp>
24  #include <boost/shared_ptr.hpp>  #include <boost/shared_ptr.hpp>
25    
26  #include <iostream>  #include <iostream>
27    
28    #include <vector>
29    #include "escript/Data/DataVector.h"
30    
31  namespace escript {  namespace escript {
32    
33  /**  /**
34     \brief     \brief
35     DataArrayView provides a view of data allocated externally.     DataArrayView provides a view of external data, configured according
36       to the given shape information and offset.
37    
38     Description:     Description:
39     DataArrayView provides a view of data allocated externally. The     DataArrayView provides a view of data allocated externally. The
40     external data should provide sufficient values so that the dimensions     external data should provide sufficient values so that the dimensions
41     specified for the view will be satisfied. The viewer can update     specified for the view shape will be satisfied. The viewer can update
42     values within the external data but cannot resize the external data.     values within the external data but cannot resize the external data.
43    
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       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  */  */
51    
52  class DataArrayView {  class DataArrayView {
# Line 45  class DataArrayView { Line 56  class DataArrayView {
56    
57   public:   public:
58    
59    typedef std::vector<double> ValueType;    //
60    typedef std::vector<int> ShapeType;    // Some basic types which define the data values and view shapes.
61      typedef DataVector                        ValueType;
62      //typedef std::vector<double>               ValueType;
63      typedef std::vector<int>                  ShapeType;
64    typedef std::vector<std::pair<int, int> > RegionType;    typedef std::vector<std::pair<int, int> > RegionType;
65      typedef std::vector<std::pair<int, int> > RegionLoopRangeType;
66    
67    /**    /**
68       \brief       \brief
69       Default constructor for DataArrayView.       Default constructor for DataArrayView.
70    
71       Description:       Description:
72       Default constructor for DataArrayView. Creates an       Default constructor for DataArrayView.
73       empty view with no associated data.       Creates an empty view with no associated data array.
74    
75         This is essentially useless but here for completeness.
76    */    */
77    DataArrayView();    DataArrayView();
78    
# Line 66  class DataArrayView { Line 83  class DataArrayView {
83       Description:       Description:
84       Constructor for DataArrayView.       Constructor for DataArrayView.
85    
86       \param data - Input - Container holding data to be viewed. This must       \param data - Input -
87                             be large enough for the specified shape.                  Array holding data to be viewed. This must be large enough
88       \param viewShape - Input - The shape of the view.                  to supply sufficient values for the specified shape starting at
89       \param offset - Input - Offset into the data at which view should start.                  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    */    */
95    DataArrayView(ValueType& data,    DataArrayView(ValueType& data,
96                  const ShapeType& viewShape,                  const ShapeType& viewShape,
# Line 82  class DataArrayView { Line 103  class DataArrayView {
103       Description:       Description:
104       Copy constructor for DataArrayView.       Copy constructor for DataArrayView.
105    
106       \param other - Input - DataArrayView to copy.       \param other - Input -
107                    DataArrayView to copy.
108    
109       NOTE: The copy references the same data container.       NOTE: The copy references the same data array.
110    */    */
111    DataArrayView(const DataArrayView& other);    DataArrayView(const DataArrayView& other);
112    
113    /**    /**
114       \brief       \brief
115       Check if view is empty.       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.
   bool  
   isEmpty() const;  
   
   /**  
      \brief  
      Copy from a numarray into the data managed by DataArrayView.  
117    */    */
118    void    void
119    copy(const boost::python::numeric::array& value);    copy(const boost::python::numeric::array& value);
120    
121    /**    /**
122       \brief       \brief
123       Copy from another DataArrayViewinto the data managed by this       Copy data from another DataArrayView into the data array viewed by this
124       DataArrayView at the default offset.       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    */    */
128    void    void
129    copy(const DataArrayView& other);    copy(const DataArrayView& other);
130    
131    /**    /**
132       \brief       \brief
133       Copy from another DataArrayView into this view at the       Copy data from another DataArrayView into this view starting at the
134       given offset.       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    */    */
138    void    void
139    copy(ValueType::size_type offset,    copy(ValueType::size_type offset,
# Line 121  class DataArrayView { Line 141  class DataArrayView {
141    
142    /**    /**
143       \brief       \brief
144       Copy from another DataArrayView into this view at the       Copy data from another DataArrayView into this view starting at the
145       given offsets.       given offsets in each view.
146         The shapes of both views must be compatible - will throw if not.
147       \param thisOffset - Input - Offset into this view's data array to copy to.       NB: views may or may not reference same underlying data array!
148       \param other - Input - View for the data to copy.  
149       \param otherOffset - Input - Offset into the other view to copy data from.       \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    */    */
156    void    void
157    copy(ValueType::size_type thisOffset,    copy(ValueType::size_type thisOffset,
# Line 135  class DataArrayView { Line 160  class DataArrayView {
160    
161    /**    /**
162       \brief       \brief
163       Copy the given single value over the entire view.       Copy the given single value over the entire view starting at the given
164         offset in the view's data array.
165    
166       \param offset - Input - Offset into this view's data array to copy to.       \param offset - Input -
167       \param value - Input - Value to copy.                     Offset into this view's data array to copy to.
168         \param value - Input -
169                       Value to copy.
170    */    */
171    void    void
172    copy(ValueType::size_type offset,    copy(ValueType::size_type offset,
173         ValueType::value_type value);         ValueType::value_type value);
174    
175    /**    /**
176         \brief
177         Check if view is empty. ie: does not point to any actual data.
178      */
179      bool
180      isEmpty() const;
181    
182      /**
183      \brief      \brief
184      Return this view's offset to the start of data.      Return this view's offset into the viewed data array.
185    */    */
186    ValueType::size_type    ValueType::size_type
187    getOffset() const;    getOffset() const;
188    
189    /**    /**
190      \brief       \brief
191       Return the rank of the data.       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    */    */
196    int    void
197    getRank() const;    setOffset(ValueType::size_type offset);
198    
199    /**    /**
200       \brief       \brief
201       Return the shape of the data.       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    */    */
205    const ShapeType&    void
206    getShape() const;    incrOffset();
207    
208    /**    /**
209       \brief       \brief
210       Calculate the number of values for the given shape.       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    */    */
213    static int    bool
214    noValues(const ShapeType& shape);    checkOffset() const;
215    
216      bool
217      checkOffset(ValueType::size_type offset) const;
218    
219      /**
220        \brief
221         Return the rank of the shape of this view.
222      */
223      int
224      getRank() const;
225    
226    /**    /**
227       \brief       \brief
228       Return the number of values for the current view.       Return the number of values for the shape of this view.
229    */    */
230    int    int
231    noValues() const;    noValues() const;
232    
233    /**    /**
234       \brief       \brief
235       Return true if the given shape is the same as this object's shape.       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    */    */
238    bool    static
239    checkShape(const DataArrayView::ShapeType& other) const;    int
240      noValues(const ShapeType& shape);
241    
242      static
243      int
244      noValues(const RegionLoopRangeType& region);
245    
246    /**    /**
247       \brief       \brief
248       Return a reference to the underlying data.       Return a reference to the underlying data array.
249    */    */
250    ValueType&    ValueType&
251    getData() const;    getData() const;
252    
253    /**    /**
254       \brief       \brief
255       Return the value with the given index for the view. This takes into account       Return a reference to the data value with the given
256       the offset. Effectively this returns each value of the view in sequential order.       index in this view. This takes into account the offset.
257    */    */
258    ValueType::reference    ValueType::reference
259    getData(ValueType::size_type i) const;    getData(ValueType::size_type i) const;
260    
261    /**    /**
262       \brief       \brief
263       Create a shape error message. Normally used when there is a shape       Return the shape of this view.
      mismatch.  
   
      \param messagePrefix - Input - First part of the error message.  
      \param other - Input - The other shape.  
264    */    */
265    std::string    const
266    createShapeErrorMessage(const std::string& messagePrefix,    ShapeType&
267                            const DataArrayView::ShapeType& other) const;    getShape() const;
268    
269    /**    /**
270       \brief       \brief
271       Set the offset into the array.       Return true if the given shape is the same as this view's shape.
272    */    */
273    void    bool
274    setOffset(ValueType::size_type offset);    checkShape(const ShapeType& other) const;
275    
276    /**    /**
277       \brief       \brief
278       Return the shape of a data view following the slice specified.       Create a shape error message. Normally used when there is a shape
279         mismatch between this shape and the other shape.
280    
281       \param region - Input - Slice region.       \param messagePrefix - Input -
282                           First part of the error message.
283         \param other - Input -
284                           The other shape.
285    */    */
286    static DataArrayView::ShapeType    std::string
287    getResultSliceShape(const RegionType& region);    createShapeErrorMessage(const std::string& messagePrefix,
288                              const ShapeType& other) const;
289    
290    /**    /**
291       \brief       \brief
292       Copy a slice specified by the given region from the given view       Return the viewed data as a formatted string.
293       into this view.       Not recommended for very large objects!
      The given region must be the same shape as this view.  
294    
295       \param other - Input - view to copy from.       \param suffix - Input -
296       \param region - Input - region in other to copy.                         Suffix appended to index display.
297    */    */
298    void    std::string
299    copySlice(const DataArrayView& other,    toString(const std::string& suffix=std::string("")) const;
             const RegionType& region);  
300    
301    /**    /**
302       \brief       \brief
303       Copy a slice specified by the given region from the given view into this view.       Return the given shape as a string.
304       The given region must be the same shape as this view.       This is purely a utility method and has no bearing on this view.
305    
306       \param thisOffset - Input - use this offset into this object instead of the default.       \param shape - Input.
      \param other - Input - view to copy from.  
      \param otherOffset - Input - use this offset into the given object instead of the default.  
      \param region - Input - region in other to copy.  
307    */    */
308    void    static
309    copySlice(ValueType::size_type thisOffset,    std::string
310              const DataArrayView& other,    shapeToString(const ShapeType& shape);
             ValueType::size_type otherOffset,  
             const RegionType& region);  
   
  /**  
      \brief  
      Copy into a slice from the given view.  
      This view must have the same rank as the slice region.  
311    
312       \param other - Input - Data to copy from.    /**
313       \param region - Input - Slice region.      \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    */    */
318    void    ValueType::size_type
319    copySliceFrom(const DataArrayView& other,    relIndex() const;
                 const RegionType& region);  
320    
321    /**    /**
322       \brief      \brief
323       Copy into a slice from the given value.      Return the 1 dimensional index into the data array of the element at
324       This view must have the same rank as the slice region.      position i in the view, *ignoring the offset*.
325        Assumes a rank 1 view.
      \param thisOffset - Input - use this view offset instead of the default.  
      \param other - Input - Data to copy from.  
      \param otherOffset - Input - use this slice offset instead of the default.  
      \param region - Input - Slice region.  
326    */    */
327    void    ValueType::size_type
328    copySliceFrom(ValueType::size_type thisOffset,    relIndex(ValueType::size_type i) const;
                 const DataArrayView& other,  
                 ValueType::size_type otherOffset,  
                 const RegionType& region);  
329    
330    /**    /**
331       \brief      \brief
332       Determine the shape of the result array for a matrix multiplication.      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    */    */
336    static ShapeType    ValueType::size_type
337    determineResultShape(const DataArrayView& left,    relIndex(ValueType::size_type i,
338                         const DataArrayView& right);             ValueType::size_type j) const;
339    
340    /**    /**
341       \brief      \brief
342       Determine the region specified by the given python slice object.      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       \param key - Input - python slice object specifying region to be returned.      Assumes a rank 3 view.
   
      \description  
   
      The slice object is a tuple of n python slice specifiers, where  
      n <= the rank of this Data object. Each slice specifier specifies the  
      range of indexes to be sliced from the corresponding dimension. The  
      first specifier corresponds to the first dimension, the second to the  
      second and so on. Where n < the rank, the remaining dimensions are  
      sliced across the full range of their indicies.  
   
      Each slice specifier is of the form "a:b", which specifies a slice  
      from index a, up to but not including index b. Where index a is ommitted  
      a is assumed to be 0. Where index b is ommitted, b is assumed to be the  
      length of this dimension.  
   
      The return value is a vector of pairs with length equal to the rank of  
      this object. Each pair corresponds to the range of indexes from the  
      corresponding dimension to be sliced from, as specified in the input  
      slice object.  
   
      Examples:  
   
        For a rank 1 object of shape(5):  
   
          getSliceRegion(:)   => < <0,5> >  
          getSliceRegion(2:3) => < <2,3> >  
          getSliceRegion(:3)  => < <0,3> >  
          getSliceRegion(2:)  => < <2,5> >  
   
        For a rank 3 object of shape (2,4,6):  
   
          getSliceRegion(0:2,0:4,0:6) => < <0,2> <0,4> <0,6> >  
          getSliceRegion(:,:,:)       => < <0,2> <0,4> <0,6> >  
          getSliceRegion(0:1)         => < <0,1> <0,4> <0,6> >  
          getSliceRegion(:1,0:2)      => < <0,1> <0,2> <0,6> >  
345    */    */
346    DataArrayView::RegionType    ValueType::size_type
347    getSliceRegion(const boost::python::object& key) const;    relIndex(ValueType::size_type i,
348               ValueType::size_type j,
349    // *******************************************************************             ValueType::size_type k) const;
   // NOTE: The following relIndex functions are a hack. The indexing  
   // mechanism should be split out from DataArrayView to get the flexability  
   // needed.  
350    
351    /**    /**
352      \brief      \brief
353      Return the 1 dimensional index of the element at position i,j,k,m      Return the 1 dimensional index into the data array of the element at
354      ignoring the offset.      position i,j,k,m in the view, *ignoring the offset*.
355        Assumes a rank 4 view.
356    */    */
357    ValueType::size_type    ValueType::size_type
358    relIndex(ValueType::size_type i,    relIndex(ValueType::size_type i,
# Line 356  class DataArrayView { Line 362  class DataArrayView {
362    
363    /**    /**
364      \brief      \brief
365      Return the 1 dimensional index of the element at position i,j,k      Return the 1 dimensional index into the data array of the only element
366      ignoring the offset.      in the view.
367        Assumes a rank 0 view.
368    */    */
369    ValueType::size_type    ValueType::size_type
370    relIndex(ValueType::size_type i,    index() const;
            ValueType::size_type j,  
            ValueType::size_type k) const;  
371    
372    /**    /**
373      \brief      \brief
374      Return the 1 dimensional index of the element at position i,j      Return the 1 dimensional index into the data array of the element at
375      ignoring the offset.      position i in the view.
376        Assumes a rank 1 view.
377    */    */
378    ValueType::size_type    ValueType::size_type
379    relIndex(ValueType::size_type i,    index(ValueType::size_type i) const;
            ValueType::size_type j) const;  
   
   // ********************************************************************  
380    
381    /**    /**
382      \brief      \brief
383      Return the 1 dimensional index of the element at position i,j,k,m.      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    */    */
387    ValueType::size_type    ValueType::size_type
388    index(ValueType::size_type i,    index(ValueType::size_type i,
389          ValueType::size_type j,          ValueType::size_type j) const;
         ValueType::size_type k,  
         ValueType::size_type m) const;  
390    
391    /**    /**
392      \brief      \brief
393      Return the 1 dimensional index of the element at position i,j,k.      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    */    */
397    ValueType::size_type    ValueType::size_type
398    index(ValueType::size_type i,    index(ValueType::size_type i,
# Line 396  class DataArrayView { Line 401  class DataArrayView {
401    
402    /**    /**
403      \brief      \brief
404      Return the 1 dimensional index of the element at position i,j.      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    */    */
408    ValueType::size_type    ValueType::size_type
409    index(ValueType::size_type i,    index(ValueType::size_type i,
410          ValueType::size_type j) const;          ValueType::size_type j,
411            ValueType::size_type k,
412            ValueType::size_type m) const;
413    
414    /**    /**
415      \brief      \brief
416      Return the 1 dimensional index of the element at position i.      Return a reference for the only element in the view.
417        Assumes a rank 0 view.
418    */    */
419    ValueType::size_type    ValueType::reference
420    index(ValueType::size_type i) const;    operator()();
421    
422      ValueType::const_reference
423      operator()() const;
424    
425    /**    /**
426      \brief      \brief
427      Return a reference to the element at position i.      Return a reference to the element at position i in the view.
428        Assumes a rank 1 view.
429    */    */
430    ValueType::reference    ValueType::reference
431    operator()(ValueType::size_type i);    operator()(ValueType::size_type i);
# Line 421  class DataArrayView { Line 435  class DataArrayView {
435    
436    /**    /**
437      \brief      \brief
438      Return a reference to the element at position i,j.      Return a reference to the element at position i,j in the view.
439        Assumes a rank 2 view.
440    */    */
441    ValueType::reference    ValueType::reference
442    operator()(ValueType::size_type i,    operator()(ValueType::size_type i,
# Line 433  class DataArrayView { Line 448  class DataArrayView {
448    
449    /**    /**
450      \brief      \brief
451      Return a reference to the element at position i,j,k.      Return a reference to the element at position i,j,k in the view.
452        Assumes a rank 3 view.
453    */    */
454    ValueType::reference    ValueType::reference
455    operator()(ValueType::size_type i,    operator()(ValueType::size_type i,
# Line 447  class DataArrayView { Line 463  class DataArrayView {
463    
464   /**   /**
465      \brief      \brief
466      Return a reference to the element at position i,j,k,m.      Return a reference to the element at position i,j,k,m in the view.
467        Assumes a rank 4 view.
468    */    */
469    ValueType::reference    ValueType::reference
470    operator()(ValueType::size_type i,    operator()(ValueType::size_type i,
# Line 462  class DataArrayView { Line 479  class DataArrayView {
479               ValueType::size_type m) const;               ValueType::size_type m) const;
480    
481    /**    /**
482      \brief       \brief
483      Return a reference for the only element, assuming rank 0.       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    */    */
489    ValueType::reference    static
490    operator()();    ShapeType
491      getResultSliceShape(const RegionType& region);
492    
493    ValueType::const_reference    /**
494    operator()() const;       \brief
495         Determine the region specified by the given python slice object.
496    
497         \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      RegionType
550      getSliceRegion(const boost::python::object& key) const;
551    
552    /**    /**
553       \brief       \brief
554       Perform the unary operation using the given offset       Copy a data slice specified by the given region from the given view
555       instead of the offset defined within the view.       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    */    */
   template <class UnaryFunction>  
562    void    void
563    unaryOp(ValueType::size_type leftOffset,    copySlice(const DataArrayView& other,
564            UnaryFunction operation);              const RegionLoopRangeType& region);
565    
566    /**    /**
567       \brief       \brief
568       Perform the unary operation using the view's offset.       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    */    */
   template <class UnaryFunction>  
580    void    void
581    unaryOp(UnaryFunction operation);    copySlice(ValueType::size_type thisOffset,
582                const DataArrayView& other,
583                ValueType::size_type otherOffset,
584                const RegionLoopRangeType& region);
585    
586    /**    /**
587       \brief       \brief
588       Perform the given data point reduction operation on the data point       Copy data into a slice specified by the given region in this view from
589       specified by the given offset into the view. Reduces all elements of       the given view, using the default offsets in both views.
      the data point using the given operation, returning the result as a  
      scalar.  
590    
591       Called by escript::dp_algorithm.       \param other - Input -
592                      View to copy data from.
593         \param region - Input -
594                      Region in this view to copy data to.
595    */    */
596    template <class UnaryFunction>    void
597    double    copySliceFrom(const DataArrayView& other,
598    dp_algorithm(ValueType::size_type leftOffset,                  const RegionLoopRangeType& region);
                UnaryFunction operation);  
599    
600    /**    /**
601       \brief       \brief
602       Perform the given data point reduction operation on the data point       Copy data into a slice specified by the given region and offset in
603       specified by the default offset into the view. Reduces all elements of       this view from the given view at the given offset.
      the data point using the given operation, returning the result as a  
      scalar.  
604    
605       Called by escript::dp_algorithm.       \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    */    */
614    template <class UnaryFunction>    void
615    double    copySliceFrom(ValueType::size_type thisOffset,
616    dp_algorithm(UnaryFunction operation);                  const DataArrayView& other,
617                    ValueType::size_type otherOffset,
618                    const RegionLoopRangeType& region);
619    
620    /**    /**
621       \brief       \brief
622       Perform the given operation and return a result.       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    */    */
631    template <class UnaryFunction>    template <class UnaryFunction>
632    double    void
633    algorithm(ValueType::size_type leftOffset,    unaryOp(UnaryFunction operation);
             UnaryFunction operation) const;  
634    
635    /**    /**
636       \brief       \brief
637       Perform the given operation and return a result. Use the default offset.       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    */    */
648    template <class UnaryFunction>    template <class UnaryFunction>
649    double    void
650    algorithm(UnaryFunction operation) const;    unaryOp(ValueType::size_type offset,
651              UnaryFunction operation);
652    
653    /**    /**
654       \brief       \brief
655       Perform the binary operation. Version which applies a double value       Perform the binary operation on the data points specified by the default
656       to all values within the view. The given offset is used instead of       offsets in this view and in view "right". Applies the specified operation
657       the default offset specified within the view.       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    */    */
667    template <class BinaryFunction>    template <class BinaryFunction>
668    void    void
669    binaryOp(ValueType::size_type leftOffset,    binaryOp(const DataArrayView& right,
            double right,  
670             BinaryFunction operation);             BinaryFunction operation);
671    
672    /**    /**
673       \brief       \brief
674       Perform the binary operation. Version which applies a double value       Perform the binary operation on the data points specified by the given
675       to all values within the view.       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    */    */
690    template <class BinaryFunction>    template <class BinaryFunction>
691    void    void
692    binaryOp(double right,    binaryOp(ValueType::size_type leftOffset,
693               const DataArrayView& right,
694               ValueType::size_type rightOffset,
695             BinaryFunction operation);             BinaryFunction operation);
696    
697    /**    /**
698       \brief       \brief
699       Perform the binary operation. The given offsets override the default       Perform the binary operation on the data point specified by the default
700       offsets specified within the views.       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    */    */
711    template <class BinaryFunction>    template <class BinaryFunction>
712    void    void
713    binaryOp(ValueType::size_type leftOffset,    binaryOp(double right,
            const DataArrayView& right,  
            ValueType::size_type rightOffset,  
714             BinaryFunction operation);             BinaryFunction operation);
715    
716    /**    /**
717       \brief       \brief
718       Perform the binary operation.       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    */    */
732    template <class BinaryFunction>    template <class BinaryFunction>
733    void    void
734    binaryOp(const DataArrayView& right,    binaryOp(ValueType::size_type offset,
735               double right,
736             BinaryFunction operation);             BinaryFunction operation);
737    
738    /**    /**
739       \brief       \brief
740       Return the data as a string. Not recommended for very large objects.       Perform the given data point reduction operation on the data point
741       \param suffix - Input - Suffix appended to index display.       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    std::string    template <class UnaryFunction>
751    toString(const std::string& suffix=std::string("")) const;    double
752      reductionOp(UnaryFunction operation) const;
753    
754    /**    /**
755       \brief       \brief
756       Return the given shape as a string.       Perform the given data point reduction operation on the data point
757         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       \param shape - Input.       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    static std::string    template <class UnaryFunction>
769    shapeToString(const DataArrayView::ShapeType& shape);    double
770      reductionOp(ValueType::size_type offset,
771                  UnaryFunction operation) const;
772    
773    /**    /**
774       \brief       \brief
775       Perform matrix multiply.       Perform a matrix multiply of the given views.
776         This is purely a utility method and has no bearing on this view.
      Description:  
      Perform matrix multiply.  
777    
778       \param left - Input - The left hand side.       \param left - Input - The left hand side.
779       \param right - Input - The right hand side.       \param right - Input - The right hand side.
780       \param result - Output - The result of the operation.       \param result - Output - The result of the operation.
781    */    */
782    static void    static
783      void
784    matMult(const DataArrayView& left,    matMult(const DataArrayView& left,
785            const DataArrayView& right,            const DataArrayView& right,
786            DataArrayView& result);            DataArrayView& result);
787    
788      /**
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      static
795      ShapeType
796      determineResultShape(const DataArrayView& left,
797                           const DataArrayView& right);
798    
799   protected:   protected:
800    
801   private:   private:
802    
803    //    //
804      // The maximum rank allowed for the shape of any view.
805    static const int m_maxRank=4;    static const int m_maxRank=4;
806    
807    //    //
808    // The data values for the view. NOTE: This points to data external to the view.    // The data values for the view.
809      // NOTE: This points to data external to the view.
810      // This is just a pointer to an array of ValueType.
811    ValueType* m_data;    ValueType* m_data;
812    
813    //    //
814    // The offset into the data array used by different views.    // The offset into the data array used by different views.
815      // This is simply an integer specifying a position in the data array
816      // pointed to by m_data.
817    ValueType::size_type m_offset;    ValueType::size_type m_offset;
818    
819    //    //
820    // The shape of the data.    // The shape of the data.
821      // This is simply an STL vector specifying the lengths of each dimension
822      // of the shape as ints.
823    ShapeType m_shape;    ShapeType m_shape;
824    
825    //    //
826    // The number of values needed for the array.    // The number of values needed for the array.
827      // This can be derived from m_shape by multiplying the size of each dimension, but
828      // is stored here for convenience.
829    int m_noValues;    int m_noValues;
830    
831  };  };
832    
833    bool operator==(const DataArrayView& left, const DataArrayView& right);
834    bool operator!=(const DataArrayView& left, const DataArrayView& right);
835    
836    /**
837      \brief
838       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    \brief
853    Calculate the slice range from the given python key object    Calculate the slice range from the given python key object
# Line 648  std::pair<int,int> Line 862  std::pair<int,int>
862  getSliceRange(const boost::python::object& key,  getSliceRange(const boost::python::object& key,
863                const int shape);                const int shape);
864    
865  inline  /**
866  DataArrayView::ValueType::size_type     Inline function definitions.
867  DataArrayView::getOffset() const  */
 {  
   return m_offset;  
 }  
   
 inline  
 DataArrayView::ValueType&  
 DataArrayView::getData() const  
 {  
   EsysAssert(!isEmpty(),"Error - View is empty");  
   return *m_data;  
 }  
868    
869    template <class UnaryFunction>
870  inline  inline
871  DataArrayView::ValueType::reference  void
872  DataArrayView::getData(ValueType::size_type i) const  DataArrayView::unaryOp(UnaryFunction operation)
873  {  {
874    //    unaryOp(m_offset,operation);
   // don't do any checking to allow one past the end of the vector providing  
   // the equivalent of end()  
   return (*m_data)[i+m_offset];  
875  }  }
876    
877  template <class UnaryFunction>  template <class UnaryFunction>
878  inline  inline
879  void  void
880  DataArrayView::unaryOp(ValueType::size_type leftOffset,  DataArrayView::unaryOp(ValueType::size_type offset,
881                         UnaryFunction operation)                         UnaryFunction operation)
882  {  {
883    for (ValueType::size_type i=0;i<(noValues(m_shape));i++) {    EsysAssert((!isEmpty()&&checkOffset(offset)),
884      (*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset]);                 "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  }  }
889    
890  template <class UnaryFunction>  template <class BinaryFunction>
891  inline  inline
892  void  void
893  DataArrayView::unaryOp(UnaryFunction operation)  DataArrayView::binaryOp(const DataArrayView& right,
894                            BinaryFunction operation)
895  {  {
896    unaryOp(m_offset,operation);    binaryOp(m_offset,right,right.getOffset(),operation);
897  }  }
898    
899  template <class UnaryFunction>  template <class BinaryFunction>
900  inline  inline
901  double  void
902  DataArrayView::dp_algorithm(ValueType::size_type leftOffset,  DataArrayView::binaryOp(ValueType::size_type leftOffset,
903                              UnaryFunction operation)                          const DataArrayView& right,
904                            ValueType::size_type rightOffset,
905                            BinaryFunction operation)
906  {  {
907    operation.resetResult();    EsysAssert(getShape()==right.getShape(),
908    for (ValueType::size_type i=0;i<(noValues(m_shape));i++) {           "Error - Couldn't perform binaryOp due to shape mismatch,");
909      operation((*m_data)[i+leftOffset]);    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    }    }
   return operation.getResult();  
916  }  }
917    
918  template <class UnaryFunction>  template <class BinaryFunction>
919  inline  inline
920  double  void
921  DataArrayView::dp_algorithm(UnaryFunction operation)  DataArrayView::binaryOp(double right,
922                            BinaryFunction operation)
923  {  {
924    return dp_algorithm(m_offset,operation);    binaryOp(m_offset,right,operation);
925  }  }
926    
927  template <class UnaryFunction>  template <class BinaryFunction>
928  inline  inline
929  double  void
930  DataArrayView::algorithm(ValueType::size_type leftOffset,  DataArrayView::binaryOp(ValueType::size_type offset,
931                           UnaryFunction operation) const                          double right,
932                            BinaryFunction operation)
933  {  {
934    for (ValueType::size_type i=0;i<(noValues(m_shape));++i) {    EsysAssert((!isEmpty()&&checkOffset(offset)),
935      operation((*m_data)[i+leftOffset]);               "Error - Couldn't perform binaryOp due to insufficient storage in left object.");
936      for (ValueType::size_type i=0;i<noValues();i++) {
937        (*m_data)[offset+i]=operation((*m_data)[offset+i],right);
938    }    }
   return operation.getResult();  
939  }  }
940    
941  template <class UnaryFunction>  template <class UnaryFunction>
942  inline  inline
943  double  double
944  DataArrayView::algorithm(UnaryFunction operation) const  DataArrayView::reductionOp(UnaryFunction operation) const
945  {  {
946    return algorithm(m_offset,operation);    return reductionOp(m_offset,operation);
947  }  }
948    
949  template <class BinaryFunction>  template <class UnaryFunction>
950  inline  inline
951  void  double
952  DataArrayView::binaryOp(ValueType::size_type leftOffset,  DataArrayView::reductionOp(ValueType::size_type offset,
953                          const DataArrayView& right,                             UnaryFunction operation) const
                         ValueType::size_type rightOffset,  
                         BinaryFunction operation)  
954  {  {
955    EsysAssert(getShape()==right.getShape(),    EsysAssert((!isEmpty()&&checkOffset(offset)),
956           "Error - Right hand shape: " << shapeToString(right.getShape()) << " doesn't match the left: " << shapeToString(getShape()));                 "Error - Couldn't perform reductionOp due to insufficient storage.");
957    for (ValueType::size_type i=0;i<noValues();++i) {    operation.resetResult();
958      (*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset],(*right.m_data)[i+rightOffset]);    for (ValueType::size_type i=0;i<noValues();i++) {
959        operation((*m_data)[offset+i]);
960    }    }
961      return operation.getResult();
962  }  }
963    
 template <class BinaryFunction>  
964  inline  inline
965  void  DataArrayView::ValueType::size_type
966  DataArrayView::binaryOp(const DataArrayView& right,  DataArrayView::relIndex() const
                         BinaryFunction operation)  
967  {  {
968    //    EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
969    // version using the offsets specified within the view    return 0;
   binaryOp(m_offset,right,right.getOffset(),operation);  
970  }  }
971    
 template <class BinaryFunction>  
972  inline  inline
973  void  DataArrayView::ValueType::size_type
974  DataArrayView::binaryOp(ValueType::size_type leftOffset,  DataArrayView::index() const
                         double right,  
                         BinaryFunction operation)  
975  {  {
976    //    EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
977    // If a scalar is to be applied to the entire array force the caller to    return (m_offset);
   // explicitly specify a single value  
   for (ValueType::size_type i=0;i<(noValues(m_shape));++i) {  
     (*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset],right);  
   }  
978  }  }
979    
 template <class BinaryFunction>  
980  inline  inline
981  void  DataArrayView::ValueType::size_type
982  DataArrayView::binaryOp(double right,  DataArrayView::relIndex(ValueType::size_type i) const
                         BinaryFunction operation)  
983  {  {
984    //    EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
985    // use the default offset    EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
986    binaryOp(m_offset,right,operation);    return i;
987  }  }
988    
989  inline  inline
990  DataArrayView::ValueType::size_type  DataArrayView::ValueType::size_type
991  DataArrayView::index(ValueType::size_type i) const  DataArrayView::index(ValueType::size_type i) const
992  {  {
993      //EsysAssert((i >= 0) && (i < noValues(m_shape)), "Invalid index.");    EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
994      EsysAssert((i < noValues(m_shape)), "Invalid index.");    EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
995      return (i+m_offset);    return (m_offset+i);
996  }  }
997    
998  inline  inline
# Line 799  DataArrayView::ValueType::size_type Line 1000  DataArrayView::ValueType::size_type
1000  DataArrayView::relIndex(ValueType::size_type i,  DataArrayView::relIndex(ValueType::size_type i,
1001                          ValueType::size_type j) const                          ValueType::size_type j) const
1002  {  {
1003      EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1004    ValueType::size_type temp=i+j*m_shape[0];    ValueType::size_type temp=i+j*m_shape[0];
1005    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
   EsysAssert((temp < noValues(m_shape)), "Invalid index.");  
   //  
   // no offset  
1006    return temp;    return temp;
1007  }  }
1008    
# Line 812  DataArrayView::ValueType::size_type Line 1011  DataArrayView::ValueType::size_type
1011  DataArrayView::index(ValueType::size_type i,  DataArrayView::index(ValueType::size_type i,
1012               ValueType::size_type j) const               ValueType::size_type j) const
1013  {  {
1014      EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1015    ValueType::size_type temp=i+j*m_shape[0];    ValueType::size_type temp=i+j*m_shape[0];
1016    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1017    EsysAssert((temp < noValues(m_shape)), "Invalid index.");    return (m_offset+temp);
   return (temp+m_offset);  
1018  }  }
1019    
1020  inline  inline
# Line 824  DataArrayView::relIndex(ValueType::size_ Line 1023  DataArrayView::relIndex(ValueType::size_
1023              ValueType::size_type j,              ValueType::size_type j,
1024              ValueType::size_type k) const              ValueType::size_type k) const
1025  {  {
1026      ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];    EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1027      //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1028      EsysAssert((temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1029      //    return temp;
     // no offset  
     return temp;  
1030  }  }
1031    
1032  inline  inline
# Line 838  DataArrayView::index(ValueType::size_typ Line 1035  DataArrayView::index(ValueType::size_typ
1035               ValueType::size_type j,               ValueType::size_type j,
1036               ValueType::size_type k) const               ValueType::size_type k) const
1037  {  {
1038      ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];    EsysAssert((getRank()==3),"Incorrect number of indices for the rank of this object.");
1039      //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    ValueType::size_type temp=i+j*m_shape[0]+k*m_shape[1]*m_shape[0];
1040      EsysAssert((temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1041      return (temp+m_offset);    return (m_offset+temp);
1042  }  }
1043    
1044  inline  inline
# Line 851  DataArrayView::relIndex(ValueType::size_ Line 1048  DataArrayView::relIndex(ValueType::size_
1048                          ValueType::size_type k,                          ValueType::size_type k,
1049                          ValueType::size_type m) const                          ValueType::size_type m) const
1050  {  {
1051      EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1052    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];    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    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
   EsysAssert((temp < noValues(m_shape)), "Invalid index.");  
   //  
   // no offset  
1054    return temp;    return temp;
1055  }  }
1056    
# Line 866  DataArrayView::index(ValueType::size_typ Line 1061  DataArrayView::index(ValueType::size_typ
1061               ValueType::size_type k,               ValueType::size_type k,
1062               ValueType::size_type m) const               ValueType::size_type m) const
1063  {  {
1064      EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1065    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];    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    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1067    EsysAssert((temp < noValues(m_shape)), "Invalid index.");    return (m_offset+temp);
   return (temp+m_offset);  
1068  }  }
1069    
1070  inline  inline
1071  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1072  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()()
                           ValueType::size_type j,  
                           ValueType::size_type k,  
                           ValueType::size_type m)  
1073  {  {
1074      EsysAssert((getRank()==4),    return (*m_data)[index()];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i,j,k,m)];  
1075  }  }
1076    
1077  inline  inline
1078  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1079  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()() const
                           ValueType::size_type j,  
                           ValueType::size_type k,  
                           ValueType::size_type m) const  
1080  {  {
1081      EsysAssert((getRank()==4),    return (*m_data)[index()];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i,j,k,m)];  
1082  }  }
1083    
1084  inline  inline
1085  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1086  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i)
                           ValueType::size_type j,  
                           ValueType::size_type k)  
1087  {  {
1088      EsysAssert((getRank()==3),    return (*m_data)[index(i)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i,j,k)];  
1089  }  }
1090    
1091  inline  inline
1092  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1093  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i) const
                           ValueType::size_type j,  
                           ValueType::size_type k) const  
1094  {  {
1095      EsysAssert((getRank()==3),    return (*m_data)[index(i)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i,j,k)];  
1096  }  }
1097    
1098  inline  inline
# Line 923  DataArrayView::ValueType::reference Line 1100  DataArrayView::ValueType::reference
1100  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i,
1101                            ValueType::size_type j)                            ValueType::size_type j)
1102  {  {
1103      EsysAssert((getRank()==2),    return (*m_data)[index(i,j)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i,j)];  
1104  }  }
1105    
1106  inline  inline
# Line 933  DataArrayView::ValueType::const_referenc Line 1108  DataArrayView::ValueType::const_referenc
1108  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i,
1109                            ValueType::size_type j) const                            ValueType::size_type j) const
1110  {  {
1111      EsysAssert((getRank()==2),    return (*m_data)[index(i,j)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i,j)];  
1112  }  }
1113    
1114  inline  inline
1115  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1116  DataArrayView::operator()(ValueType::size_type i)  DataArrayView::operator()(ValueType::size_type i,
1117                              ValueType::size_type j,
1118                              ValueType::size_type k)
1119  {  {
1120      EsysAssert((getRank()==1),    return (*m_data)[index(i,j,k)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i)];  
1121  }  }
1122    
1123  inline  inline
1124  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1125  DataArrayView::operator()(ValueType::size_type i) const  DataArrayView::operator()(ValueType::size_type i,
1126                              ValueType::size_type j,
1127                              ValueType::size_type k) const
1128  {  {
1129      EsysAssert((getRank()==1),    return (*m_data)[index(i,j,k)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[index(i)];  
1130  }  }
1131    
1132  inline  inline
1133  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1134  DataArrayView::operator()()  DataArrayView::operator()(ValueType::size_type i,
1135                              ValueType::size_type j,
1136                              ValueType::size_type k,
1137                              ValueType::size_type m)
1138  {  {
1139      EsysAssert((getRank()==0),    return (*m_data)[index(i,j,k,m)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[m_offset];  
1140  }  }
1141    
1142  inline  inline
1143  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1144  DataArrayView::operator()() const  DataArrayView::operator()(ValueType::size_type i,
1145                              ValueType::size_type j,
1146                              ValueType::size_type k,
1147                              ValueType::size_type m) const
1148  {  {
1149      EsysAssert((getRank()==0),    return (*m_data)[index(i,j,k,m)];
            "Incorrect number of indices for the rank of this object.");  
     return (*m_data)[m_offset];  
1150  }  }
1151    
 bool operator==(const DataArrayView& left, const DataArrayView& right);  
 bool operator!=(const DataArrayView& left, const DataArrayView& right);  
   
1152  } // end of namespace  } // end of namespace
1153    
1154  #endif  #endif

Legend:
Removed from v.106  
changed lines
  Added in v.117

  ViewVC Help
Powered by ViewVC 1.1.26