/[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

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

Legend:
Removed from v.100  
changed lines
  Added in v.155

  ViewVC Help
Powered by ViewVC 1.1.26