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

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

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

  ViewVC Help
Powered by ViewVC 1.1.26