source: Sophya/trunk/SophyaLib/TArray/tarray.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: 15.0 KB
Line 
1// template array class for numerical types
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 "tarray.h"
9
10
11
12
13// -------------------------------------------------------
14// Methodes de la classe
15// -------------------------------------------------------
16
17// Les constructeurs
18template <class T>
19TArray<T>::TArray()
20 : mNDBlock() , BaseArray()
21// Default constructor
22{
23}
24
25template <class T>
26TArray<T>::TArray(uint_4 ndim, uint_4 * siz, uint_4 step)
27 : mNDBlock(ComputeTotalSize(ndim, siz, step, 1)) , BaseArray()
28{
29 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, uint_4)";
30 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
31}
32
33template <class T>
34TArray<T>::TArray(uint_4 nx, uint_4 ny=1, uint_4 nz=1)
35 : mNDBlock(nx*((ny>0)?ny:1)*((nz>0)?nz:1)) , BaseArray()
36{
37 uint_4 size[BASEARRAY_MAXNDIMS];
38 size[0] = nx; size[1] = ny; size[2] = nz;
39 int ndim = 1;
40 if ((size[1] > 0) && (size[2] > 0)) ndim = 3;
41 else if (size[1] > 0) ndim = 2;
42 else ndim = 1;
43 string exmsg = "TArray<T>::TArray(uint_4, uint_4, uint_4)";
44 if (!UpdateSizes(ndim, size, 1, 0, exmsg)) throw( ParmError(exmsg) );
45}
46
47template <class T>
48TArray<T>::TArray(uint_4 ndim, uint_4 * siz, NDataBlock<T> & db, bool share, uint_4 step, uint_8 offset)
49 : mNDBlock(db, share) , BaseArray()
50{
51 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, NDataBlock<T> & ... )";
52 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
53
54}
55
56template <class T>
57TArray<T>::TArray(uint_4 ndim, uint_4 * siz, T* values, uint_4 step, uint_8 offset, Bridge* br)
58 : mNDBlock(ComputeTotalSize(ndim, siz, step, 1), values, br) , BaseArray()
59{
60 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, T* ... )";
61 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
62}
63
64template <class T>
65TArray<T>::TArray(const TArray<T>& a)
66 : mNDBlock(a.mNDBlock) , BaseArray()
67{
68 string exmsg = "TArray<T>::TArray(const TArray<T>&)";
69 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
70 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
71}
72
73template <class T>
74TArray<T>::TArray(const TArray<T>& a, bool share)
75 : mNDBlock(a.mNDBlock, share) , BaseArray()
76{
77 string exmsg = "TArray<T>::TArray(const TArray<T>&, bool)";
78 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
79 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
80}
81
82// Destructeur
83template <class T>
84TArray<T>::~TArray()
85{
86}
87
88template <class T>
89TArray<T>& TArray<T>::operator = (const TArray<T>& a)
90{
91 if (this != &a) {
92 CloneOrShare(a);
93 if (mInfo) delete mInfo;
94 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
95 }
96 return(*this);
97}
98
99template <class T>
100void TArray<T>::Clone(const TArray<T>& a)
101{
102 string exmsg = "TArray<T>::Clone()";
103 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
104 mNDBlock.Clone(a.mNDBlock);
105 if (mInfo) delete mInfo;
106 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
107}
108
109template <class T>
110void TArray<T>::ReSize(uint_4 ndim, uint_4 * siz, uint_4 step)
111{
112 string exmsg = "TArray<T>::ReSize()";
113 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
114 mNDBlock.ReSize(totsize_);
115}
116
117template <class T>
118void TArray<T>::Realloc(uint_4 ndim, uint_4 * siz, uint_4 step, bool force)
119{
120 string exmsg = "TArray<T>::Realloc()";
121 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
122 mNDBlock.ReSize(totsize_);
123}
124
125
126template <class T>
127TArray<T>& TArray<T>::CompactAllDimensions()
128{
129 CompactAllDim();
130 return(*this);
131}
132
133template <class T>
134TArray<T>& TArray<T>::CompactTrailingDimensions()
135{
136 CompactTrailingDim();
137 return(*this);
138}
139
140template <class T>
141double TArray<T>::ValueAtPosition(uint_8 ip) const
142{
143#ifdef SO_BOUNDCHECKING
144 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
145#endif
146 return( (double)(*(mNDBlock.Begin()+Offset(ip))) );
147}
148
149// For complex values, we return the module of the complex number
150double TArray< complex<r_4> >::ValueAtPosition(uint_8 ip) const
151{
152#ifdef SO_BOUNDCHECKING
153 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
154#endif
155 complex<r_4> c = *(mNDBlock.Begin()+Offset(ip));
156 double cr = (double)(c.real());
157 double ci = (double)(c.imag());
158 return( sqrt(cr*cr+ci*ci) );
159}
160
161double TArray< complex<r_8> >::ValueAtPosition(uint_8 ip) const
162{
163#ifdef SO_BOUNDCHECKING
164 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
165#endif
166 complex<r_8> c = *(mNDBlock.Begin()+Offset(ip));
167 double cr = (double)(c.real());
168 double ci = (double)(c.imag());
169 return( sqrt(cr*cr+ci*ci) );
170}
171
172
173// SubArrays
174template <class T>
175TArray<T> TArray<T>::operator () (Range rx, Range ry, Range rz, Range rt, Range ru)
176{
177 uint_4 ndim = 0;
178 uint_4 size[BASEARRAY_MAXNDIMS];
179 uint_4 step[BASEARRAY_MAXNDIMS];
180 uint_4 pos[BASEARRAY_MAXNDIMS];
181 size[0] = rx.Size();
182 size[1] = ry.Size();
183 size[2] = rz.Size();
184 size[3] = rt.Size();
185 size[4] = ru.Size();
186
187 step[0] = rx.Step();
188 step[1] = ry.Step();
189 step[2] = rz.Step();
190 step[3] = rt.Step();
191 step[4] = ru.Step();
192
193 pos[0] = rx.Start();
194 pos[1] = ry.Start();
195 pos[2] = rz.Start();
196 pos[3] = rt.Start();
197 pos[4] = ru.Start();
198
199 ndim = ndim_;
200 TArray<T> ra;
201 SubArray(ra, ndim, size, pos, step);
202 ra.DataBlock().Share(this->DataBlock());
203 ra.SetTemp(true);
204 return(ra);
205}
206
207// ...... Operation de calcul sur les tableaux ......
208// ------- Attention --------
209// Boucles normales prenant en compte les steps ....
210// Possibilite de // , vectorisation
211template <class T>
212TArray<T>& TArray<T>::operator = (Sequence seq)
213{
214 T * pe;
215 uint_8 j,k;
216 if (AvgStep() > 0) { // regularly spaced elements
217 uint_8 step = AvgStep();
218 pe = Data();
219 for(k=0; k<totsize_; k++ ) pe[k*step] = seq(k);
220 }
221 else { // Non regular data spacing ...
222 uint_4 ka = MaxSizeKA();
223 uint_8 step = Step(ka);
224 uint_8 gpas = Size(ka);
225 for(j=0; j<totsize_; j += Size(ka)) {
226 pe = mNDBlock.Begin()+Offset(j);
227 for(k=0; k<gpas; k++) pe[k*step] = seq(j+k);
228 }
229 }
230 return(*this);
231}
232
233// >>>> Operations avec 2nd membre de type scalaire
234
235template <class T>
236TArray<T>& TArray<T>::operator = (T x)
237{
238 T * pe;
239 uint_8 j,k;
240 if (AvgStep() > 0) { // regularly spaced elements
241 uint_8 step = AvgStep();
242 uint_8 maxx = totsize_*step;
243 pe = Data();
244 for(k=0; k<maxx; k+=step ) pe[k] = x;
245 }
246 else { // Non regular data spacing ...
247 uint_4 ka = MaxSizeKA();
248 uint_8 step = Step(ka);
249 uint_8 gpas = Size(ka)*step;
250 for(j=0; j<totsize_; j += Size(ka)) {
251 pe = mNDBlock.Begin()+Offset(j);
252 for(k=0; k<gpas; k+=step) pe[k] = x;
253 }
254 }
255 return(*this);
256}
257
258template <class T>
259TArray<T>& TArray<T>::operator += (T x)
260{
261 T * pe;
262 uint_8 j,k;
263 if (AvgStep() > 0) { // regularly spaced elements
264 uint_8 step = AvgStep();
265 uint_8 maxx = totsize_*step;
266 pe = Data();
267 for(k=0; k<maxx; k+=step ) pe[k] += x;
268 }
269 else { // Non regular data spacing ...
270 uint_4 ka = MaxSizeKA();
271 uint_8 step = Step(ka);
272 uint_8 gpas = Size(ka)*step;
273 for(j=0; j<totsize_; j += Size(ka)) {
274 pe = mNDBlock.Begin()+Offset(j);
275 for(k=0; k<gpas; k+=step) pe[k] += x;
276 }
277 }
278 return(*this);
279}
280
281template <class T>
282TArray<T>& TArray<T>::operator -= (T x)
283{
284 T * pe;
285 uint_8 j,k;
286 if (AvgStep() > 0) { // regularly spaced elements
287 uint_8 step = AvgStep();
288 uint_8 maxx = totsize_*step;
289 pe = Data();
290 for(k=0; k<maxx; k+=step ) pe[k] -= x;
291 }
292 else { // Non regular data spacing ...
293 uint_4 ka = MaxSizeKA();
294 uint_8 step = Step(ka);
295 uint_8 gpas = Size(ka)*step;
296 for(j=0; j<totsize_; j += Size(ka)) {
297 pe = mNDBlock.Begin()+Offset(j);
298 for(k=0; k<gpas; k+=step) pe[k] -= x;
299 }
300 }
301 return(*this);
302}
303
304template <class T>
305TArray<T>& TArray<T>::operator *= (T x)
306{
307 T * pe;
308 uint_8 j,k;
309 if (AvgStep() > 0) { // regularly spaced elements
310 uint_8 step = AvgStep();
311 uint_8 maxx = totsize_*step;
312 pe = Data();
313 for(k=0; k<maxx; k+=step ) pe[k] *= x;
314 }
315 else { // Non regular data spacing ...
316 uint_4 ka = MaxSizeKA();
317 uint_8 step = Step(ka);
318 uint_8 gpas = Size(ka)*step;
319 for(j=0; j<totsize_; j += Size(ka)) {
320 pe = mNDBlock.Begin()+Offset(j);
321 for(k=0; k<gpas; k+=step) pe[k] *= x;
322 }
323 }
324 return(*this);
325}
326
327template <class T>
328TArray<T>& TArray<T>::operator /= (T x)
329{
330 T * pe;
331 uint_8 j,k;
332 if (AvgStep() > 0) { // regularly spaced elements
333 uint_8 step = AvgStep();
334 uint_8 maxx = totsize_*step;
335 pe = Data();
336 for(k=0; k<maxx; k+=step ) pe[k] /= x;
337 }
338 else { // Non regular data spacing ...
339 uint_4 ka = MaxSizeKA();
340 uint_8 step = Step(ka);
341 uint_8 gpas = Size(ka)*step;
342 for(j=0; j<totsize_; j += Size(ka)) {
343 pe = mNDBlock.Begin()+Offset(j);
344 for(k=0; k<gpas; k+=step) pe[k] /= x;
345 }
346 }
347 return(*this);
348}
349
350
351// >>>> Operations avec 2nd membre de type tableau
352template <class T>
353TArray<T>& TArray<T>::operator += (const TArray<T>& a)
354{
355 if (!CompareSizes(a)) throw(SzMismatchError("TArray<T>::operator += (const TArray<T>&)")) ;
356
357 T * pe;
358 const T * pea;
359 uint_8 j,k,ka;
360 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
361 uint_8 step = AvgStep();
362 uint_8 stepa = a.AvgStep();
363 uint_8 maxx = totsize_*step;
364 pe = Data();
365 pea = a.Data();
366 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] += pea[ka] ;
367 }
368 else { // Non regular data spacing ...
369 uint_4 ax = MaxSizeKA();
370 uint_8 step = Step(ax);
371 uint_8 stepa = a.Step(ax);
372 uint_8 gpas = Size(ax)*step;
373 for(j=0; j<totsize_; j += Size(ax)) {
374 pe = mNDBlock.Begin()+Offset(j);
375 pea = a.DataBlock().Begin()+a.Offset(j);
376 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] += pea[ka];
377 }
378 }
379 return(*this);
380}
381
382template <class T>
383TArray<T>& TArray<T>::operator -= (const TArray<T>& a)
384{
385 if (!CompareSizes(a)) throw(SzMismatchError("TArray<T>::operator -= (const TArray<T>&)")) ;
386
387 T * pe;
388 const T * pea;
389 uint_8 j,k,ka;
390 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
391 uint_8 step = AvgStep();
392 uint_8 stepa = a.AvgStep();
393 uint_8 maxx = totsize_*step;
394 pe = Data();
395 pea = a.Data();
396 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] -= pea[ka] ;
397 }
398 else { // Non regular data spacing ...
399 uint_4 ax = MaxSizeKA();
400 uint_8 step = Step(ax);
401 uint_8 stepa = a.Step(ax);
402 uint_8 gpas = Size(ax)*step;
403 for(j=0; j<totsize_; j += Size(ax)) {
404 pe = mNDBlock.Begin()+Offset(j);
405 pea = a.DataBlock().Begin()+a.Offset(j);
406 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] -= pea[ka];
407 }
408 }
409 return(*this);
410}
411
412
413template <class T>
414TArray<T>& TArray<T>::MultElt(const TArray<T>& a)
415{
416 if (!CompareSizes(a)) throw(SzMismatchError("TArray<T>::MultElt(const TArray<T>&)")) ;
417
418 T * pe;
419 const T * pea;
420 uint_8 j,k,ka;
421 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
422 uint_8 step = AvgStep();
423 uint_8 stepa = a.AvgStep();
424 uint_8 maxx = totsize_*step;
425 pe = Data();
426 pea = a.Data();
427 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] *= pea[ka] ;
428 }
429 else { // Non regular data spacing ...
430 uint_4 ax = MaxSizeKA();
431 uint_8 step = Step(ax);
432 uint_8 stepa = a.Step(ax);
433 uint_8 gpas = Size(ax)*step;
434 for(j=0; j<totsize_; j += Size(ax)) {
435 pe = mNDBlock.Begin()+Offset(j);
436 pea = a.DataBlock().Begin()+a.Offset(j);
437 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] *= pea[ka];
438 }
439 }
440 return(*this);
441}
442
443template <class T>
444TArray<T>& TArray<T>::DivElt(const TArray<T>& a)
445{
446 if (!CompareSizes(a)) throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&)")) ;
447
448 T * pe;
449 const T * pea;
450 uint_8 j,k,ka;
451 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
452 uint_8 step = AvgStep();
453 uint_8 stepa = a.AvgStep();
454 uint_8 maxx = totsize_*step;
455 pe = Data();
456 pea = a.Data();
457 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] /= pea[ka] ;
458 }
459 else { // Non regular data spacing ...
460 uint_4 ax = MaxSizeKA();
461 uint_8 step = Step(ax);
462 uint_8 stepa = a.Step(ax);
463 uint_8 gpas = Size(ax)*step;
464 for(j=0; j<totsize_; j += Size(ax)) {
465 pe = mNDBlock.Begin()+Offset(j);
466 pea = a.DataBlock().Begin()+a.Offset(j);
467 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] /= pea[ka];
468 }
469 }
470 return(*this);
471}
472
473
474// ----------------------------------------------------
475// Impression, etc ...
476// ----------------------------------------------------
477
478template <class T>
479string TArray<T>::DataType() const
480{
481 string rs = typeid(T).name();
482 return(rs);
483}
484
485template <class T>
486void TArray<T>::Print(ostream& os, int_4 maxprt, bool si) const
487{
488 if (maxprt < 0) maxprt = max_nprt_;
489 uint_4 npr = 0;
490 Show(os, si);
491 int k0,k1,k2,k3,k4;
492 for(k4=0; k4<size_[4]; k4++) {
493 if (size_[4] > 1) cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
494 for(k3=0; k3<size_[3]; k3++) {
495 if (size_[3] > 1) cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
496 for(k2=0; k2<size_[2]; k2++) {
497 if (size_[2] > 1) cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
498 for(k1=0; k1<size_[1]; k1++) {
499 if ( (size_[1] > 1) && (size_[0] > 10) ) cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
500 for(k0=0; k0<size_[0]; k0++) {
501 if(k0 > 0) os << ", ";
502 os << Elem(k0, k1, k2, k3, k4); npr++;
503 if (npr >= maxprt) {
504 if (npr < totsize_) os << "\n .... " << endl; return;
505 }
506 }
507 os << endl;
508 }
509 }
510 }
511 }
512 os << "\n" << endl;
513}
514
515
516template <class T>
517void TArray<T>::CloneOrShare(const TArray<T>& a)
518{
519 string exmsg = "TArray<T>::CloneOrShare()";
520 if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) );
521 mNDBlock.CloneOrShare(a.mNDBlock);
522}
523
524template <class T>
525void TArray<T>::Share(const TArray<T>& a)
526{
527 string exmsg = "TArray<T>::Share()";
528 if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) );
529 mNDBlock.Share(a.mNDBlock);
530}
531
532
533
534///////////////////////////////////////////////////////////////
535///////////////////////////////////////////////////////////////
536#ifdef __CXX_PRAGMA_TEMPLATES__
537#pragma define_template TArray<uint_1>
538#pragma define_template TArray<uint_2>
539#pragma define_template TArray<int_2>
540#pragma define_template TArray<int_4>
541#pragma define_template TArray<int_8>
542#pragma define_template TArray<uint_4>
543#pragma define_template TArray<uint_8>
544#pragma define_template TArray<r_4>
545#pragma define_template TArray<r_8>
546#pragma define_template TArray< complex<r_4> >
547#pragma define_template TArray< complex<r_8> >
548#endif
549
550#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
551template class TArray<uint_1>;
552template class TArray<uint_2>;
553template class TArray<int_2>;
554template class TArray<int_4>;
555template class TArray<int_8>;
556template class TArray<uint_4>;
557template class TArray<uint_8>;
558template class TArray<r_4>;
559template class TArray<r_8>;
560template class TArray< complex<r_4> >;
561template class TArray< complex<r_8> >;
562#endif
563
564
Note: See TracBrowser for help on using the repository browser.