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

Last change on this file since 824 was 813, checked in by ansari, 25 years ago

Correction bug/amelioarions TArray,TMatrix,TVector - Reza 5/4/2000

File size: 21.0 KB
RevLine 
[772]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()
[804]20 : BaseArray() , mNDBlock()
[772]21// Default constructor
22{
23}
24
25template <class T>
[804]26TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, uint_4 step)
27 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1))
[772]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>
[804]34TArray<T>::TArray(uint_4 nx, uint_4 ny, uint_4 nz, uint_4 nt, uint_4 nu)
35 : BaseArray() , mNDBlock(nx*((ny>0)?ny:1)*((nz>0)?nz:1)*((nt>0)?nt:1)*((nu>0)?nu:1))
[772]36{
[787]37 uint_4 size[BASEARRAY_MAXNDIMS];
[772]38 size[0] = nx; size[1] = ny; size[2] = nz;
[804]39 size[3] = nt; size[4] = nu;
[772]40 int ndim = 1;
[804]41 if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) && (size[4] > 0) ) ndim = 5;
42 else if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) ) ndim = 4;
43 else if ((size[1] > 0) && (size[2] > 0)) ndim = 3;
[772]44 else if (size[1] > 0) ndim = 2;
45 else ndim = 1;
46 string exmsg = "TArray<T>::TArray(uint_4, uint_4, uint_4)";
47 if (!UpdateSizes(ndim, size, 1, 0, exmsg)) throw( ParmError(exmsg) );
48}
49
50template <class T>
[804]51TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, NDataBlock<T> & db, bool share, uint_4 step, uint_8 offset)
52 : BaseArray() , mNDBlock(db, share)
[772]53{
54 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, NDataBlock<T> & ... )";
55 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
56
57}
58
59template <class T>
[804]60TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, T* values, uint_4 step, uint_8 offset, Bridge* br)
61 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), values, br)
[772]62{
63 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, T* ... )";
64 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
65}
66
67template <class T>
68TArray<T>::TArray(const TArray<T>& a)
[804]69 : BaseArray() , mNDBlock(a.mNDBlock)
[772]70{
71 string exmsg = "TArray<T>::TArray(const TArray<T>&)";
72 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
73 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
74}
75
76template <class T>
77TArray<T>::TArray(const TArray<T>& a, bool share)
[804]78 : BaseArray() , mNDBlock(a.mNDBlock, share)
[772]79{
80 string exmsg = "TArray<T>::TArray(const TArray<T>&, bool)";
81 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
82 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
83}
84
85// Destructeur
86template <class T>
87TArray<T>::~TArray()
88{
89}
90
91template <class T>
[804]92TArray<T>& TArray<T>::Set(const TArray<T>& a)
[772]93{
94 if (this != &a) {
95 CloneOrShare(a);
96 if (mInfo) delete mInfo;
97 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
98 }
99 return(*this);
100}
101
102template <class T>
103void TArray<T>::Clone(const TArray<T>& a)
104{
105 string exmsg = "TArray<T>::Clone()";
106 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
107 mNDBlock.Clone(a.mNDBlock);
108 if (mInfo) delete mInfo;
109 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
110}
111
112template <class T>
113void TArray<T>::ReSize(uint_4 ndim, uint_4 * siz, uint_4 step)
114{
115 string exmsg = "TArray<T>::ReSize()";
116 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
117 mNDBlock.ReSize(totsize_);
118}
119
120template <class T>
121void TArray<T>::Realloc(uint_4 ndim, uint_4 * siz, uint_4 step, bool force)
122{
123 string exmsg = "TArray<T>::Realloc()";
124 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
125 mNDBlock.ReSize(totsize_);
126}
127
[787]128
[772]129template <class T>
[787]130TArray<T>& TArray<T>::CompactAllDimensions()
[772]131{
[787]132 CompactAllDim();
133 return(*this);
[772]134}
135
[785]136template <class T>
[787]137TArray<T>& TArray<T>::CompactTrailingDimensions()
[785]138{
[787]139 CompactTrailingDim();
[785]140 return(*this);
141}
142
143template <class T>
[787]144double TArray<T>::ValueAtPosition(uint_8 ip) const
[785]145{
[787]146#ifdef SO_BOUNDCHECKING
147 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
148#endif
149 return( (double)(*(mNDBlock.Begin()+Offset(ip))) );
[785]150}
151
[787]152// For complex values, we return the module of the complex number
153double TArray< complex<r_4> >::ValueAtPosition(uint_8 ip) const
[785]154{
[787]155#ifdef SO_BOUNDCHECKING
156 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
157#endif
158 complex<r_4> c = *(mNDBlock.Begin()+Offset(ip));
159 double cr = (double)(c.real());
160 double ci = (double)(c.imag());
161 return( sqrt(cr*cr+ci*ci) );
[785]162}
163
[787]164double TArray< complex<r_8> >::ValueAtPosition(uint_8 ip) const
[785]165{
[787]166#ifdef SO_BOUNDCHECKING
167 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
168#endif
169 complex<r_8> c = *(mNDBlock.Begin()+Offset(ip));
170 double cr = (double)(c.real());
171 double ci = (double)(c.imag());
172 return( sqrt(cr*cr+ci*ci) );
[785]173}
174
[787]175
[804]176template <class T>
177TArray<T> TArray<T>::PackElements(bool force) const
178{
179 if (NbDimensions() < 1)
180 throw RangeCheckError("TArray<T>::PackElements() - Not Allocated Array ! ");
181 if ( !force && (AvgStep() == 1) ) {
182 TArray<T> ra(*this, true);
183 ra.SetTemp(true);
184 return(ra);
185 }
186 else {
187 TArray<T> ra(ndim_, size_, 1);
188 ra.CopyElt(*this);
189 ra.SetTemp(true);
190 return(ra);
191 }
192}
193
[785]194// SubArrays
[804]195// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
[785]196template <class T>
[804]197TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const
[785]198{
[804]199 if (NbDimensions() < 1)
200 throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
[785]201 uint_4 ndim = 0;
[787]202 uint_4 size[BASEARRAY_MAXNDIMS];
203 uint_4 step[BASEARRAY_MAXNDIMS];
204 uint_4 pos[BASEARRAY_MAXNDIMS];
[785]205 size[0] = rx.Size();
206 size[1] = ry.Size();
207 size[2] = rz.Size();
208 size[3] = rt.Size();
209 size[4] = ru.Size();
210
211 step[0] = rx.Step();
212 step[1] = ry.Step();
213 step[2] = rz.Step();
214 step[3] = rt.Step();
215 step[4] = ru.Step();
216
217 pos[0] = rx.Start();
218 pos[1] = ry.Start();
219 pos[2] = rz.Start();
220 pos[3] = rt.Start();
221 pos[4] = ru.Start();
222
223 ndim = ndim_;
224 TArray<T> ra;
[804]225 UpdateSubArraySizes(ra, ndim, size, pos, step);
[787]226 ra.DataBlock().Share(this->DataBlock());
[785]227 ra.SetTemp(true);
228 return(ra);
229}
230
[772]231// ...... Operation de calcul sur les tableaux ......
232// ------- Attention --------
233// Boucles normales prenant en compte les steps ....
234// Possibilite de // , vectorisation
235template <class T>
[813]236TArray<T>& TArray<T>::SetSeq(Sequence seq)
[772]237{
[804]238 if (NbDimensions() < 1)
[813]239 throw RangeCheckError("TArray<T>::SetSeq(Sequence ) - Not Allocated Array ! ");
[785]240 T * pe;
241 uint_8 j,k;
242 if (AvgStep() > 0) { // regularly spaced elements
243 uint_8 step = AvgStep();
244 pe = Data();
245 for(k=0; k<totsize_; k++ ) pe[k*step] = seq(k);
246 }
247 else { // Non regular data spacing ...
[813]248 // uint_4 ka = MaxSizeKA();
249 uint_4 ka = 0;
[785]250 uint_8 step = Step(ka);
251 uint_8 gpas = Size(ka);
[813]252 uint_8 naxa = Size()/Size(ka);
253 for(j=0; j<naxa; j++) {
254 pe = mNDBlock.Begin()+Offset(ka,j);
255 for(k=0; k<gpas; k++) pe[k*step] = seq(j*gpas+k);
[785]256 }
257 }
[772]258 return(*this);
259}
260
261// >>>> Operations avec 2nd membre de type scalaire
262
263template <class T>
[813]264TArray<T>& TArray<T>::SetT(T x)
[772]265{
[804]266 if (NbDimensions() < 1)
[813]267 throw RangeCheckError("TArray<T>::SetT(T ) - Not Allocated Array ! ");
[785]268 T * pe;
269 uint_8 j,k;
270 if (AvgStep() > 0) { // regularly spaced elements
271 uint_8 step = AvgStep();
272 uint_8 maxx = totsize_*step;
273 pe = Data();
274 for(k=0; k<maxx; k+=step ) pe[k] = x;
275 }
276 else { // Non regular data spacing ...
277 uint_4 ka = MaxSizeKA();
278 uint_8 step = Step(ka);
279 uint_8 gpas = Size(ka)*step;
[813]280 uint_8 naxa = Size()/Size(ka);
281 for(j=0; j<naxa; j++) {
282 pe = mNDBlock.Begin()+Offset(ka,j);
[785]283 for(k=0; k<gpas; k+=step) pe[k] = x;
284 }
285 }
[772]286 return(*this);
287}
288
289template <class T>
[804]290TArray<T>& TArray<T>::Add(T x)
[772]291{
[804]292 if (NbDimensions() < 1)
293 throw RangeCheckError("TArray<T>::Add(T ) - Not Allocated Array ! ");
[785]294 T * pe;
295 uint_8 j,k;
296 if (AvgStep() > 0) { // regularly spaced elements
297 uint_8 step = AvgStep();
298 uint_8 maxx = totsize_*step;
299 pe = Data();
300 for(k=0; k<maxx; k+=step ) pe[k] += x;
301 }
302 else { // Non regular data spacing ...
303 uint_4 ka = MaxSizeKA();
304 uint_8 step = Step(ka);
305 uint_8 gpas = Size(ka)*step;
[813]306 uint_8 naxa = Size()/Size(ka);
307 for(j=0; j<naxa; j++) {
308 pe = mNDBlock.Begin()+Offset(ka,j);
[785]309 for(k=0; k<gpas; k+=step) pe[k] += x;
310 }
311 }
[772]312 return(*this);
313}
314
315template <class T>
[804]316TArray<T>& TArray<T>::Sub(T x)
[772]317{
[804]318 if (NbDimensions() < 1)
319 throw RangeCheckError("TArray<T>::Sub(T ) - Not Allocated Array ! ");
[785]320 T * pe;
321 uint_8 j,k;
322 if (AvgStep() > 0) { // regularly spaced elements
323 uint_8 step = AvgStep();
324 uint_8 maxx = totsize_*step;
325 pe = Data();
326 for(k=0; k<maxx; k+=step ) pe[k] -= x;
327 }
328 else { // Non regular data spacing ...
329 uint_4 ka = MaxSizeKA();
330 uint_8 step = Step(ka);
331 uint_8 gpas = Size(ka)*step;
[813]332 uint_8 naxa = Size()/Size(ka);
333 for(j=0; j<naxa; j++) {
334 pe = mNDBlock.Begin()+Offset(ka,j);
[785]335 for(k=0; k<gpas; k+=step) pe[k] -= x;
336 }
337 }
[772]338 return(*this);
339}
340
341template <class T>
[804]342TArray<T>& TArray<T>::Mul(T x)
[772]343{
[804]344 if (NbDimensions() < 1)
345 throw RangeCheckError("TArray<T>::Mul(T ) - Not Allocated Array ! ");
[785]346 T * pe;
347 uint_8 j,k;
348 if (AvgStep() > 0) { // regularly spaced elements
349 uint_8 step = AvgStep();
350 uint_8 maxx = totsize_*step;
351 pe = Data();
352 for(k=0; k<maxx; k+=step ) pe[k] *= x;
353 }
354 else { // Non regular data spacing ...
355 uint_4 ka = MaxSizeKA();
356 uint_8 step = Step(ka);
357 uint_8 gpas = Size(ka)*step;
[813]358 uint_8 naxa = Size()/Size(ka);
359 for(j=0; j<naxa; j++) {
360 pe = mNDBlock.Begin()+Offset(ka,j);
[785]361 for(k=0; k<gpas; k+=step) pe[k] *= x;
362 }
363 }
[772]364 return(*this);
365}
366
367template <class T>
[804]368TArray<T>& TArray<T>::Div(T x)
[772]369{
[804]370 if (NbDimensions() < 1)
371 throw RangeCheckError("TArray<T>::Div(T ) - Not Allocated Array ! ");
[785]372 T * pe;
373 uint_8 j,k;
374 if (AvgStep() > 0) { // regularly spaced elements
375 uint_8 step = AvgStep();
376 uint_8 maxx = totsize_*step;
377 pe = Data();
378 for(k=0; k<maxx; k+=step ) pe[k] /= x;
379 }
380 else { // Non regular data spacing ...
381 uint_4 ka = MaxSizeKA();
382 uint_8 step = Step(ka);
383 uint_8 gpas = Size(ka)*step;
[813]384 uint_8 naxa = Size()/Size(ka);
385 for(j=0; j<naxa; j++) {
386 pe = mNDBlock.Begin()+Offset(ka,j);
[785]387 for(k=0; k<gpas; k+=step) pe[k] /= x;
388 }
389 }
[772]390 return(*this);
391}
392
393
[804]394template <class T>
395TArray<T>& TArray<T>::SubInv(T x)
396{
397 if (NbDimensions() < 1)
398 throw RangeCheckError("TArray<T>::SubInv(T ) - Not Allocated Array ! ");
399 T * pe;
400 uint_8 j,k;
401 if (AvgStep() > 0) { // regularly spaced elements
402 uint_8 step = AvgStep();
403 uint_8 maxx = totsize_*step;
404 pe = Data();
405 for(k=0; k<maxx; k+=step ) pe[k] = x-pe[k];
406 }
407 else { // Non regular data spacing ...
408 uint_4 ka = MaxSizeKA();
409 uint_8 step = Step(ka);
410 uint_8 gpas = Size(ka)*step;
[813]411 uint_8 naxa = Size()/Size(ka);
412 for(j=0; j<naxa; j++) {
413 pe = mNDBlock.Begin()+Offset(ka,j);
[804]414 for(k=0; k<gpas; k+=step) pe[k] = x-pe[k];
415 }
416 }
417 return(*this);
418}
419
420template <class T>
421TArray<T>& TArray<T>::DivInv(T x)
422{
423 if (NbDimensions() < 1)
424 throw RangeCheckError("TArray<T>::DivInv(T ) - Not Allocated Array ! ");
425 T * pe;
426 uint_8 j,k;
427 if (AvgStep() > 0) { // regularly spaced elements
428 uint_8 step = AvgStep();
429 uint_8 maxx = totsize_*step;
430 pe = Data();
431 for(k=0; k<maxx; k+=step ) pe[k] = x/pe[k];
432 }
433 else { // Non regular data spacing ...
434 uint_4 ka = MaxSizeKA();
435 uint_8 step = Step(ka);
436 uint_8 gpas = Size(ka)*step;
[813]437 uint_8 naxa = Size()/Size(ka);
438 for(j=0; j<naxa; j++) {
439 pe = mNDBlock.Begin()+Offset(ka,j);
[804]440 for(k=0; k<gpas; k+=step) pe[k] = x/pe[k];
441 }
442 }
443 return(*this);
444}
445
446
[772]447// >>>> Operations avec 2nd membre de type tableau
448template <class T>
[804]449TArray<T>& TArray<T>::AddElt(const TArray<T>& a)
[772]450{
[804]451 if (NbDimensions() < 1)
452 throw RangeCheckError("TArray<T>::AddElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]453 if (!CompareSizes(a))
454 throw(SzMismatchError("TArray<T>::AddElt(const TArray<T>&) SizeMismatch")) ;
[785]455
456 T * pe;
457 const T * pea;
458 uint_8 j,k,ka;
459 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
460 uint_8 step = AvgStep();
461 uint_8 stepa = a.AvgStep();
462 uint_8 maxx = totsize_*step;
463 pe = Data();
464 pea = a.Data();
465 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] += pea[ka] ;
[772]466 }
[785]467 else { // Non regular data spacing ...
468 uint_4 ax = MaxSizeKA();
469 uint_8 step = Step(ax);
470 uint_8 stepa = a.Step(ax);
471 uint_8 gpas = Size(ax)*step;
[813]472 uint_8 naxa = Size()/Size(ax);
473 for(j=0; j<naxa; j++) {
474 pe = mNDBlock.Begin()+Offset(ax,j);
475 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[785]476 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] += pea[ka];
477 }
478 }
[772]479 return(*this);
480}
481
482template <class T>
[804]483TArray<T>& TArray<T>::SubElt(const TArray<T>& a)
[772]484{
[804]485 if (NbDimensions() < 1)
486 throw RangeCheckError("TArray<T>::SubElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]487 if (!CompareSizes(a))
488 throw(SzMismatchError("TArray<T>::SubElt(const TArray<T>&) SizeMismatch")) ;
[785]489
490 T * pe;
491 const T * pea;
492 uint_8 j,k,ka;
493 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
494 uint_8 step = AvgStep();
495 uint_8 stepa = a.AvgStep();
496 uint_8 maxx = totsize_*step;
497 pe = Data();
498 pea = a.Data();
499 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] -= pea[ka] ;
[772]500 }
[785]501 else { // Non regular data spacing ...
502 uint_4 ax = MaxSizeKA();
503 uint_8 step = Step(ax);
504 uint_8 stepa = a.Step(ax);
505 uint_8 gpas = Size(ax)*step;
[813]506 uint_8 naxa = Size()/Size(ax);
507 for(j=0; j<naxa; j++) {
508 pe = mNDBlock.Begin()+Offset(ax,j);
509 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[785]510 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] -= pea[ka];
511 }
512 }
[772]513 return(*this);
514}
515
516
517template <class T>
[804]518TArray<T>& TArray<T>::MulElt(const TArray<T>& a)
[772]519{
[804]520 if (NbDimensions() < 1)
521 throw RangeCheckError("TArray<T>::MulElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]522 if (!CompareSizes(a))
523 throw(SzMismatchError("TArray<T>::MulElt(const TArray<T>&) SizeMismatch")) ;
[785]524
525 T * pe;
526 const T * pea;
527 uint_8 j,k,ka;
528 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
529 uint_8 step = AvgStep();
530 uint_8 stepa = a.AvgStep();
531 uint_8 maxx = totsize_*step;
532 pe = Data();
533 pea = a.Data();
534 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] *= pea[ka] ;
[772]535 }
[785]536 else { // Non regular data spacing ...
537 uint_4 ax = MaxSizeKA();
538 uint_8 step = Step(ax);
539 uint_8 stepa = a.Step(ax);
540 uint_8 gpas = Size(ax)*step;
[813]541 uint_8 naxa = Size()/Size(ax);
542 for(j=0; j<naxa; j++) {
543 pe = mNDBlock.Begin()+Offset(ax,j);
544 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[785]545 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] *= pea[ka];
546 }
547 }
[772]548 return(*this);
549}
550
[804]551
[772]552template <class T>
553TArray<T>& TArray<T>::DivElt(const TArray<T>& a)
554{
[804]555 if (NbDimensions() < 1)
556 throw RangeCheckError("TArray<T>::DivElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]557 if (!CompareSizes(a))
558 throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&) SizeMismatch")) ;
[785]559
560 T * pe;
561 const T * pea;
562 uint_8 j,k,ka;
563 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
564 uint_8 step = AvgStep();
565 uint_8 stepa = a.AvgStep();
566 uint_8 maxx = totsize_*step;
567 pe = Data();
568 pea = a.Data();
569 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] /= pea[ka] ;
[772]570 }
[785]571 else { // Non regular data spacing ...
572 uint_4 ax = MaxSizeKA();
573 uint_8 step = Step(ax);
574 uint_8 stepa = a.Step(ax);
575 uint_8 gpas = Size(ax)*step;
[813]576 uint_8 naxa = Size()/Size(ax);
577 for(j=0; j<naxa; j++) {
578 pe = mNDBlock.Begin()+Offset(ax,j);
579 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[785]580 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] /= pea[ka];
581 }
582 }
[772]583 return(*this);
584}
585
[804]586template <class T>
587TArray<T>& TArray<T>::CopyElt(const TArray<T>& a)
588{
589 if (NbDimensions() < 1)
590 throw RangeCheckError("TArray<T>::CopyElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]591 if (!CompareSizes(a))
592 throw(SzMismatchError("TArray<T>::MultElt(const TArray<T>&) SizeMismatch")) ;
[772]593
[804]594 T * pe;
595 const T * pea;
596 uint_8 j,k,ka;
597 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
598 uint_8 step = AvgStep();
599 uint_8 stepa = a.AvgStep();
600 uint_8 maxx = totsize_*step;
601 pe = Data();
602 pea = a.Data();
603 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka] ;
604 }
605 else { // Non regular data spacing ...
606 uint_4 ax = MaxSizeKA();
607 uint_8 step = Step(ax);
608 uint_8 stepa = a.Step(ax);
609 uint_8 gpas = Size(ax)*step;
[813]610 uint_8 naxa = Size()/Size(ax);
611 for(j=0; j<naxa; j++) {
612 pe = mNDBlock.Begin()+Offset(ax,j);
613 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[804]614 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka];
615 }
616 }
617 return(*this);
618}
619
620
621// Somme et produit des elements
622template <class T>
623T TArray<T>::Sum() const
624{
625 if (NbDimensions() < 1)
626 throw RangeCheckError("TArray<T>::Sum() - Not Allocated Array ! ");
627 T ret=0;
628 const T * pe;
629 uint_8 j,k;
630 if (AvgStep() > 0) { // regularly spaced elements
631 uint_8 step = AvgStep();
632 uint_8 maxx = totsize_*step;
633 pe = Data();
634 for(k=0; k<maxx; k+=step ) ret += pe[k];
635 }
636 else { // Non regular data spacing ...
637 uint_4 ka = MaxSizeKA();
638 uint_8 step = Step(ka);
639 uint_8 gpas = Size(ka)*step;
[813]640 uint_8 naxa = Size()/Size(ka);
641 for(j=0; j<naxa; j++) {
642 pe = mNDBlock.Begin()+Offset(ka,j);
[804]643 for(k=0; k<gpas; k+=step) ret += pe[k] ;
644 }
645 }
646 return ret;
647}
648
649template <class T>
650T TArray<T>::Product() const
651{
652 if (NbDimensions() < 1)
653 throw RangeCheckError("TArray<T>::Product() - Not Allocated Array ! ");
654 T ret=0;
655 const T * pe;
656 uint_8 j,k;
657 if (AvgStep() > 0) { // regularly spaced elements
658 uint_8 step = AvgStep();
659 uint_8 maxx = totsize_*step;
660 pe = Data();
661 for(k=0; k<maxx; k+=step ) ret *= pe[k];
662 }
663 else { // Non regular data spacing ...
664 uint_4 ka = MaxSizeKA();
665 uint_8 step = Step(ka);
666 uint_8 gpas = Size(ka)*step;
[813]667 uint_8 naxa = Size()/Size(ka);
668 for(j=0; j<naxa; j++) {
669 pe = mNDBlock.Begin()+Offset(ka,j);
[804]670 for(k=0; k<gpas; k+=step) ret *= pe[k] ;
671 }
672 }
673 return ret;
674}
675
676
677
[772]678// ----------------------------------------------------
679// Impression, etc ...
680// ----------------------------------------------------
681
682template <class T>
[813]683string TArray<T>::InfoString() const
[772]684{
[813]685 string rs = "TArray<" ;
686 rs += typeid(T).name();
687 rs += "> ";
[787]688 return(rs);
[772]689}
690
691template <class T>
692void TArray<T>::Print(ostream& os, int_4 maxprt, bool si) const
693{
694 if (maxprt < 0) maxprt = max_nprt_;
[804]695 int_4 npr = 0;
[772]696 Show(os, si);
[804]697 uint_4 k0,k1,k2,k3,k4;
[772]698 for(k4=0; k4<size_[4]; k4++) {
[785]699 if (size_[4] > 1) cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
[772]700 for(k3=0; k3<size_[3]; k3++) {
[785]701 if (size_[3] > 1) cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
[772]702 for(k2=0; k2<size_[2]; k2++) {
[785]703 if (size_[2] > 1) cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
[772]704 for(k1=0; k1<size_[1]; k1++) {
[785]705 if ( (size_[1] > 1) && (size_[0] > 10) ) cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
[772]706 for(k0=0; k0<size_[0]; k0++) {
[785]707 if(k0 > 0) os << ", ";
708 os << Elem(k0, k1, k2, k3, k4); npr++;
[772]709 if (npr >= maxprt) {
710 if (npr < totsize_) os << "\n .... " << endl; return;
711 }
712 }
713 os << endl;
714 }
715 }
716 }
717 }
[813]718 os << endl;
[772]719}
720
721
722template <class T>
723void TArray<T>::CloneOrShare(const TArray<T>& a)
724{
725 string exmsg = "TArray<T>::CloneOrShare()";
726 if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) );
727 mNDBlock.CloneOrShare(a.mNDBlock);
728}
729
730template <class T>
731void TArray<T>::Share(const TArray<T>& a)
732{
733 string exmsg = "TArray<T>::Share()";
734 if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) );
735 mNDBlock.Share(a.mNDBlock);
736}
737
738
[785]739
[772]740///////////////////////////////////////////////////////////////
741///////////////////////////////////////////////////////////////
742#ifdef __CXX_PRAGMA_TEMPLATES__
[804]743/*
[772]744#pragma define_template TArray<uint_1>
[804]745#pragma define_template TArray<int_2>
746#pragma define_template TArray<uint_4>
747#pragma define_template TArray<uint_8>
748*/
[772]749#pragma define_template TArray<uint_2>
750#pragma define_template TArray<int_4>
751#pragma define_template TArray<int_8>
752#pragma define_template TArray<r_4>
753#pragma define_template TArray<r_8>
754#pragma define_template TArray< complex<r_4> >
755#pragma define_template TArray< complex<r_8> >
756#endif
757
758#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
[804]759/*
760template class TArray<uint_1>;
761template class TArray<int_2>;
762template class TArray<uint_4>;
763template class TArray<uint_8>;
764*/
[772]765template class TArray<uint_2>;
766template class TArray<int_4>;
767template class TArray<int_8>;
768template class TArray<r_4>;
769template class TArray<r_8>;
770template class TArray< complex<r_4> >;
771template class TArray< complex<r_8> >;
772#endif
773
774
Note: See TracBrowser for help on using the repository browser.