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

Legend:
Removed from v.82  
changed lines
  Added in v.121

  ViewVC Help
Powered by ViewVC 1.1.26