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

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

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

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

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

  ViewVC Help
Powered by ViewVC 1.1.26