source: Sophya/trunk/SophyaLib/TArray/basarr.cc@ 787

Last change on this file since 787 was 787, checked in by ansari, 26 years ago

Introduction de BaseArray comme classe parente de TArray<T>
Separation des operations math (fonctions) ds la classe MathArr<T>

Reza 20/3/2000

File size: 6.9 KB
Line 
1// Base class for numerical arrays
2// R. Ansari, C.Magneville 03/2000
3
4#include "machdefs.h"
5#include <stdio.h>
6#include <stdlib.h>
7#include "pexceptions.h"
8#include "basarr.h"
9
10
11
12// Variables statiques globales
13char * BaseArray::ck_op_msg_[6] = {"???", "Size(int )", "IsPacked(int )",
14 "Stride(int )", "ElemCheckBound()", "operator()" };
15uint_4 BaseArray::max_nprt_ = 50;
16
17// Methodes statiques globales
18void BaseArray::SetMaxPrint(uint_4 nprt)
19{
20 max_nprt_ = nprt;
21}
22
23
24uint_8 BaseArray::ComputeTotalSize(uint_4 ndim, uint_4 * siz, uint_4 step, uint_8 offset)
25{
26 uint_8 rs = step;
27 for(int k=0; k<ndim; k++) rs *= siz[k];
28 return(rs+offset);
29}
30
31// -------------------------------------------------------
32// Methodes de la classe
33// -------------------------------------------------------
34
35// Les constructeurs
36BaseArray::BaseArray()
37 : mInfo(NULL)
38// Default constructor
39{
40 ndim_ = 0;
41 for(int k=0; k<BASEARRAY_MAXNDIMS; k++) step_[k] = size_[k] = 0;
42 totsize_ = 0;
43 minstep_ = 0;
44 moystep_ = 0;
45 offset_ = 0;
46 // Default for matrices : Lines = Y , Columns = X
47 macoli_ = 0;
48 marowi_ = 1;
49}
50
51// Destructeur
52BaseArray::~BaseArray()
53{
54}
55
56
57bool BaseArray::CompareSizes(const BaseArray& a)
58{
59 if (ndim_ != a.ndim_) return(false);
60 for(int k=0; k<ndim_; k++)
61 if (size_[k] != a.size_[k]) return(false);
62 if ( (macoli_ != a.macoli_) || (marowi_ != a.marowi_) ) return(false);
63 return(true);
64}
65
66void BaseArray::CompactAllDim()
67{
68 if (ndim_ < 2) return;
69 uint_4 ndim = 0;
70 uint_4 size[BASEARRAY_MAXNDIMS];
71 uint_4 step[BASEARRAY_MAXNDIMS];
72 for(int k=0; k<ndim_; k++) {
73 if (size_[k] < 2) continue;
74 size[ndim] = size_[k];
75 step[ndim] = step_[k];
76 ndim++;
77 }
78 if (ndim == 0) {
79 size[0] = size_[0];
80 step[0] = step_[0];
81 ndim = 1;
82 }
83 string exmsg = "BaseArray::CompactAllDim() ";
84 if (!UpdateSizes(ndim, size, step, offset_, exmsg)) throw( ParmError(exmsg) );
85 return;
86}
87
88void BaseArray::CompactTrailingDim()
89{
90 if (ndim_ < 2) return;
91 uint_4 ndim = 0;
92 uint_4 size[BASEARRAY_MAXNDIMS];
93 uint_4 step[BASEARRAY_MAXNDIMS];
94 for(int k=0; k<ndim_; k++) {
95 size[ndim] = size_[k];
96 step[ndim] = step_[k];
97 if (size_[k] > 1) ndim=k;
98 }
99 if (ndim == 0) ndim = 1;
100 string exmsg = "BaseArray::CompactTrailingDim() ";
101 if (!UpdateSizes(ndim, size, step, offset_, exmsg)) throw( ParmError(exmsg) );
102 return;
103}
104
105
106uint_4 BaseArray::MinStepKA() const
107{
108 for(int ka=0; ka<ndim_; ka++)
109 if (step_[ka] == minstep_) return(ka);
110 return(0);
111}
112
113uint_4 BaseArray::MaxSizeKA() const
114{
115 uint_4 ka = 0;
116 uint_4 mx = size_[0];
117 for(int k=0; k<ndim_; k++)
118 if (size_[k] > mx) { ka = k; mx = size_[k]; }
119 return(ka);
120}
121
122
123// Acces lineaire aux elements .... Calcul d'offset
124
125uint_8 BaseArray::Offset(uint_8 ip) const
126{
127if (ip == 0) return(offset_);
128uint_4 idx[BASEARRAY_MAXNDIMS];
129int k;
130uint_8 rest = ip;
131for(k=0; k<ndim_; k++) { idx[k] = rest%size_[k]; rest /= size_[k]; }
132uint_8 off = offset_;
133for(k=0; k<ndim_; k++) off += idx[k]*step_[k];
134return (off);
135}
136
137
138// ----------------------------------------------------
139// Impression, etc ...
140// ----------------------------------------------------
141
142void BaseArray::Show(ostream& os, bool si) const
143{
144 os << " TArray< " << DataType() << " > NDim= " << ndim_
145 << "(" << typeid(*this).name() << " )" << endl;
146 os << "TotSize=" << totsize_ << " Size(X*Y*...)= " ;
147 for(int k=0; k<ndim_; k++) {
148 os << size_[k];
149 if (k<ndim_-1) os << " x ";
150 }
151 os << endl;
152 os << " Step(X Y ...)= " ;
153 for(int k=0; k<ndim_; k++) os << step_[k] << " " ;
154 os << " Offset= " << offset_ << "\n " << endl;
155 if (si && (mInfo != NULL)) os << (*mInfo) << endl;
156
157}
158
159
160DVList& BaseArray::Info()
161{
162if (mInfo == NULL) mInfo = new DVList;
163return(*mInfo);
164}
165
166
167bool BaseArray::UpdateSizes(uint_4 ndim, const uint_4 * siz, uint_4 step, uint_8 offset, string & exmsg)
168{
169 if (ndim >= BASEARRAY_MAXNDIMS) {
170 exmsg += " NDim Error"; return false;
171 }
172 if (step < 1) {
173 exmsg += " Step(=0) Error"; return false;
174 }
175
176 minstep_ = moystep_ = step;
177
178 // Flagging bad updates ...
179 ndim_ = 0;
180
181 totsize_ = 1;
182 int k;
183 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
184 size_[k] = 1;
185 step_[k] = 0;
186 }
187 for(k=0; k<ndim; k++) {
188 size_[k] = siz[k] ;
189 step_[k] = totsize_*step;
190 totsize_ *= size_[k];
191 }
192 if (totsize_ < 1) {
193 exmsg += " Size Error"; return false;
194 }
195 offset_ = offset;
196 // Default for matrices : Lines = Y , Columns = X
197 macoli_ = 0;
198 marowi_ = 1;
199 // Update OK
200 ndim_ = ndim;
201 return true;
202}
203
204bool BaseArray::UpdateSizes(uint_4 ndim, const uint_4 * siz, const uint_4 * step, uint_8 offset, string & exmsg)
205{
206 if (ndim >= BASEARRAY_MAXNDIMS) {
207 exmsg += " NDim Error"; return false;
208 }
209
210 // Flagging bad updates ...
211 ndim_ = 0;
212
213 totsize_ = 1;
214 int k;
215 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
216 size_[k] = 1;
217 step_[k] = 0;
218 }
219 uint_4 minstep = step[0];
220 for(k=0; k<ndim; k++) {
221 size_[k] = siz[k] ;
222 step_[k] = step[k];
223 totsize_ *= size_[k];
224 if (step_[k] < minstep) minstep = step_[k];
225 }
226 if (minstep < 1) {
227 exmsg += " Step(=0) Error"; return false;
228 }
229 if (totsize_ < 1) {
230 exmsg += " Size Error"; return false;
231 }
232 uint_8 plast = 0;
233 for(k=0; k<ndim; k++) plast += (siz[k]-1)*step[k];
234 if (plast == minstep*totsize_ ) moystep_ = minstep;
235 else moystep_ = 0;
236 minstep_ = minstep;
237 offset_ = offset;
238 // Default for matrices : Lines = Y , Columns = X
239 macoli_ = 0;
240 marowi_ = 1;
241 // Update OK
242 ndim_ = ndim;
243 return true;
244}
245
246bool BaseArray::UpdateSizes(const BaseArray& a, string & exmsg)
247{
248 if (a.ndim_ >= BASEARRAY_MAXNDIMS) {
249 exmsg += " NDim Error"; return false;
250 }
251
252 // Flagging bad updates ...
253 ndim_ = 0;
254
255 totsize_ = 1;
256 int k;
257 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
258 size_[k] = 1;
259 step_[k] = 0;
260 }
261 uint_4 minstep = a.step_[0];
262 for(k=0; k<a.ndim_; k++) {
263 size_[k] = a.size_[k] ;
264 step_[k] = a.step_[k];
265 totsize_ *= size_[k];
266 if (step_[k] < minstep) minstep = step_[k];
267 }
268 if (minstep < 1) {
269 exmsg += " Step(=0) Error"; return false;
270 }
271 if (totsize_ < 1) {
272 exmsg += " Size Error"; return false;
273 }
274
275 minstep_ = a.minstep_;
276 moystep_ = a.moystep_;
277 offset_ = a.offset_;
278 macoli_ = a.macoli_;
279 marowi_ = a.marowi_;
280 // Update OK
281 ndim_ = a.ndim_;
282 return true;
283}
284
285
286void BaseArray::SubArray(BaseArray & ra, uint_4 ndim, uint_4 * siz, uint_4 * pos, uint_4 * step)
287{
288 if ( (ndim > ndim_) || (ndim < 1) ) throw(SzMismatchError("BaseArray::SubArray( ... ) NDim Error") );
289 int k;
290 for(k=0; k<ndim; k++)
291 if ( (siz[k]*step[k]+pos[k]) > size_[k] )
292 throw(SzMismatchError("BaseArray::SubArray( ... ) Size/Pos Error") );
293 uint_8 offset = offset_;
294 for(k=0; k<ndim_; k++) {
295 offset += pos[k]*step_[k];
296 step[k] *= step_[k];
297 }
298 string exm = "BaseArray::SubArray() ";
299 if (!ra.UpdateSizes(ndim, siz, step, offset, exm))
300 throw( ParmError(exm) );
301 // (ra.mNDBlock).Share(mNDBlock);
302 return;
303}
304
305
Note: See TracBrowser for help on using the repository browser.