source: Sophya/trunk/SophyaLib/TArray/tarray.cc@ 772

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

Separation MatrixRC et TMatrix, etc ... - Creation de TArray<T> Reza 10/3/2000

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