/[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 580 by gross, Wed Mar 8 05:45:51 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
565         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      */
577      void
578      copySlice(ValueType::size_type thisOffset,
579                const DataArrayView& other,
580                ValueType::size_type otherOffset,
581                const RegionLoopRangeType& region);
582    
583      /**
584         \brief
585         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      void
594      copySliceFrom(const DataArrayView& other,
595                    const RegionLoopRangeType& region);
596    
597      /**
598         \brief
599         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       \brief
619       Perform the unary operation using the view's offset.       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    void    void
# Line 451  class DataArrayView { Line 631  class DataArrayView {
631    
632    /**    /**
633       \brief       \brief
634       Perform the given operation and return a result.       Perform the unary operation on the data point specified by the given
635         offset. Applies the specified operation to each value in the data
636         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 UnaryFunction>    template <class UnaryFunction>
646    double    void
647    algorithm(ValueType::size_type leftOffset,    unaryOp(ValueType::size_type offset,
648              UnaryFunction operation) const;            UnaryFunction operation);
649    
650    /**    /**
651       \brief       \brief
652       Perform the given operation and return a result. Use the default offset.       Perform the binary operation on the data points specified by the default
653         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 UnaryFunction>    template <class BinaryFunction>
665    double    void
666    algorithm(UnaryFunction operation) const;    binaryOp(const DataArrayView& right,
667               BinaryFunction operation);
668    
669    /**    /**
670       \brief       \brief
671       Perform the binary operation. Version which applies a double value       Perform the binary operation on the data points specified by the given
672       to all values within the view. The given offset is used instead of       offsets in this view and in view "right". Applies the specified operation
673       the default offset specified within the view.       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
689    binaryOp(ValueType::size_type leftOffset,    binaryOp(ValueType::size_type leftOffset,
690             double right,             const DataArrayView& right,
691               ValueType::size_type rightOffset,
692             BinaryFunction operation);             BinaryFunction operation);
693    
694    /**    /**
695       \brief       \brief
696       Perform the binary operation. Version which applies a double value       Perform the binary operation on the data point specified by the default
697       to all values within the view.       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
# Line 490  class DataArrayView { Line 712  class DataArrayView {
712    
713    /**    /**
714       \brief       \brief
715       Perform the binary operation. The given offsets override the default       Perform the binary operation on the data point specified by the given
716       offsets specified within the views.       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    template <class BinaryFunction>    template <class BinaryFunction>
730    void    void
731    binaryOp(ValueType::size_type leftOffset,    binaryOp(ValueType::size_type offset,
732             const DataArrayView& right,             double right,
            ValueType::size_type rightOffset,  
733             BinaryFunction operation);             BinaryFunction operation);
734    
735    /**    /**
736       \brief       \brief
737       Perform the binary operation.       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         Called by escript::algorithm.
743    
744         \param operation - Input -
745                      Operation to apply. Must be a pointer to a function.
746    */    */
747    template <class BinaryFunction>    template <class BinaryFunction>
748    void    double
749    binaryOp(const DataArrayView& right,    reductionOp(BinaryFunction operation,
750             BinaryFunction operation);                double initial_value) const;
751    
752    /**    /**
753       \brief       \brief
754       Return the data as a string. Not recommended for very large objects.       Perform the given data point reduction operation on the data point
755       \param suffix - Input - Suffix appended to index display.       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         Called by escript::algorithm.
760    
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    std::string    template <class BinaryFunction>
767    toString(const std::string& suffix=std::string("")) const;    double
768      reductionOp(ValueType::size_type offset,
769                  BinaryFunction operation,
770                  double initial_value) const;
771    
772    /**    /**
773       \brief       \brief
774       Return the given shape as a string.       solves a local eigenvalue problem
775    
776       \param shape - Input.       \param in - Input - matrix
777         \param inOffset - Input - offset into in
778         \param ev - Output - The eigenvalues
779         \param inOffset - Input - offset into ev
780    */    */
781    static std::string    static
782    shapeToString(const DataArrayView::ShapeType& shape);    inline
783      void
784      DataArrayView::eigenvalues(DataArrayView& in,
785                                 ValueType::size_type inOffset,
786                                 DataArrayView& ev,
787                                 ValueType::size_type evOffset)
788     {
789       double in00,in10,in20,in01,in11,in21,in02,in12,in22;
790       double ev0,ev1,ev2;
791       int s=in.getShape()[0];
792       if (s==1) {
793          in00=(*(in.m_data))[inOffset+in.index(0,0)];
794          eigenvalues1(in00,&ev0);
795          (*(ev.m_data))[evOffset+ev.index(0)]=ev0;
796    
797       } else  if (s==2) {
798          in00=(*(in.m_data))[inOffset+in.index(0,0)];
799          in10=(*(in.m_data))[inOffset+in.index(1,0)];
800          in01=(*(in.m_data))[inOffset+in.index(0,1)];
801          in11=(*(in.m_data))[inOffset+in.index(1,1)];
802          eigenvalues2(in00,(in01+in10)/2.,in11,&ev0,&ev1);
803          (*(ev.m_data))[evOffset+ev.index(0)]=ev0;
804          (*(ev.m_data))[evOffset+ev.index(1)]=ev1;
805    
806       } else  if (s==3) {
807          in00=(*(in.m_data))[inOffset+in.index(0,0)];
808          in10=(*(in.m_data))[inOffset+in.index(1,0)];
809          in20=(*(in.m_data))[inOffset+in.index(2,0)];
810          in01=(*(in.m_data))[inOffset+in.index(0,1)];
811          in11=(*(in.m_data))[inOffset+in.index(1,1)];
812          in21=(*(in.m_data))[inOffset+in.index(2,1)];
813          in02=(*(in.m_data))[inOffset+in.index(0,2)];
814          in12=(*(in.m_data))[inOffset+in.index(1,2)];
815          in22=(*(in.m_data))[inOffset+in.index(2,2)];
816          eigenvalues3(in00,(in01+in10)/2.,(in02+in20)/2.,in11,(in21+in12)/2.,in22,
817                     &ev0,&ev1,&ev2);
818          (*(ev.m_data))[evOffset+ev.index(0)]=ev0;
819          (*(ev.m_data))[evOffset+ev.index(1)]=ev1;
820          (*(ev.m_data))[evOffset+ev.index(2)]=ev2;
821    
822       }
823     }
824    
825    /**    /**
826       \brief       \brief
827       Perform matrix multiply.       solves a local eigenvalue problem
828    
829         \param in - Input - matrix
830         \param inOffset - Input - offset into in
831         \param ev - Output - The eigenvalues
832         \param evOffset - Input - offset into ev
833         \param V - Output - The eigenvectors
834         \param VOffset - Input - offset into V
835         \param tol - Input - eigenvalues with relative difference tol are treated as equal
836      */
837      static
838      inline
839      void
840      DataArrayView::eigenvalues_and_eigenvectors(DataArrayView& in,
841                                                  ValueType::size_type inOffset,
842                                                  DataArrayView& ev,
843                                                  ValueType::size_type evOffset,
844                                                  DataArrayView& V,
845                                                  ValueType::size_type VOffset,
846                                                  const double tol=1.e-13)
847      {
848       double ev0,ev1,ev2;
849       int s=in.getShape()[0];
850       if (s==1) {
851          eigenvalues1(in(0,0),&ev0);
852          ev(0)=ev0;
853    
854       } else  if (s==2) {
855          eigenvalues2(in(0,0),(in(0,1)+in(1,0))/2.,in(1,1),
856                       &ev0,&ev1);
857          ev(0)=ev0;
858          ev(1)=ev1;
859    
860       } else  if (s==3) {
861          eigenvalues3(in(0,0),(in(0,1)+in(1,0))/2.,(in(0,2)+in(2,0))/2.,in(1,1),(in(2,1)+in(1,2))/2.,in(2,2),
862                     &ev0,&ev1,&ev2);
863          ev(0)=ev0;
864          ev(1)=ev1;
865          ev(2)=ev2;
866    
867       Description:     }
868       Perform matrix multiply.   }
869     /**
870         \brief
871         Perform a matrix multiply of the given views.
872         This is purely a utility method and has no bearing on this view.
873    
874         NB: Only multiplies together the two given views, ie: two data-points,
875         would need to call this over all data-points to multiply the entire
876         Data objects involved.
877    
878       \param left - Input - The left hand side.       \param left - Input - The left hand side.
879       \param right - Input - The right hand side.       \param right - Input - The right hand side.
880       \param result - Output - The result of the operation.       \param result - Output - The result of the operation.
881    */    */
882    static void    static
883      void
884    matMult(const DataArrayView& left,    matMult(const DataArrayView& left,
885            const DataArrayView& right,            const DataArrayView& right,
886            DataArrayView& result);            DataArrayView& result);
887    
888      /**
889         \brief
890         Determine the shape of the result array for a matrix multiplication
891         of the given views.
892         This is purely a utility method and has no bearing on this view.
893      */
894      static
895      ShapeType
896      determineResultShape(const DataArrayView& left,
897                           const DataArrayView& right);
898    
899   protected:   protected:
900    
901   private:   private:
902    
903    //    //
904      // The maximum rank allowed for the shape of any view.
905    static const int m_maxRank=4;    static const int m_maxRank=4;
906    
907    //    //
908    // The data values for the view. NOTE: This points to data external to the view.    // The data values for the view.
909      // NOTE: This points to data external to the view.
910      // This is just a pointer to an array of ValueType.
911    ValueType* m_data;    ValueType* m_data;
912    
913    //    //
914    // The offset into the data array used by different views.    // The offset into the data array used by different views.
915      // This is simply an integer specifying a position in the data array
916      // pointed to by m_data.
917    ValueType::size_type m_offset;    ValueType::size_type m_offset;
918    
919    //    //
920    // The shape of the data.    // The shape of the data.
921      // This is simply an STL vector specifying the lengths of each dimension
922      // of the shape as ints.
923    ShapeType m_shape;    ShapeType m_shape;
924    
925    //    //
926    // The number of values needed for the array.    // The number of values needed for the array.
927      // This can be derived from m_shape by multiplying the size of each dimension, but
928      // is stored here for convenience.
929    int m_noValues;    int m_noValues;
930    
931  };  };
932    
933  inline  bool operator==(const DataArrayView& left, const DataArrayView& right);
934  DataArrayView::ValueType::size_type  bool operator!=(const DataArrayView& left, const DataArrayView& right);
 DataArrayView::getOffset() const  
 {  
   return m_offset;  
 }  
935    
936  inline  /**
937  DataArrayView::ValueType&    \brief
938  DataArrayView::getData() const     Modify region to copy from in order to
939  {     deal with the case where one range in the region contains identical indexes,
940    EsysAssert(!isEmpty(),"Error - View is empty");     eg: <<1,1><0,3><0,3>>
941    return *m_data;     This situation implies we want to copy from an object with rank greater than that of this
942  }     object. eg: we want to copy the values from a two dimensional slice out of a three
943       dimensional object into a two dimensional object.
944       We do this by taking a slice from the other object where one dimension of
945       the slice region is of size 1. So in the above example, we modify the above
946       region like so: <<1,2><0,3><0,3>> and take this slice.
947    */
948    DataArrayView::RegionLoopRangeType
949    getSliceRegionLoopRange(const DataArrayView::RegionType& region);
950    
951  inline  /**
952  DataArrayView::ValueType::reference    \brief
953  DataArrayView::getData(ValueType::size_type i) const    Calculate the slice range from the given python key object
954  {    Used by DataArrayView::getSliceRegion.
955    //    Returns the python slice object key as a pair of ints where the first
956    // 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
957    // the equivalent of end()    step attribute with value different from one will throw an exception
   return (*m_data)[i+m_offset];  
 }  
958    
959  template <class UnaryFunction>    /param key - Input - key object specifying slice range.
960  inline  */
961  void  std::pair<int,int>
962  DataArrayView::unaryOp(ValueType::size_type leftOffset,  getSliceRange(const boost::python::object& key,
963                         UnaryFunction operation)                const int shape);
964  {  
965    for (ValueType::size_type i=0;i<(noValues(m_shape));++i) {  /**
966      (*m_data)[i+leftOffset]=operation((*m_data)[i+leftOffset]);     Inline function definitions.
967    }  */
 }  
968    
969  template <class UnaryFunction>  template <class UnaryFunction>
970  inline  inline
# Line 613  DataArrayView::unaryOp(UnaryFunction ope Line 976  DataArrayView::unaryOp(UnaryFunction ope
976    
977  template <class UnaryFunction>  template <class UnaryFunction>
978  inline  inline
979  double  void
980  DataArrayView::algorithm(ValueType::size_type leftOffset,  DataArrayView::unaryOp(ValueType::size_type offset,
981                           UnaryFunction operation) const                         UnaryFunction operation)
982  {  {
983    for (ValueType::size_type i=0;i<(noValues(m_shape));++i) {    EsysAssert((!isEmpty()&&checkOffset(offset)),
984      operation((*m_data)[i+leftOffset]);                 "Error - Couldn't perform unaryOp due to insufficient storage.");
985      for (ValueType::size_type i=0;i<noValues();i++) {
986        (*m_data)[offset+i]=operation((*m_data)[offset+i]);
987    }    }
   return operation.getResult();  
988  }  }
989    
990  template <class UnaryFunction>  template <class BinaryFunction>
991  inline  inline
992  double  void
993  DataArrayView::algorithm(UnaryFunction operation) const  DataArrayView::binaryOp(const DataArrayView& right,
994                            BinaryFunction operation)
995  {  {
996    return algorithm(m_offset,operation);    binaryOp(m_offset,right,right.getOffset(),operation);
997  }  }
998    
999  template <class BinaryFunction>  template <class BinaryFunction>
1000  inline  inline
1001  void  void
1002  DataArrayView::binaryOp(ValueType::size_type leftOffset,  DataArrayView::binaryOp(ValueType::size_type leftOffset,
1003                          const DataArrayView& right,                          const DataArrayView& right,
1004                          ValueType::size_type rightOffset,                          ValueType::size_type rightOffset,
1005                          BinaryFunction operation)                          BinaryFunction operation)
1006  {  {
1007    EsysAssert(getShape()==right.getShape(),    EsysAssert(getShape()==right.getShape(),
1008           "Error - Right hand shape: " << shapeToString(right.getShape()) << " doesn't match the left: " << shapeToString(getShape()));           "Error - Couldn't perform binaryOp due to shape mismatch,");
1009    for (ValueType::size_type i=0;i<noValues();++i) {    EsysAssert((!isEmpty()&&checkOffset(leftOffset)),
1010      (*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.");
1011      EsysAssert((!right.isEmpty()&&right.checkOffset(rightOffset)),
1012                 "Error - Couldn't perform binaryOp due to insufficient storage in right object.");
1013      for (ValueType::size_type i=0;i<noValues();i++) {
1014        (*m_data)[leftOffset+i]=operation((*m_data)[leftOffset+i],(*right.m_data)[rightOffset+i]);
1015    }    }
1016  }  }
1017    
1018  template <class BinaryFunction>  template <class BinaryFunction>
1019  inline  inline
1020  void  void
1021  DataArrayView::binaryOp(const DataArrayView& right,  DataArrayView::binaryOp(double right,
1022                          BinaryFunction operation)                          BinaryFunction operation)
1023  {  {
1024    //    binaryOp(m_offset,right,operation);
   // version using the offsets specified within the view  
   binaryOp(m_offset,right,right.getOffset(),operation);  
1025  }  }
1026    
1027  template <class BinaryFunction>  template <class BinaryFunction>
1028  inline  inline
1029  void  void
1030  DataArrayView::binaryOp(ValueType::size_type leftOffset,  DataArrayView::binaryOp(ValueType::size_type offset,
1031                          double right,                          double right,
1032                          BinaryFunction operation)                          BinaryFunction operation)
1033  {  {
1034    //    EsysAssert((!isEmpty()&&checkOffset(offset)),
1035    // 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.");
1036    // explicitly specify a single value    for (ValueType::size_type i=0;i<noValues();i++) {
1037    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);  
1038    }    }
1039  }  }
1040    
1041  template <class BinaryFunction>  template <class BinaryFunction>
1042  inline  inline
1043  void  double
1044  DataArrayView::binaryOp(double right,  DataArrayView::reductionOp(BinaryFunction operation,
1045                          BinaryFunction operation)                             double initial_value) const
1046  {  {
1047    //    return reductionOp(m_offset,operation,initial_value);
1048    // use the default offset  }
1049    binaryOp(m_offset,right,operation);  
1050    template <class BinaryFunction>
1051    inline
1052    double
1053    DataArrayView::reductionOp(ValueType::size_type offset,
1054                               BinaryFunction operation,
1055                               double initial_value) const
1056    {
1057      EsysAssert((!isEmpty()&&checkOffset(offset)),
1058                   "Error - Couldn't perform reductionOp due to insufficient storage.");
1059      double current_value=initial_value;
1060      for (ValueType::size_type i=0;i<noValues();i++) {
1061        current_value=operation(current_value,(*m_data)[offset+i]);
1062      }
1063      return current_value;
1064    }
1065    
1066    inline
1067    DataArrayView::ValueType::size_type
1068    DataArrayView::relIndex() const
1069    {
1070      EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
1071      return 0;
1072    }
1073    
1074    inline
1075    DataArrayView::ValueType::size_type
1076    DataArrayView::index() const
1077    {
1078      EsysAssert((getRank()==0),"Incorrect number of indices for the rank of this object.");
1079      return (m_offset);
1080    }
1081    
1082    inline
1083    DataArrayView::ValueType::size_type
1084    DataArrayView::relIndex(ValueType::size_type i) const
1085    {
1086      EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
1087      EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
1088      return i;
1089  }  }
1090    
1091  inline  inline
1092  DataArrayView::ValueType::size_type  DataArrayView::ValueType::size_type
1093  DataArrayView::index(ValueType::size_type i) const  DataArrayView::index(ValueType::size_type i) const
1094  {  {
1095      //EsysAssert((i >= 0) && (i < noValues(m_shape)), "Invalid index.");    EsysAssert((getRank()==1),"Incorrect number of indices for the rank of this object.");
1096      EsysAssert((i < noValues(m_shape)), "Invalid index.");    EsysAssert((i < noValues(m_shape)), "Error - Invalid index.");
1097      return (i+m_offset);    return (m_offset+i);
1098  }  }
1099    
1100  inline  inline
# Line 697  DataArrayView::ValueType::size_type Line 1102  DataArrayView::ValueType::size_type
1102  DataArrayView::relIndex(ValueType::size_type i,  DataArrayView::relIndex(ValueType::size_type i,
1103                          ValueType::size_type j) const                          ValueType::size_type j) const
1104  {  {
1105      EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1106    ValueType::size_type temp=i+j*m_shape[0];    ValueType::size_type temp=i+j*m_shape[0];
1107    //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  
1108    return temp;    return temp;
1109  }  }
1110    
# Line 710  DataArrayView::ValueType::size_type Line 1113  DataArrayView::ValueType::size_type
1113  DataArrayView::index(ValueType::size_type i,  DataArrayView::index(ValueType::size_type i,
1114               ValueType::size_type j) const               ValueType::size_type j) const
1115  {  {
1116      EsysAssert((getRank()==2),"Incorrect number of indices for the rank of this object.");
1117    ValueType::size_type temp=i+j*m_shape[0];    ValueType::size_type temp=i+j*m_shape[0];
1118    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1119    EsysAssert((temp < noValues(m_shape)), "Invalid index.");    return (m_offset+temp);
   return (temp+m_offset);  
1120  }  }
1121    
1122  inline  inline
# Line 722  DataArrayView::relIndex(ValueType::size_ Line 1125  DataArrayView::relIndex(ValueType::size_
1125              ValueType::size_type j,              ValueType::size_type j,
1126              ValueType::size_type k) const              ValueType::size_type k) const
1127  {  {
1128      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.");
1129      //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];
1130      EsysAssert((temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1131      //    return temp;
     // no offset  
     return temp;  
1132  }  }
1133    
1134  inline  inline
# Line 736  DataArrayView::index(ValueType::size_typ Line 1137  DataArrayView::index(ValueType::size_typ
1137               ValueType::size_type j,               ValueType::size_type j,
1138               ValueType::size_type k) const               ValueType::size_type k) const
1139  {  {
1140      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.");
1141      //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];
1142      EsysAssert((temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1143      return (temp+m_offset);    return (m_offset+temp);
1144  }  }
1145    
1146  inline  inline
# Line 749  DataArrayView::relIndex(ValueType::size_ Line 1150  DataArrayView::relIndex(ValueType::size_
1150                          ValueType::size_type k,                          ValueType::size_type k,
1151                          ValueType::size_type m) const                          ValueType::size_type m) const
1152  {  {
1153      EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1154    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];
1155    //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  
1156    return temp;    return temp;
1157  }  }
1158    
# Line 764  DataArrayView::index(ValueType::size_typ Line 1163  DataArrayView::index(ValueType::size_typ
1163               ValueType::size_type k,               ValueType::size_type k,
1164               ValueType::size_type m) const               ValueType::size_type m) const
1165  {  {
1166      EsysAssert((getRank()==4),"Incorrect number of indices for the rank of this object.");
1167    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];
1168    //EsysAssert((temp >= 0 || temp < noValues(m_shape)), "Invalid index.");    EsysAssert((temp < noValues(m_shape)), "Error - Invalid index.");
1169    EsysAssert((temp < noValues(m_shape)), "Invalid index.");    return (m_offset+temp);
   return (temp+m_offset);  
1170  }  }
1171    
1172  inline  inline
1173  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1174  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()()
                           ValueType::size_type j,  
                           ValueType::size_type k,  
                           ValueType::size_type m)  
1175  {  {
1176      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)];  
1177  }  }
1178    
1179  inline  inline
1180  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1181  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()() const
                           ValueType::size_type j,  
                           ValueType::size_type k,  
                           ValueType::size_type m) const  
1182  {  {
1183      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)];  
1184  }  }
1185    
1186  inline  inline
1187  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1188  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i)
                           ValueType::size_type j,  
                           ValueType::size_type k)  
1189  {  {
1190      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)];  
1191  }  }
1192    
1193  inline  inline
1194  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1195  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i) const
                           ValueType::size_type j,  
                           ValueType::size_type k) const  
1196  {  {
1197      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)];  
1198  }  }
1199    
1200  inline  inline
# Line 821  DataArrayView::ValueType::reference Line 1202  DataArrayView::ValueType::reference
1202  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i,
1203                            ValueType::size_type j)                            ValueType::size_type j)
1204  {  {
1205      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)];  
1206  }  }
1207    
1208  inline  inline
# Line 831  DataArrayView::ValueType::const_referenc Line 1210  DataArrayView::ValueType::const_referenc
1210  DataArrayView::operator()(ValueType::size_type i,  DataArrayView::operator()(ValueType::size_type i,
1211                            ValueType::size_type j) const                            ValueType::size_type j) const
1212  {  {
1213      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)];  
1214  }  }
1215    
1216  inline  inline
1217  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1218  DataArrayView::operator()(ValueType::size_type i)  DataArrayView::operator()(ValueType::size_type i,
1219                              ValueType::size_type j,
1220                              ValueType::size_type k)
1221  {  {
1222      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)];  
1223  }  }
1224    
1225  inline  inline
1226  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1227  DataArrayView::operator()(ValueType::size_type i) const  DataArrayView::operator()(ValueType::size_type i,
1228                              ValueType::size_type j,
1229                              ValueType::size_type k) const
1230  {  {
1231      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)];  
1232  }  }
1233    
1234  inline  inline
1235  DataArrayView::ValueType::reference  DataArrayView::ValueType::reference
1236  DataArrayView::operator()()  DataArrayView::operator()(ValueType::size_type i,
1237                              ValueType::size_type j,
1238                              ValueType::size_type k,
1239                              ValueType::size_type m)
1240  {  {
1241      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];  
1242  }  }
1243    
1244  inline  inline
1245  DataArrayView::ValueType::const_reference  DataArrayView::ValueType::const_reference
1246  DataArrayView::operator()() const  DataArrayView::operator()(ValueType::size_type i,
1247                              ValueType::size_type j,
1248                              ValueType::size_type k,
1249                              ValueType::size_type m) const
1250  {  {
1251      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];  
1252  }  }
1253    
 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);  
   
1254  } // end of namespace  } // end of namespace
1255    
1256  #endif  #endif

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

  ViewVC Help
Powered by ViewVC 1.1.26