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

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

Passage des TArray en partage de donnees par defaut pour constructeur de copie - Copie pour l'operateur = , cmv+Reza 26/4/2000

File size: 24.8 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>
[922]7#include <math.h>
[772]8#include "pexceptions.h"
9#include "tarray.h"
10
[926]11/*!
12 \class SOPHYA::TArray
13 \ingroup TArray
14 Class for template arrays
[772]15
[926]16 This class implements arrays of dimensions up to
17 \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS"
18*/
[772]19
20// -------------------------------------------------------
21// Methodes de la classe
22// -------------------------------------------------------
23
[894]24////////////////////////// Les constructeurs / destructeurs
25
26//! Default constructor
[772]27template <class T>
28TArray<T>::TArray()
[804]29 : BaseArray() , mNDBlock()
[772]30{
31}
32
[894]33//! Constructor
34/*!
35 \param ndim : number of dimensions (less or equal to
36 \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS")
37 \param siz[ndim] : size along each dimension
38 \param step : step (same for all dimensions)
39 */
[772]40template <class T>
[804]41TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, uint_4 step)
42 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1))
[772]43{
44 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, uint_4)";
45 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
46}
47
[894]48//! Constructor
49/*!
50 \param nx,ny,nz,nt,nu : sizes along first, second, third, fourth and fifth dimension
51 */
[772]52template <class T>
[804]53TArray<T>::TArray(uint_4 nx, uint_4 ny, uint_4 nz, uint_4 nt, uint_4 nu)
54 : BaseArray() , mNDBlock(nx*((ny>0)?ny:1)*((nz>0)?nz:1)*((nt>0)?nt:1)*((nu>0)?nu:1))
[772]55{
[787]56 uint_4 size[BASEARRAY_MAXNDIMS];
[772]57 size[0] = nx; size[1] = ny; size[2] = nz;
[804]58 size[3] = nt; size[4] = nu;
[772]59 int ndim = 1;
[804]60 if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) && (size[4] > 0) ) ndim = 5;
61 else if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) ) ndim = 4;
62 else if ((size[1] > 0) && (size[2] > 0)) ndim = 3;
[772]63 else if (size[1] > 0) ndim = 2;
64 else ndim = 1;
65 string exmsg = "TArray<T>::TArray(uint_4, uint_4, uint_4)";
66 if (!UpdateSizes(ndim, size, 1, 0, exmsg)) throw( ParmError(exmsg) );
67}
68
[894]69//! Constructor
70/*!
71 \param ndim : number of dimensions
72 \param siz[ndim] : size along each dimension
73 \param db : datas are given by this NDataBlock
74 \param share : if true, data are shared, if false they are copied
75 \param step : step (same for all dimensions) in data block
76 \param offset : offset for first element in data block
77 */
[772]78template <class T>
[804]79TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, NDataBlock<T> & db, bool share, uint_4 step, uint_8 offset)
80 : BaseArray() , mNDBlock(db, share)
[772]81{
82 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, NDataBlock<T> & ... )";
83 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
84
85}
86
[894]87//! Constructor
88/*!
89 \param ndim : number of dimensions
90 \param siz[ndim] : size along each dimension
91 \param values : datas are given by this pointer
92 \param share : if true, data are shared, if false they are copied
93 \param step : step (same for all dimensions) in data block
94 \param offset : offset for first element in data block
95 \param br : if not NULL, dats are bridge with other datas
96 \sa NDataBlock
97 */
[772]98template <class T>
[804]99TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, T* values, uint_4 step, uint_8 offset, Bridge* br)
100 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), values, br)
[772]101{
102 string exmsg = "TArray<T>::TArray(uint_4, uint_4 *, T* ... )";
103 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
104}
105
[894]106//! Constructor by copy
[967]107/*! \sa NDataBlock::NDataBlock(const NDataBlock<T>&) */
[772]108template <class T>
109TArray<T>::TArray(const TArray<T>& a)
[804]110 : BaseArray() , mNDBlock(a.mNDBlock)
[772]111{
112 string exmsg = "TArray<T>::TArray(const TArray<T>&)";
113 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
114 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
115}
116
[894]117//! Constructor by copy
118/*!
119 \param share : if true, data are shared, if false they are copied
120 */
[772]121template <class T>
122TArray<T>::TArray(const TArray<T>& a, bool share)
[804]123 : BaseArray() , mNDBlock(a.mNDBlock, share)
[772]124{
125 string exmsg = "TArray<T>::TArray(const TArray<T>&, bool)";
126 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
127 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
128}
129
[894]130//! Destructor
[772]131template <class T>
132TArray<T>::~TArray()
133{
134}
135
[894]136////////////////////////// Les methodes de copie/share
137
138//! Set array equal to \b a and return *this
[772]139template <class T>
[804]140TArray<T>& TArray<T>::Set(const TArray<T>& a)
[772]141{
[970]142 if (this == &a) return(*this);
143 if (a.NbDimensions() < 1)
144 throw RangeCheckError("TArray<T>::Set(a ) - Array a not allocated ! ");
145 if (NbDimensions() < 1) CloneOrShare(a);
146 else CopyElt(a);
[772]147 return(*this);
148}
149
[894]150//! Clone array \b a
[772]151template <class T>
152void TArray<T>::Clone(const TArray<T>& a)
153{
154 string exmsg = "TArray<T>::Clone()";
155 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
156 mNDBlock.Clone(a.mNDBlock);
[894]157 if (mInfo) {delete mInfo; mInfo = NULL;}
[772]158 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
159}
160
[970]161//! Clone if \b a is not temporary, share if temporary
162template <class T>
163void TArray<T>::CloneOrShare(const TArray<T>& a)
164{
165 string exmsg = "TArray<T>::CloneOrShare()";
166 if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) );
167 mNDBlock.CloneOrShare(a.mNDBlock);
168}
169
170//! Share data with a
171template <class T>
172void TArray<T>::Share(const TArray<T>& a)
173{
174 string exmsg = "TArray<T>::Share()";
175 if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) );
176 mNDBlock.Share(a.mNDBlock);
177}
178
179
[894]180//! Resize array
181/*!
182 \param ndim : number of dimensions
183 \param siz[ndim] : size along each dimension
184 \param step : step (same for all dimensions)
185 */
[772]186template <class T>
187void TArray<T>::ReSize(uint_4 ndim, uint_4 * siz, uint_4 step)
188{
189 string exmsg = "TArray<T>::ReSize()";
190 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
191 mNDBlock.ReSize(totsize_);
192}
193
[894]194//! Re-allocate space for array
195/*!
196 \param ndim : number of dimensions
197 \param siz[ndim] : size along each dimension
198 \param step : step (same for all dimensions)
199 \param force : if true re-allocation is forced, if not it occurs
200 only if the required space is greater than the old one.
201 */
[772]202template <class T>
203void TArray<T>::Realloc(uint_4 ndim, uint_4 * siz, uint_4 step, bool force)
204{
205 string exmsg = "TArray<T>::Realloc()";
206 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
207 mNDBlock.ReSize(totsize_);
208}
209
[787]210
[894]211//! Compact dimensions in one or more is equal to 1.
[772]212template <class T>
[787]213TArray<T>& TArray<T>::CompactAllDimensions()
[772]214{
[787]215 CompactAllDim();
216 return(*this);
[772]217}
218
[894]219//! Compact dimensions if the last one is equal to 1.
[785]220template <class T>
[787]221TArray<T>& TArray<T>::CompactTrailingDimensions()
[785]222{
[787]223 CompactTrailingDim();
[785]224 return(*this);
225}
226
[922]227inline double _SqrtRz_(double x) { return sqrt(x); } // Pb avec SGI-CC - $CHECK$ - Reza 04/2000
228
[894]229//! Give value (in \b double) for element at position \b ip..
[785]230template <class T>
[787]231double TArray<T>::ValueAtPosition(uint_8 ip) const
[785]232{
[787]233#ifdef SO_BOUNDCHECKING
234 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
235#endif
236 return( (double)(*(mNDBlock.Begin()+Offset(ip))) );
[785]237}
238
[894]239//! Give value (in \b double) for element at position \b ip..
240/*!
241 For complex values, we return the module of the complex number
242*/
[787]243double TArray< complex<r_4> >::ValueAtPosition(uint_8 ip) const
[785]244{
[787]245#ifdef SO_BOUNDCHECKING
246 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
247#endif
248 complex<r_4> c = *(mNDBlock.Begin()+Offset(ip));
249 double cr = (double)(c.real());
250 double ci = (double)(c.imag());
[922]251 return( _SqrtRz_(cr*cr+ci*ci) );
[785]252}
253
[894]254//! Give value (in \b double) for element at position \b ip..
255/*!
256 For complex values, we return the module of the complex number
257*/
[787]258double TArray< complex<r_8> >::ValueAtPosition(uint_8 ip) const
[785]259{
[787]260#ifdef SO_BOUNDCHECKING
261 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(uint_8 ip) Out-of-bound Error") );
262#endif
263 complex<r_8> c = *(mNDBlock.Begin()+Offset(ip));
264 double cr = (double)(c.real());
265 double ci = (double)(c.imag());
[922]266 return( _SqrtRz_(cr*cr+ci*ci) );
[785]267}
268
[894]269//! Return array with elements packed
270/*!
271 \param force : if true, pack elements in a new array.
272 If false and array is already packed, return
273 an array that share data with the current one.
274 \return packed array
275 */
[804]276template <class T>
277TArray<T> TArray<T>::PackElements(bool force) const
278{
279 if (NbDimensions() < 1)
280 throw RangeCheckError("TArray<T>::PackElements() - Not Allocated Array ! ");
281 if ( !force && (AvgStep() == 1) ) {
[970]282 TArray<T> ra;
283 ra.Share(*this);
[804]284 ra.SetTemp(true);
285 return(ra);
286 }
287 else {
288 TArray<T> ra(ndim_, size_, 1);
289 ra.CopyElt(*this);
290 ra.SetTemp(true);
291 return(ra);
292 }
293}
294
[785]295// SubArrays
[804]296// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
[894]297//! Extract a sub-array
298/*!
299 \param rx,ry,rz,rt,ru : range of extraction along dimensions
300 \sa Range
301 */
[785]302template <class T>
[804]303TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const
[785]304{
[804]305 if (NbDimensions() < 1)
306 throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
[785]307 uint_4 ndim = 0;
[787]308 uint_4 size[BASEARRAY_MAXNDIMS];
309 uint_4 step[BASEARRAY_MAXNDIMS];
310 uint_4 pos[BASEARRAY_MAXNDIMS];
[785]311 size[0] = rx.Size();
312 size[1] = ry.Size();
313 size[2] = rz.Size();
314 size[3] = rt.Size();
315 size[4] = ru.Size();
316
317 step[0] = rx.Step();
318 step[1] = ry.Step();
319 step[2] = rz.Step();
320 step[3] = rt.Step();
321 step[4] = ru.Step();
322
323 pos[0] = rx.Start();
324 pos[1] = ry.Start();
325 pos[2] = rz.Start();
326 pos[3] = rt.Start();
327 pos[4] = ru.Start();
328
329 ndim = ndim_;
330 TArray<T> ra;
[804]331 UpdateSubArraySizes(ra, ndim, size, pos, step);
[787]332 ra.DataBlock().Share(this->DataBlock());
[785]333 ra.SetTemp(true);
334 return(ra);
335}
336
[772]337// ...... Operation de calcul sur les tableaux ......
338// ------- Attention --------
339// Boucles normales prenant en compte les steps ....
[894]340// Possibilite de // , vectorisation
341
342//! Fill TArray with Sequence \b seq
343/*!
344 \param seq : sequence to fill the array
345 \sa Sequence
346 */
[772]347template <class T>
[813]348TArray<T>& TArray<T>::SetSeq(Sequence seq)
[772]349{
[804]350 if (NbDimensions() < 1)
[813]351 throw RangeCheckError("TArray<T>::SetSeq(Sequence ) - Not Allocated Array ! ");
[785]352 T * pe;
353 uint_8 j,k;
354 if (AvgStep() > 0) { // regularly spaced elements
355 uint_8 step = AvgStep();
356 pe = Data();
[958]357 for(k=0; k<totsize_; k++ ) pe[k*step] = (T) seq(k);
[785]358 }
359 else { // Non regular data spacing ...
[813]360 // uint_4 ka = MaxSizeKA();
361 uint_4 ka = 0;
[785]362 uint_8 step = Step(ka);
363 uint_8 gpas = Size(ka);
[813]364 uint_8 naxa = Size()/Size(ka);
365 for(j=0; j<naxa; j++) {
366 pe = mNDBlock.Begin()+Offset(ka,j);
[958]367 for(k=0; k<gpas; k++) pe[k*step] = (T) seq(j*gpas+k);
[785]368 }
369 }
[772]370 return(*this);
371}
372
373// >>>> Operations avec 2nd membre de type scalaire
374
[894]375//! Fill an array with a constant value \b x
[772]376template <class T>
[813]377TArray<T>& TArray<T>::SetT(T x)
[772]378{
[804]379 if (NbDimensions() < 1)
[813]380 throw RangeCheckError("TArray<T>::SetT(T ) - Not Allocated Array ! ");
[785]381 T * pe;
382 uint_8 j,k;
383 if (AvgStep() > 0) { // regularly spaced elements
384 uint_8 step = AvgStep();
385 uint_8 maxx = totsize_*step;
386 pe = Data();
387 for(k=0; k<maxx; k+=step ) pe[k] = x;
388 }
389 else { // Non regular data spacing ...
390 uint_4 ka = MaxSizeKA();
391 uint_8 step = Step(ka);
392 uint_8 gpas = Size(ka)*step;
[813]393 uint_8 naxa = Size()/Size(ka);
394 for(j=0; j<naxa; j++) {
395 pe = mNDBlock.Begin()+Offset(ka,j);
[785]396 for(k=0; k<gpas; k+=step) pe[k] = x;
397 }
398 }
[772]399 return(*this);
400}
401
[894]402//! Add a constant value \b x to an array
[772]403template <class T>
[804]404TArray<T>& TArray<T>::Add(T x)
[772]405{
[804]406 if (NbDimensions() < 1)
407 throw RangeCheckError("TArray<T>::Add(T ) - Not Allocated Array ! ");
[785]408 T * pe;
409 uint_8 j,k;
410 if (AvgStep() > 0) { // regularly spaced elements
411 uint_8 step = AvgStep();
412 uint_8 maxx = totsize_*step;
413 pe = Data();
414 for(k=0; k<maxx; k+=step ) pe[k] += x;
415 }
416 else { // Non regular data spacing ...
417 uint_4 ka = MaxSizeKA();
418 uint_8 step = Step(ka);
419 uint_8 gpas = Size(ka)*step;
[813]420 uint_8 naxa = Size()/Size(ka);
421 for(j=0; j<naxa; j++) {
422 pe = mNDBlock.Begin()+Offset(ka,j);
[785]423 for(k=0; k<gpas; k+=step) pe[k] += x;
424 }
425 }
[772]426 return(*this);
427}
428
[894]429//! Substract a constant value \b x to an array
[970]430/*!
431Substract a constant from the *this = *this-x
432\param fginv == true : Perfoms the inverse subtraction (*this = x-(*this))
433*/
[772]434template <class T>
[970]435TArray<T>& TArray<T>::Sub(T x, bool fginv)
[772]436{
[804]437 if (NbDimensions() < 1)
438 throw RangeCheckError("TArray<T>::Sub(T ) - Not Allocated Array ! ");
[785]439 T * pe;
440 uint_8 j,k;
441 if (AvgStep() > 0) { // regularly spaced elements
442 uint_8 step = AvgStep();
443 uint_8 maxx = totsize_*step;
444 pe = Data();
[970]445 if (fginv)
446 for(k=0; k<maxx; k+=step ) pe[k] = x-pe[k];
447 else
448 for(k=0; k<maxx; k+=step ) pe[k] -= x;
[785]449 }
450 else { // Non regular data spacing ...
451 uint_4 ka = MaxSizeKA();
452 uint_8 step = Step(ka);
453 uint_8 gpas = Size(ka)*step;
[813]454 uint_8 naxa = Size()/Size(ka);
455 for(j=0; j<naxa; j++) {
456 pe = mNDBlock.Begin()+Offset(ka,j);
[970]457 if (fginv)
458 for(k=0; k<gpas; k+=step) pe[k] = x-pe[k];
459 else
460 for(k=0; k<gpas; k+=step) pe[k] -= x;
[785]461 }
462 }
[772]463 return(*this);
464}
465
[894]466//! Multiply an array by a constant value \b x
[772]467template <class T>
[804]468TArray<T>& TArray<T>::Mul(T x)
[772]469{
[804]470 if (NbDimensions() < 1)
471 throw RangeCheckError("TArray<T>::Mul(T ) - Not Allocated Array ! ");
[785]472 T * pe;
473 uint_8 j,k;
474 if (AvgStep() > 0) { // regularly spaced elements
475 uint_8 step = AvgStep();
476 uint_8 maxx = totsize_*step;
477 pe = Data();
478 for(k=0; k<maxx; k+=step ) pe[k] *= x;
479 }
480 else { // Non regular data spacing ...
481 uint_4 ka = MaxSizeKA();
482 uint_8 step = Step(ka);
483 uint_8 gpas = Size(ka)*step;
[813]484 uint_8 naxa = Size()/Size(ka);
485 for(j=0; j<naxa; j++) {
486 pe = mNDBlock.Begin()+Offset(ka,j);
[785]487 for(k=0; k<gpas; k+=step) pe[k] *= x;
488 }
489 }
[772]490 return(*this);
491}
492
[894]493//! Divide an array by a constant value \b x
[970]494/*!
495Divide the array by a constant *this = *this/x
496\param fginv == true : Perfoms the inverse division (*this = x/(*this))
497*/
[772]498template <class T>
[970]499TArray<T>& TArray<T>::Div(T x, bool fginv)
[772]500{
[804]501 if (NbDimensions() < 1)
502 throw RangeCheckError("TArray<T>::Div(T ) - Not Allocated Array ! ");
[970]503 if (!fginv && (x == (T) 0) )
[894]504 throw MathExc("TArray<T>::Div(T ) - Divide by zero ! ");
[785]505 T * pe;
506 uint_8 j,k;
507 if (AvgStep() > 0) { // regularly spaced elements
508 uint_8 step = AvgStep();
509 uint_8 maxx = totsize_*step;
510 pe = Data();
[970]511 if (fginv)
512 for(k=0; k<maxx; k+=step ) pe[k] = x/pe[k];
513 else
514 for(k=0; k<maxx; k+=step ) pe[k] /= x;
[785]515 }
516 else { // Non regular data spacing ...
517 uint_4 ka = MaxSizeKA();
518 uint_8 step = Step(ka);
519 uint_8 gpas = Size(ka)*step;
[813]520 uint_8 naxa = Size()/Size(ka);
521 for(j=0; j<naxa; j++) {
522 pe = mNDBlock.Begin()+Offset(ka,j);
[970]523 if (fginv)
524 for(k=0; k<gpas; k+=step) pe[k] = x/pe[k];
525 else
526 for(k=0; k<gpas; k+=step) pe[k] /= x;
[785]527 }
528 }
[772]529 return(*this);
530}
531
532
[804]533
534
[772]535// >>>> Operations avec 2nd membre de type tableau
[894]536//! Add two TArrays
[772]537template <class T>
[804]538TArray<T>& TArray<T>::AddElt(const TArray<T>& a)
[772]539{
[804]540 if (NbDimensions() < 1)
541 throw RangeCheckError("TArray<T>::AddElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]542 if (!CompareSizes(a))
543 throw(SzMismatchError("TArray<T>::AddElt(const TArray<T>&) SizeMismatch")) ;
[785]544
545 T * pe;
546 const T * pea;
547 uint_8 j,k,ka;
548 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
549 uint_8 step = AvgStep();
550 uint_8 stepa = a.AvgStep();
551 uint_8 maxx = totsize_*step;
552 pe = Data();
553 pea = a.Data();
554 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] += pea[ka] ;
[772]555 }
[785]556 else { // Non regular data spacing ...
557 uint_4 ax = MaxSizeKA();
558 uint_8 step = Step(ax);
559 uint_8 stepa = a.Step(ax);
560 uint_8 gpas = Size(ax)*step;
[813]561 uint_8 naxa = Size()/Size(ax);
562 for(j=0; j<naxa; j++) {
563 pe = mNDBlock.Begin()+Offset(ax,j);
564 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[785]565 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] += pea[ka];
566 }
567 }
[772]568 return(*this);
569}
570
[894]571//! Substract two TArrays
[970]572/*!
573Substract two TArrays *this = *this-a
574\param fginv == true : Perfoms the inverse subtraction (*this = a-(*this))
575*/
[772]576template <class T>
[970]577TArray<T>& TArray<T>::SubElt(const TArray<T>& a, bool fginv)
[772]578{
[804]579 if (NbDimensions() < 1)
580 throw RangeCheckError("TArray<T>::SubElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]581 if (!CompareSizes(a))
582 throw(SzMismatchError("TArray<T>::SubElt(const TArray<T>&) SizeMismatch")) ;
[785]583
584 T * pe;
585 const T * pea;
586 uint_8 j,k,ka;
587 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
588 uint_8 step = AvgStep();
589 uint_8 stepa = a.AvgStep();
590 uint_8 maxx = totsize_*step;
591 pe = Data();
592 pea = a.Data();
[970]593 if (fginv)
594 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka]-pe[k] ;
595 else
596 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] -= pea[ka] ;
[772]597 }
[785]598 else { // Non regular data spacing ...
599 uint_4 ax = MaxSizeKA();
600 uint_8 step = Step(ax);
601 uint_8 stepa = a.Step(ax);
602 uint_8 gpas = Size(ax)*step;
[813]603 uint_8 naxa = Size()/Size(ax);
604 for(j=0; j<naxa; j++) {
605 pe = mNDBlock.Begin()+Offset(ax,j);
606 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[970]607 if (fginv)
608 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka]-pe[k] ;
609 else
610 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] -= pea[ka];
[785]611 }
612 }
[772]613 return(*this);
614}
615
[970]616
[894]617//! Multiply two TArrays (elements by elements)
[772]618template <class T>
[804]619TArray<T>& TArray<T>::MulElt(const TArray<T>& a)
[772]620{
[804]621 if (NbDimensions() < 1)
622 throw RangeCheckError("TArray<T>::MulElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]623 if (!CompareSizes(a))
624 throw(SzMismatchError("TArray<T>::MulElt(const TArray<T>&) SizeMismatch")) ;
[785]625
626 T * pe;
627 const T * pea;
628 uint_8 j,k,ka;
629 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
630 uint_8 step = AvgStep();
631 uint_8 stepa = a.AvgStep();
632 uint_8 maxx = totsize_*step;
633 pe = Data();
634 pea = a.Data();
635 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] *= pea[ka] ;
[772]636 }
[785]637 else { // Non regular data spacing ...
638 uint_4 ax = MaxSizeKA();
639 uint_8 step = Step(ax);
640 uint_8 stepa = a.Step(ax);
641 uint_8 gpas = Size(ax)*step;
[813]642 uint_8 naxa = Size()/Size(ax);
643 for(j=0; j<naxa; j++) {
644 pe = mNDBlock.Begin()+Offset(ax,j);
645 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[785]646 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] *= pea[ka];
647 }
648 }
[772]649 return(*this);
650}
651
[804]652
[894]653//! Divide two TArrays (elements by elements)
[970]654/*!
655Divide two TArrays *this = (*this)/a
656\param fginv == true : Perfoms the inverse division (*this = a/(*this))
657*/
[772]658template <class T>
[970]659TArray<T>& TArray<T>::DivElt(const TArray<T>& a, bool fginv)
[772]660{
[804]661 if (NbDimensions() < 1)
662 throw RangeCheckError("TArray<T>::DivElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]663 if (!CompareSizes(a))
664 throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&) SizeMismatch")) ;
[785]665
666 T * pe;
667 const T * pea;
668 uint_8 j,k,ka;
669 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
670 uint_8 step = AvgStep();
671 uint_8 stepa = a.AvgStep();
672 uint_8 maxx = totsize_*step;
673 pe = Data();
674 pea = a.Data();
[970]675 if (fginv)
676 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka]/pe[k];
677 else
678 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] /= pea[ka] ;
[772]679 }
[785]680 else { // Non regular data spacing ...
681 uint_4 ax = MaxSizeKA();
682 uint_8 step = Step(ax);
683 uint_8 stepa = a.Step(ax);
684 uint_8 gpas = Size(ax)*step;
[813]685 uint_8 naxa = Size()/Size(ax);
686 for(j=0; j<naxa; j++) {
687 pe = mNDBlock.Begin()+Offset(ax,j);
688 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[970]689 if (fginv)
690 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka]/pe[k];
691 else
692 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] /= pea[ka];
[785]693 }
694 }
[772]695 return(*this);
696}
697
[894]698//! Copy elements of \b a
[804]699template <class T>
700TArray<T>& TArray<T>::CopyElt(const TArray<T>& a)
701{
702 if (NbDimensions() < 1)
703 throw RangeCheckError("TArray<T>::CopyElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]704 if (!CompareSizes(a))
705 throw(SzMismatchError("TArray<T>::MultElt(const TArray<T>&) SizeMismatch")) ;
[772]706
[804]707 T * pe;
708 const T * pea;
709 uint_8 j,k,ka;
710 if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
711 uint_8 step = AvgStep();
712 uint_8 stepa = a.AvgStep();
713 uint_8 maxx = totsize_*step;
714 pe = Data();
715 pea = a.Data();
716 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka] ;
717 }
718 else { // Non regular data spacing ...
719 uint_4 ax = MaxSizeKA();
720 uint_8 step = Step(ax);
721 uint_8 stepa = a.Step(ax);
722 uint_8 gpas = Size(ax)*step;
[813]723 uint_8 naxa = Size()/Size(ax);
724 for(j=0; j<naxa; j++) {
725 pe = mNDBlock.Begin()+Offset(ax,j);
726 pea = a.DataBlock().Begin()+a.Offset(ax,j);
[804]727 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka];
728 }
729 }
730 return(*this);
731}
732
733
734// Somme et produit des elements
[894]735//! Sum all elements
[804]736template <class T>
737T TArray<T>::Sum() const
738{
739 if (NbDimensions() < 1)
740 throw RangeCheckError("TArray<T>::Sum() - Not Allocated Array ! ");
741 T ret=0;
742 const T * pe;
743 uint_8 j,k;
744 if (AvgStep() > 0) { // regularly spaced elements
745 uint_8 step = AvgStep();
746 uint_8 maxx = totsize_*step;
747 pe = Data();
748 for(k=0; k<maxx; k+=step ) ret += pe[k];
749 }
750 else { // Non regular data spacing ...
751 uint_4 ka = MaxSizeKA();
752 uint_8 step = Step(ka);
753 uint_8 gpas = Size(ka)*step;
[813]754 uint_8 naxa = Size()/Size(ka);
755 for(j=0; j<naxa; j++) {
756 pe = mNDBlock.Begin()+Offset(ka,j);
[804]757 for(k=0; k<gpas; k+=step) ret += pe[k] ;
758 }
759 }
760 return ret;
761}
762
[894]763//! Multiply all elements
[804]764template <class T>
765T TArray<T>::Product() const
766{
767 if (NbDimensions() < 1)
768 throw RangeCheckError("TArray<T>::Product() - Not Allocated Array ! ");
769 T ret=0;
770 const T * pe;
771 uint_8 j,k;
772 if (AvgStep() > 0) { // regularly spaced elements
773 uint_8 step = AvgStep();
774 uint_8 maxx = totsize_*step;
775 pe = Data();
776 for(k=0; k<maxx; k+=step ) ret *= pe[k];
777 }
778 else { // Non regular data spacing ...
779 uint_4 ka = MaxSizeKA();
780 uint_8 step = Step(ka);
781 uint_8 gpas = Size(ka)*step;
[813]782 uint_8 naxa = Size()/Size(ka);
783 for(j=0; j<naxa; j++) {
784 pe = mNDBlock.Begin()+Offset(ka,j);
[804]785 for(k=0; k<gpas; k+=step) ret *= pe[k] ;
786 }
787 }
788 return ret;
789}
790
791
792
[772]793// ----------------------------------------------------
794// Impression, etc ...
795// ----------------------------------------------------
796
[894]797//! Return a string that contain the type \b T of the array
[772]798template <class T>
[813]799string TArray<T>::InfoString() const
[772]800{
[813]801 string rs = "TArray<" ;
802 rs += typeid(T).name();
803 rs += "> ";
[787]804 return(rs);
[772]805}
806
[894]807//! Print array
808/*!
809 \param os : output stream
810 \param maxprt : maximum numer of print
811 \param si : if true, display attached DvList
812 \sa SetMaxPrint
813 */
[772]814template <class T>
815void TArray<T>::Print(ostream& os, int_4 maxprt, bool si) const
816{
817 if (maxprt < 0) maxprt = max_nprt_;
[958]818 uint_4 npr = 0;
[772]819 Show(os, si);
[850]820 if (ndim_ < 1) return;
[804]821 uint_4 k0,k1,k2,k3,k4;
[772]822 for(k4=0; k4<size_[4]; k4++) {
[785]823 if (size_[4] > 1) cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
[772]824 for(k3=0; k3<size_[3]; k3++) {
[785]825 if (size_[3] > 1) cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
[772]826 for(k2=0; k2<size_[2]; k2++) {
[785]827 if (size_[2] > 1) cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
[772]828 for(k1=0; k1<size_[1]; k1++) {
[785]829 if ( (size_[1] > 1) && (size_[0] > 10) ) cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
[772]830 for(k0=0; k0<size_[0]; k0++) {
[785]831 if(k0 > 0) os << ", ";
832 os << Elem(k0, k1, k2, k3, k4); npr++;
[958]833 if (npr >= (uint_4) maxprt) {
[772]834 if (npr < totsize_) os << "\n .... " << endl; return;
835 }
836 }
837 os << endl;
838 }
839 }
840 }
841 }
[813]842 os << endl;
[772]843}
844
845
846
847///////////////////////////////////////////////////////////////
848///////////////////////////////////////////////////////////////
849#ifdef __CXX_PRAGMA_TEMPLATES__
[804]850/*
[772]851#pragma define_template TArray<uint_1>
[804]852#pragma define_template TArray<int_2>
853#pragma define_template TArray<uint_4>
854#pragma define_template TArray<uint_8>
855*/
[772]856#pragma define_template TArray<uint_2>
857#pragma define_template TArray<int_4>
858#pragma define_template TArray<int_8>
859#pragma define_template TArray<r_4>
860#pragma define_template TArray<r_8>
861#pragma define_template TArray< complex<r_4> >
862#pragma define_template TArray< complex<r_8> >
863#endif
864
865#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
[804]866/*
867template class TArray<uint_1>;
868template class TArray<int_2>;
869template class TArray<uint_4>;
870template class TArray<uint_8>;
871*/
[772]872template class TArray<uint_2>;
873template class TArray<int_4>;
874template class TArray<int_8>;
875template class TArray<r_4>;
876template class TArray<r_8>;
877template class TArray< complex<r_4> >;
878template class TArray< complex<r_8> >;
879#endif
880
881
Note: See TracBrowser for help on using the repository browser.