/[escript]/trunk/escript/src/DataTypes.cpp
ViewVC logotype

Diff of /trunk/escript/src/DataTypes.cpp

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

revision 1698 by jfenwick, Tue Aug 12 01:13:16 2008 UTC revision 1715 by jfenwick, Thu Aug 21 04:52:14 2008 UTC
# Line 13  Line 13 
13  *******************************************************/  *******************************************************/
14    
15  #include <sstream>  #include <sstream>
16    #include <boost/python/extract.hpp>
17    #include <boost/python/tuple.hpp>
18    #include "DataException.h"
19  #include "DataTypes.h"  #include "DataTypes.h"
20    
21    using namespace boost::python;
22    
23  namespace escript  namespace escript
24  {  {
25  namespace DataTypes  namespace DataTypes
# Line 62  namespace DataTypes Line 67  namespace DataTypes
67        return temp.str();        return temp.str();
68     }     }
69    
70    
71    /*
72      \brief
73      Calculate the slice range from the given python key object
74      Used by getSliceRegion - since it is not used anywhere else, I have elected not to declare it
75      in the header.
76      Returns the python slice object key as a pair of ints where the first
77      member is the start and the second member is the end. the presence of a possible
78      step attribute with value different from one will throw an exception
79    
80      /param key - Input - key object specifying slice range.
81    */
82       std::pair<int,int>
83       getSliceRange(const boost::python::object& key,
84                  const int shape)
85       {
86          /* default slice range is range of entire shape dimension */
87          int s0=0, s1=shape;;
88          extract<int> slice_int(key);
89          if (slice_int.check()) {
90             /* if the key is a single int set start=key and end=key */
91             /* in this case, we want to return a rank-1 dimension object from
92             this object, taken from a single index value for one of this
93             object's dimensions */
94             s0=slice_int();
95             s1=s0;
96          } else {
97             /* if key is a pair extract begin and end values */
98             extract<int> step(key.attr("step"));
99             if (step.check() && step()!=1) {
100                throw DataException("Error - Data does not support increments in slicing ");
101             } else {
102                extract<int> start(key.attr("start"));
103                if (start.check()) {
104                   s0=start();
105                }
106                extract<int> stop(key.attr("stop"));
107                if (stop.check()) {
108                   s1=stop();
109                }
110             }
111          }
112          if (s0 < 0)
113             throw DataException("Error - slice index out of range.");
114          if (s0 == s1 && s1 >= shape)
115             throw DataException("Error - slice index out of range.");
116          if (s0 != s1 &&  s1>shape)
117             throw DataException("Error - slice index out of range.");
118          if (s0 > s1)
119             throw DataException("Error - lower index must less or equal upper index.");
120          return std::pair<int,int>(s0,s1);
121       }
122    
123    
124    
125       DataTypes::RegionType
126       getSliceRegion(const DataTypes::ShapeType& shape, const boost::python::object& key)
127       {
128          int slice_rank, i;
129          int this_rank=shape.size();
130          RegionType out(this_rank);
131          /* allow for case where key is singular eg: [1], this implies we
132          want to generate a rank-1 dimension object, as opposed to eg: [1,2]
133          which implies we want to take a rank dimensional object with one
134          dimension of size 1 */
135          extract<tuple> key_tuple(key);
136          if (key_tuple.check()) {
137             slice_rank=extract<int> (key.attr("__len__")());
138             /* ensure slice is correctly dimensioned */
139             if (slice_rank>this_rank) {
140                throw DataException("Error - rank of slices does not match rank of slicee");
141             } else {
142                /* calculate values for slice range */
143                for (i=0;i<slice_rank;i++) {
144                   out[i]=getSliceRange(key[i],shape[i]);
145                }
146             }
147          } else {
148             slice_rank=1;
149             if (slice_rank>this_rank) {
150                throw DataException("Error - rank of slices does not match rank of slicee");
151             } else {
152                out[0]=getSliceRange(key,shape[0]);
153             }
154          }
155          for (i=slice_rank;i<this_rank;i++) {
156             out[i]=std::pair<int,int>(0,shape[i]);
157          }
158          return out;
159       }
160    
161       DataTypes::ShapeType
162       getResultSliceShape(const RegionType& region)
163       {
164          int dimSize;
165          ShapeType result;
166          RegionType::const_iterator i;
167          for (i=region.begin();i!=region.end();i++) {
168             dimSize=((i->second)-(i->first));
169             if (dimSize!=0) {
170                result.push_back(dimSize);
171             }
172          }
173          return result;
174       }
175    
176       DataTypes::RegionLoopRangeType
177       getSliceRegionLoopRange(const DataTypes::RegionType& region)
178       {
179          DataTypes::RegionLoopRangeType region_loop_range(region.size());
180          unsigned int i;
181          for (i=0;i<region.size();i++) {
182             if (region[i].first==region[i].second) {
183                region_loop_range[i].first=region[i].first;
184                region_loop_range[i].second=region[i].second+1;
185             } else {
186                region_loop_range[i].first=region[i].first;
187                region_loop_range[i].second=region[i].second;
188             }
189          }
190          return region_loop_range;
191       }
192    
193  }   // end namespace DataTypes  }   // end namespace DataTypes
194  }   // end namespace escript  }   // end namespace escript

Legend:
Removed from v.1698  
changed lines
  Added in v.1715

  ViewVC Help
Powered by ViewVC 1.1.26