/[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 100 by jgs, Wed Dec 15 03:48:48 2004 UTC revision 126 by jgs, Fri Jul 22 03:53:08 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);
             UnaryFunction operation) const;  
597    
598    /**    /**
599       \brief       \brief
600       Perform the given operation and return a result. Use the default offset.       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
620         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    static std::string    template <class UnaryFunction>
749    shapeToString(const DataArrayView::ShapeType& shape);    double
750      reductionOp(UnaryFunction operation) const;
751    
752    /**    /**
753       \brief       \brief
754       Perform matrix multiply.       Perform the given data point reduction operation on the data point
755         specified by the given offset into the view. Reduces all elements of
756         the data point using the given operation, returning the result as a
757         scalar. Operation must be a pointer to a function.
758    
759       Description:       Called by escript::algorithm.
760       Perform matrix multiply.  
761         \param offset - Input -
762                      Apply the operation to data starting at this offset in this view.
763         \param operation - Input -
764                      Operation to apply. Must be a pointer to a function.
765      */
766      template <class UnaryFunction>
767      double
768      reductionOp(ValueType::size_type offset,
769                  UnaryFunction operation) const;
770    
771      /**
772         \brief
773         Perform a matrix multiply of the given views.
774         This is purely a utility method and has no bearing on this view.
775    
776         NB: Only multiplies together the two given views, ie: two data-points,
777         would need to call this over all data-points to multiply the entire
778         Data objects involved.
779    
780       \param left - Input - The left hand side.       \param left - Input - The left hand side.
781       \param right - Input - The right hand side.       \param right - Input - The right hand side.
782       \param result - Output - The result of the operation.       \param result - Output - The result of the operation.
783    */    */
784    static void    static
785      void
786    matMult(const DataArrayView& left,    matMult(const DataArrayView& left,
787            const DataArrayView& right,            const DataArrayView& right,
788            DataArrayView& result);            DataArrayView& result);
789    
790      /**
791         \brief
792         Determine the shape of the result array for a matrix multiplication
793         of the given views.
794         This is purely a utility method and has no bearing on this view.
795      */
796      static
797      ShapeType
798      determineResultShape(const DataArrayView& left,
799                           const DataArrayView& right);
800    
801   protected:   protected:
802    
803   private:   private:
804    
805    //    //
806      // The maximum rank allowed for the shape of any view.
807    static const int m_maxRank=4;    static const int m_maxRank=4;
808    
809    //    //
810    // The data values for the view. NOTE: This points to data external to the view.    // The data values for the view.
811      // NOTE: This points to data external to the view.
812      // This is just a pointer to an array of ValueType.
813    ValueType* m_data;    ValueType* m_data;
814    
815    //    //
816    // The offset into the data array used by different views.    // The offset into the data array used by different views.
817      // This is simply an integer specifying a position in the data array
818      // pointed to by m_data.
819    ValueType::size_type m_offset;    ValueType::size_type m_offset;
820    
821    //    //
822    // The shape of the data.    // The shape of the data.
823      // This is simply an STL vector specifying the lengths of each dimension
824      // of the shape as ints.
825    ShapeType m_shape;    ShapeType m_shape;
826    
827    //    //
828    // The number of values needed for the array.    // The number of values needed for the array.
829      // This can be derived from m_shape by multiplying the size of each dimension, but
830      // is stored here for convenience.
831    int m_noValues;    int m_noValues;
832    
833  };  };
834    
835  inline  bool operator==(const DataArrayView& left, const DataArrayView& right);
836  DataArrayView::ValueType::size_type  bool operator!=(const DataArrayView& left, const DataArrayView& right);
 DataArrayView::getOffset() const  
 {  
   return m_offset;  
 }  
837    
838  inline  /**
839  DataArrayView::ValueType&    \brief
840  DataArrayView::getData() const     Modify region to copy from in order to
841  {     deal with the case where one range in the region contains identical indexes,
842    EsysAssert(!isEmpty(),"Error - View is empty");     eg: <<1,1><0,3><0,3>>
843    return *m_data;     This situation implies we want to copy from an object with rank greater than that of this
844  }     object. eg: we want to copy the values from a two dimensional slice out of a three
845       dimensional object into a two dimensional object.
846       We do this by taking a slice from the other object where one dimension of
847       the slice region is of size 1. So in the above example, we modify the above
848       region like so: <<1,2><0,3><0,3>> and take this slice.
849    */
850    DataArrayView::RegionLoopRangeType
851    getSliceRegionLoopRange(const DataArrayView::RegionType& region);
852    
853  inline  /**
854  DataArrayView::ValueType::reference    \brief
855  DataArrayView::getData(ValueType::size_type i) const    Calculate the slice range from the given python key object
856  {    Used by DataArrayView::getSliceRegion.
857    //    Returns the python slice object key as a pair of ints where the first
858    // 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
859    // the equivalent of end()    step attribute with value different from one will throw an exception
   return (*m_data)[i+m_offset];  
 }  
860    
861  template <class UnaryFunction>    /param key - Input - key object specifying slice range.
862  inline  */
863  void  std::pair<int,int>
864  DataArrayView::unaryOp(ValueType::size_type leftOffset,  getSliceRange(const boost::python::object& key,
865                         UnaryFunction operation)                const int shape);
866  {  
867    for (ValueType::size_type i=0;i<(noValues(m_shape));++i) {  /**
868      (*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset]);     Inline function definitions.
869    }  */
 }  
870    
871  template <class UnaryFunction>  template <class UnaryFunction>
872  inline  inline
# Line 613  DataArrayView::unaryOp(UnaryFunction ope Line 878  DataArrayView::unaryOp(UnaryFunction ope
878    
879  template <class UnaryFunction>  template <class UnaryFunction>
880  inline  inline
881  double  void
882  DataArrayView::algorithm(ValueType::size_type leftOffset,  DataArrayView::unaryOp(ValueType::size_type offset,
883                           UnaryFunction operation) const                         UnaryFunction operation)
884  {  {
885    for (ValueType::size_type i=0;i<(noValues(m_shape));++i) {    EsysAssert((!isEmpty()&&checkOffset(offset)),
886      operation((*m_data)[i+leftOffset]);                 "Error - Couldn't perform unaryOp due to insufficient storage.");
887      for (ValueType::size_type i=0;i<noValues();i++) {
888        (*m_data)[offset+i]=operation((*m_data)[offset+i]);
889    }    }
   return operation.getResult();  
890  }  }
891    
892  template <class UnaryFunction>  template <class BinaryFunction>
893  inline  inline
894  double  void
895  DataArrayView::algorithm(UnaryFunction operation) const  DataArrayView::binaryOp(const DataArrayView& right,
896                            BinaryFunction operation)
897  {  {
898    return algorithm(m_offset,operation);    binaryOp(m_offset,right,right.getOffset(),operation);
899  }  }
900    
901  template <class BinaryFunction>  template <class BinaryFunction>
902  inline  inline
903  void  void
904  DataArrayView::binaryOp(ValueType::size_type leftOffset,  DataArrayView::binaryOp(ValueType::size_type leftOffset,
905                          const DataArrayView& right,                          const DataArrayView& right,
906                          ValueType::size_type rightOffset,                          ValueType::size_type rightOffset,
907                          BinaryFunction operation)                          BinaryFunction operation)
908  {  {
909    EsysAssert(getShape()==right.getShape(),    EsysAssert(getShape()==right.getShape(),
910           "Error - Right hand shape: " << shapeToString(right.getShape()) << " doesn't match the left: " << shapeToString(getShape()));           "Error - Couldn't perform binaryOp due to shape mismatch,");
911    for (ValueType::size_type i=0;i<noValues();++i) {    EsysAssert((!isEmpty()&&checkOffset(leftOffset)),
912      (*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.");
913      EsysAssert((!right.isEmpty()&&right.checkOffset(rightOffset)),
914                 "Error - Couldn't perform binaryOp due to insufficient storage in right object.");
915      for (ValueType::size_type i=0;i<noValues();i++) {
916        (*m_data)[leftOffset+i]=operation((*m_data)[leftOffset+i],(*right.m_data)[rightOffset+i]);
917    }    }
918  }  }
919    
920  template <class BinaryFunction>  template <class BinaryFunction>
921  inline  inline
922  void  void
923  DataArrayView::binaryOp(const DataArrayView& right,  DataArrayView::binaryOp(double right,
924                          BinaryFunction operation)                          BinaryFunction operation)
925  {  {
926    //    binaryOp(m_offset,right,operation);
   // version using the offsets specified within the view  
   binaryOp(m_offset,right,right.getOffset(),operation);  
927  }  }
928    
929  template <class BinaryFunction>  template <class BinaryFunction>
930  inline  inline
931  void  void
932  DataArrayView::binaryOp(ValueType::size_type leftOffset,  DataArrayView::binaryOp(ValueType::size_type offset,
933                          double right,                          double right,
934                          BinaryFunction operation)                          BinaryFunction operation)
935  {  {
936    //    EsysAssert((!isEmpty()&&checkOffset(offset)),
937    // 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.");
938    // explicitly specify a single value    for (ValueType::size_type i=0;i<noValues();i++) {
939    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);  
940    }    }
941  }  }
942    
943  template <class BinaryFunction>  template <class UnaryFunction>
944  inline  inline
945  void  double
946  DataArrayView::binaryOp(double right,  DataArrayView::reductionOp(UnaryFunction operation) const
                         BinaryFunction operation)  
947  {  {
948    //    return reductionOp(m_offset,operation);
949    // use the default offset  }
950    binaryOp(m_offset,right,operation);  
951    template <class UnaryFunction>
952    inline
953    double
954    DataArrayView::reductionOp(ValueType::size_type offset,
955                               UnaryFunction operation) const
956    {
957      EsysAssert((!isEmpty()&&checkOffset(offset)),
958                   "Error - Couldn't perform reductionOp due to insufficient storage.");
959      operation.resetResult();
960      for (ValueType::size_type i=0;i<noValues();i++) {
961        operation((*m_data)[offset+i]);
962      }
963      return operation.getResult();
964    }
965    
966    inline
967    DataArrayView::ValueType::size_type
968    DataArrayView::relIndex() const
969    {
970      EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
971      return 0;
972    }
973    
974    inline
975    DataArrayView::ValueType::size_type
976    DataArrayView::index() const
977    {
978      EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
979      return (m_offset);
980    }
981    
982    inline
983    DataArrayView::ValueType::size_type
984    DataArrayView::relIndex(ValueType::size_type i) const
985    {
986      EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
987      EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
988      return i;
989  }  }
990    
991  inline  inline
992  DataArrayView::ValueType::size_type  DataArrayView::ValueType::size_type
993  DataArrayView::index(ValueType::size_type i) const  DataArrayView::index(ValueType::size_type i) const
994  {  {
995      //EsysAssert((i >= 0) && (i < noValues(m_shape)), "Invalid index.");    EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
996      EsysAssert((i < noValues(m_shape)), "Invalid index.");    EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
997      return (i+m_offset);    return (m_offset+i);
998  }  }
999    
1000  inline  inline
# Line 697  DataArrayView::ValueType::size_type Line 1002  DataArrayView::ValueType::size_type
1002  DataArrayView::relIndex(ValueType::size_type i,  DataArrayView::relIndex(ValueType::size_type i,
1003                          ValueType::size_type j) const                          ValueType::size_type j) const
1004  {  {
1005      EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1006    ValueType::size_type temp=i+j*m_shape[0];    ValueType::size_type temp=i+j*m_shape[0];
1007    //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  
1008    return temp;    return temp;
1009  }  }
1010    
# Line 710  DataArrayView::ValueType::size_type Line 1013  DataArrayView::ValueType::size_type
1013  DataArrayView::index(ValueType::size_type i,  DataArrayView::index(ValueType::size_type i,
1014               ValueType::size_type j) const               ValueType::size_type j) const
1015  {  {
1016      EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1017    ValueType::size_type temp=i+j*m_shape[0];    ValueType::size_type temp=i+j*m_shape[0];
1018    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1019    EsysAssert((temp < noValues(m_shape)), "Invalid index.");    return (m_offset+temp);
   return (temp+m_offset);  
1020  }  }
1021    
1022  inline  inline
# Line 722  DataArrayView::relIndex(ValueType::size_ Line 1025  DataArrayView::relIndex(ValueType::size_
1025              ValueType::size_type j,              ValueType::size_type j,
1026              ValueType::size_type k) const              ValueType::size_type k) const
1027  {  {
1028      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.");
1029      //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];
1030      EsysAssert((temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1031      //    return temp;
     // no offset  
     return temp;  
1032  }  }
1033    
1034  inline  inline
# Line 736  DataArrayView::index(ValueType::size_typ Line 1037  DataArrayView::index(ValueType::size_typ
1037               ValueType::size_type j,               ValueType::size_type j,
1038               ValueType::size_type k) const               ValueType::size_type k) const
1039  {  {
1040      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.");
1041      //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];
1042      EsysAssert((temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1043      return (temp+m_offset);    return (m_offset+temp);
1044  }  }
1045    
1046  inline  inline
# Line 749  DataArrayView::relIndex(ValueType::size_ Line 1050  DataArrayView::relIndex(ValueType::size_
1050                          ValueType::size_type k,                          ValueType::size_type k,
1051                          ValueType::size_type m) const                          ValueType::size_type m) const
1052  {  {
1053      EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1054    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];
1055    //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  
1056    return temp;    return temp;
1057  }  }
1058    
# Line 764  DataArrayView::index(ValueType::size_typ Line 1063  DataArrayView::index(ValueType::size_typ
1063               ValueType::size_type k,               ValueType::size_type k,
1064               ValueType::size_type m) const               ValueType::size_type m) const
1065  {  {
1066      EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1067    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];
1068    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1069    EsysAssert((temp < noValues(m_shape)), "Invalid index.");    return (m_offset+temp);
   return (temp+m_offset);  
1070  }  }
1071    
1072  inline  inline
1073  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1074  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()()
                           ValueType::size_type j,  
                           ValueType::size_type k,  
                           ValueType::size_type m)  
1075  {  {
1076      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)];  
1077  }  }
1078    
1079  inline  inline
1080  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1081  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()() const
                           ValueType::size_type j,  
                           ValueType::size_type k,  
                           ValueType::size_type m) const  
1082  {  {
1083      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)];  
1084  }  }
1085    
1086  inline  inline
1087  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1088  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i)
                           ValueType::size_type j,  
                           ValueType::size_type k)  
1089  {  {
1090      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)];  
1091  }  }
1092    
1093  inline  inline
1094  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1095  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i) const
                           ValueType::size_type j,  
                           ValueType::size_type k) const  
1096  {  {
1097      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)];  
1098  }  }
1099    
1100  inline  inline
# Line 821  DataArrayView::ValueType::reference Line 1102  DataArrayView::ValueType::reference
1102  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i,
1103                            ValueType::size_type j)                            ValueType::size_type j)
1104  {  {
1105      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)];  
1106  }  }
1107    
1108  inline  inline
# Line 831  DataArrayView::ValueType::const_referenc Line 1110  DataArrayView::ValueType::const_referenc
1110  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i,
1111                            ValueType::size_type j) const                            ValueType::size_type j) const
1112  {  {
1113      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)];  
1114  }  }
1115    
1116  inline  inline
1117  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1118  DataArrayView::operator()(ValueType::size_type i)  DataArrayView::operator()(ValueType::size_type i,
1119                              ValueType::size_type j,
1120                              ValueType::size_type k)
1121  {  {
1122      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)];  
1123  }  }
1124    
1125  inline  inline
1126  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1127  DataArrayView::operator()(ValueType::size_type i) const  DataArrayView::operator()(ValueType::size_type i,
1128                              ValueType::size_type j,
1129                              ValueType::size_type k) const
1130  {  {
1131      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)];  
1132  }  }
1133    
1134  inline  inline
1135  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1136  DataArrayView::operator()()  DataArrayView::operator()(ValueType::size_type i,
1137                              ValueType::size_type j,
1138                              ValueType::size_type k,
1139                              ValueType::size_type m)
1140  {  {
1141      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];  
1142  }  }
1143    
1144  inline  inline
1145  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1146  DataArrayView::operator()() const  DataArrayView::operator()(ValueType::size_type i,
1147                              ValueType::size_type j,
1148                              ValueType::size_type k,
1149                              ValueType::size_type m) const
1150  {  {
1151      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];  
1152  }  }
1153    
 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);  
   
1154  } // end of namespace  } // end of namespace
1155    
1156  #endif  #endif

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

  ViewVC Help
Powered by ViewVC 1.1.26