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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1714 - (show annotations)
Thu Aug 21 00:01:55 2008 UTC (11 years, 6 months ago) by jfenwick
Original Path: branches/arrayview_from_1695_trunk/escript/src/DataTypes.cpp
File size: 5330 byte(s)
Branch commit

Moved getSliceRegion() and getSliceRange() into DataTypes
Data.cpp - modified not to rely on operator() from DataArrayView
         - Used more const& to avoid copies


1 /* $Id:$ */
2
3 /*******************************************************
4 *
5 * Copyright 2003-2007 by ACceSS MNRF
6 * Copyright 2007 by University of Queensland
7 *
8 * http://esscc.uq.edu.au
9 * Primary Business: Queensland, Australia
10 * Licensed under the Open Software License version 3.0
11 * http://www.opensource.org/licenses/osl-3.0.php
12 *
13 *******************************************************/
14
15 #include <sstream>
16 #include <boost/python/extract.hpp>
17 #include <boost/python/tuple.hpp>
18 #include "DataException.h"
19 #include "DataTypes.h"
20
21 using namespace boost::python;
22
23 namespace escript
24 {
25 namespace DataTypes
26 {
27
28 int
29 noValues(const ShapeType& shape)
30 {
31 ShapeType::const_iterator i;
32 //
33 // An empty shape vector means rank 0 which contains 1 value
34 int noValues=1;
35 for (i=shape.begin();i!=shape.end();i++) {
36 noValues*=(*i);
37 }
38 return noValues;
39 }
40
41 int
42 noValues(const RegionLoopRangeType& region)
43 {
44 //
45 // An empty region vector means rank 0 which contains 1 value
46 int noValues=1;
47 unsigned int i;
48 for (i=0;i<region.size();i++) {
49 noValues*=region[i].second-region[i].first;
50 }
51 return noValues;
52 }
53
54 std::string
55 shapeToString(const DataTypes::ShapeType& shape)
56 {
57 std::stringstream temp;
58 temp << "(";
59 unsigned int i;
60 for (i=0;i<shape.size();i++) {
61 temp << shape[i];
62 if (i < shape.size()-1) {
63 temp << ",";
64 }
65 }
66 temp << ")";
67 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
177 } // end namespace DataTypes
178 } // end namespace escript

  ViewVC Help
Powered by ViewVC 1.1.26