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
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 <math.h>
8#include "pexceptions.h"
9#include "tarray.h"
10
11/*!
12 \class SOPHYA::TArray
13 \ingroup TArray
14 Class for template arrays
15
16 This class implements arrays of dimensions up to
17 \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS"
18*/
19
20// -------------------------------------------------------
21// Methodes de la classe
22// -------------------------------------------------------
23
24////////////////////////// Les constructeurs / destructeurs
25
26//! Default constructor
27template <class T>
28TArray<T>::TArray()
29 : BaseArray() , mNDBlock()
30{
31}
32
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 */
40template <class T>
41TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, uint_4 step)
42 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1))
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
48//! Constructor
49/*!
50 \param nx,ny,nz,nt,nu : sizes along first, second, third, fourth and fifth dimension
51 */
52template <class T>
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))
55{
56 uint_4 size[BASEARRAY_MAXNDIMS];
57 size[0] = nx; size[1] = ny; size[2] = nz;
58 size[3] = nt; size[4] = nu;
59 int ndim = 1;
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;
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
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 */
78template <class T>
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)
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
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 */
98template <class T>
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)
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
106//! Constructor by copy
107/*! \sa NDataBlock::NDataBlock(const NDataBlock<T>&) */
108template <class T>
109TArray<T>::TArray(const TArray<T>& a)
110 : BaseArray() , mNDBlock(a.mNDBlock)
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
117//! Constructor by copy
118/*!
119 \param share : if true, data are shared, if false they are copied
120 */
121template <class T>
122TArray<T>::TArray(const TArray<T>& a, bool share)
123 : BaseArray() , mNDBlock(a.mNDBlock, share)
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
130//! Destructor
131template <class T>
132TArray<T>::~TArray()
133{
134}
135
136////////////////////////// Les methodes de copie/share
137
138//! Set array equal to \b a and return *this
139template <class T>
140TArray<T>& TArray<T>::Set(const TArray<T>& a)
141{
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);
147 return(*this);
148}
149
150//! Clone array \b a
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);
157 if (mInfo) {delete mInfo; mInfo = NULL;}
158 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
159}
160
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
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 */
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
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 */
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
210
211//! Compact dimensions in one or more is equal to 1.
212template <class T>
213TArray<T>& TArray<T>::CompactAllDimensions()
214{
215 CompactAllDim();
216 return(*this);
217}
218
219//! Compact dimensions if the last one is equal to 1.
220template <class T>
221TArray<T>& TArray<T>::CompactTrailingDimensions()
222{
223 CompactTrailingDim();
224 return(*this);
225}
226
227inline double _SqrtRz_(double x) { return sqrt(x); } // Pb avec SGI-CC - $CHECK$ - Reza 04/2000
228
229//! Give value (in \b double) for element at position \b ip..
230template <class T>
231double TArray<T>::ValueAtPosition(uint_8 ip) const
232{
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))) );
237}
238
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*/
243double TArray< complex<r_4> >::ValueAtPosition(uint_8 ip) const
244{
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());
251 return( _SqrtRz_(cr*cr+ci*ci) );
252}
253
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*/
258double TArray< complex<r_8> >::ValueAtPosition(uint_8 ip) const
259{
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());
266 return( _SqrtRz_(cr*cr+ci*ci) );
267}
268
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 */
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) ) {
282 TArray<T> ra;
283 ra.Share(*this);
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
295// SubArrays
296// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
297//! Extract a sub-array
298/*!
299 \param rx,ry,rz,rt,ru : range of extraction along dimensions
300 \sa Range
301 */
302template <class T>
303TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const
304{
305 if (NbDimensions() < 1)
306 throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
307 uint_4 ndim = 0;
308 uint_4 size[BASEARRAY_MAXNDIMS];
309 uint_4 step[BASEARRAY_MAXNDIMS];
310 uint_4 pos[BASEARRAY_MAXNDIMS];
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;
331 UpdateSubArraySizes(ra, ndim, size, pos, step);
332 ra.DataBlock().Share(this->DataBlock());
333 ra.SetTemp(true);
334 return(ra);
335}
336
337// ...... Operation de calcul sur les tableaux ......
338// ------- Attention --------
339// Boucles normales prenant en compte les steps ....
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 */
347template <class T>
348TArray<T>& TArray<T>::SetSeq(Sequence seq)
349{
350 if (NbDimensions() < 1)
351 throw RangeCheckError("TArray<T>::SetSeq(Sequence ) - Not Allocated Array ! ");
352 T * pe;
353 uint_8 j,k;
354 if (AvgStep() > 0) { // regularly spaced elements
355 uint_8 step = AvgStep();
356 pe = Data();
357 for(k=0; k<totsize_; k++ ) pe[k*step] = (T) seq(k);
358 }
359 else { // Non regular data spacing ...
360 // uint_4 ka = MaxSizeKA();
361 uint_4 ka = 0;
362 uint_8 step = Step(ka);
363 uint_8 gpas = Size(ka);
364 uint_8 naxa = Size()/Size(ka);
365 for(j=0; j<naxa; j++) {
366 pe = mNDBlock.Begin()+Offset(ka,j);
367 for(k=0; k<gpas; k++) pe[k*step] = (T) seq(j*gpas+k);
368 }
369 }
370 return(*this);
371}
372
373// >>>> Operations avec 2nd membre de type scalaire
374
375//! Fill an array with a constant value \b x
376template <class T>
377TArray<T>& TArray<T>::SetT(T x)
378{
379 if (NbDimensions() < 1)
380 throw RangeCheckError("TArray<T>::SetT(T ) - Not Allocated Array ! ");
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;
393 uint_8 naxa = Size()/Size(ka);
394 for(j=0; j<naxa; j++) {
395 pe = mNDBlock.Begin()+Offset(ka,j);
396 for(k=0; k<gpas; k+=step) pe[k] = x;
397 }
398 }
399 return(*this);
400}
401
402//! Add a constant value \b x to an array
403template <class T>
404TArray<T>& TArray<T>::Add(T x)
405{
406 if (NbDimensions() < 1)
407 throw RangeCheckError("TArray<T>::Add(T ) - Not Allocated Array ! ");
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;
420 uint_8 naxa = Size()/Size(ka);
421 for(j=0; j<naxa; j++) {
422 pe = mNDBlock.Begin()+Offset(ka,j);
423 for(k=0; k<gpas; k+=step) pe[k] += x;
424 }
425 }
426 return(*this);
427}
428
429//! Substract a constant value \b x to an array
430/*!
431Substract a constant from the *this = *this-x
432\param fginv == true : Perfoms the inverse subtraction (*this = x-(*this))
433*/
434template <class T>
435TArray<T>& TArray<T>::Sub(T x, bool fginv)
436{
437 if (NbDimensions() < 1)
438 throw RangeCheckError("TArray<T>::Sub(T ) - Not Allocated Array ! ");
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();
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;
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;
454 uint_8 naxa = Size()/Size(ka);
455 for(j=0; j<naxa; j++) {
456 pe = mNDBlock.Begin()+Offset(ka,j);
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;
461 }
462 }
463 return(*this);
464}
465
466//! Multiply an array by a constant value \b x
467template <class T>
468TArray<T>& TArray<T>::Mul(T x)
469{
470 if (NbDimensions() < 1)
471 throw RangeCheckError("TArray<T>::Mul(T ) - Not Allocated Array ! ");
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;
484 uint_8 naxa = Size()/Size(ka);
485 for(j=0; j<naxa; j++) {
486 pe = mNDBlock.Begin()+Offset(ka,j);
487 for(k=0; k<gpas; k+=step) pe[k] *= x;
488 }
489 }
490 return(*this);
491}
492
493//! Divide an array by a constant value \b x
494/*!
495Divide the array by a constant *this = *this/x
496\param fginv == true : Perfoms the inverse division (*this = x/(*this))
497*/
498template <class T>
499TArray<T>& TArray<T>::Div(T x, bool fginv)
500{
501 if (NbDimensions() < 1)
502 throw RangeCheckError("TArray<T>::Div(T ) - Not Allocated Array ! ");
503 if (!fginv && (x == (T) 0) )
504 throw MathExc("TArray<T>::Div(T ) - Divide by zero ! ");
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();
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;
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;
520 uint_8 naxa = Size()/Size(ka);
521 for(j=0; j<naxa; j++) {
522 pe = mNDBlock.Begin()+Offset(ka,j);
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;
527 }
528 }
529 return(*this);
530}
531
532
533
534
535// >>>> Operations avec 2nd membre de type tableau
536//! Add two TArrays
537template <class T>
538TArray<T>& TArray<T>::AddElt(const TArray<T>& a)
539{
540 if (NbDimensions() < 1)
541 throw RangeCheckError("TArray<T>::AddElt(const TArray<T>& ) - Not Allocated Array ! ");
542 if (!CompareSizes(a))
543 throw(SzMismatchError("TArray<T>::AddElt(const TArray<T>&) SizeMismatch")) ;
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] ;
555 }
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;
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);
565 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] += pea[ka];
566 }
567 }
568 return(*this);
569}
570
571//! Substract two TArrays
572/*!
573Substract two TArrays *this = *this-a
574\param fginv == true : Perfoms the inverse subtraction (*this = a-(*this))
575*/
576template <class T>
577TArray<T>& TArray<T>::SubElt(const TArray<T>& a, bool fginv)
578{
579 if (NbDimensions() < 1)
580 throw RangeCheckError("TArray<T>::SubElt(const TArray<T>& ) - Not Allocated Array ! ");
581 if (!CompareSizes(a))
582 throw(SzMismatchError("TArray<T>::SubElt(const TArray<T>&) SizeMismatch")) ;
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();
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] ;
597 }
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;
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);
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];
611 }
612 }
613 return(*this);
614}
615
616
617//! Multiply two TArrays (elements by elements)
618template <class T>
619TArray<T>& TArray<T>::MulElt(const TArray<T>& a)
620{
621 if (NbDimensions() < 1)
622 throw RangeCheckError("TArray<T>::MulElt(const TArray<T>& ) - Not Allocated Array ! ");
623 if (!CompareSizes(a))
624 throw(SzMismatchError("TArray<T>::MulElt(const TArray<T>&) SizeMismatch")) ;
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] ;
636 }
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;
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);
646 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] *= pea[ka];
647 }
648 }
649 return(*this);
650}
651
652
653//! Divide two TArrays (elements by elements)
654/*!
655Divide two TArrays *this = (*this)/a
656\param fginv == true : Perfoms the inverse division (*this = a/(*this))
657*/
658template <class T>
659TArray<T>& TArray<T>::DivElt(const TArray<T>& a, bool fginv)
660{
661 if (NbDimensions() < 1)
662 throw RangeCheckError("TArray<T>::DivElt(const TArray<T>& ) - Not Allocated Array ! ");
663 if (!CompareSizes(a))
664 throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&) SizeMismatch")) ;
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();
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] ;
679 }
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;
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);
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];
693 }
694 }
695 return(*this);
696}
697
698//! Copy elements of \b a
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 ! ");
704 if (!CompareSizes(a))
705 throw(SzMismatchError("TArray<T>::MultElt(const TArray<T>&) SizeMismatch")) ;
706
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;
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);
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
735//! Sum all elements
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;
754 uint_8 naxa = Size()/Size(ka);
755 for(j=0; j<naxa; j++) {
756 pe = mNDBlock.Begin()+Offset(ka,j);
757 for(k=0; k<gpas; k+=step) ret += pe[k] ;
758 }
759 }
760 return ret;
761}
762
763//! Multiply all elements
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;
782 uint_8 naxa = Size()/Size(ka);
783 for(j=0; j<naxa; j++) {
784 pe = mNDBlock.Begin()+Offset(ka,j);
785 for(k=0; k<gpas; k+=step) ret *= pe[k] ;
786 }
787 }
788 return ret;
789}
790
791
792
793// ----------------------------------------------------
794// Impression, etc ...
795// ----------------------------------------------------
796
797//! Return a string that contain the type \b T of the array
798template <class T>
799string TArray<T>::InfoString() const
800{
801 string rs = "TArray<" ;
802 rs += typeid(T).name();
803 rs += "> ";
804 return(rs);
805}
806
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 */
814template <class T>
815void TArray<T>::Print(ostream& os, int_4 maxprt, bool si) const
816{
817 if (maxprt < 0) maxprt = max_nprt_;
818 uint_4 npr = 0;
819 Show(os, si);
820 if (ndim_ < 1) return;
821 uint_4 k0,k1,k2,k3,k4;
822 for(k4=0; k4<size_[4]; k4++) {
823 if (size_[4] > 1) cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
824 for(k3=0; k3<size_[3]; k3++) {
825 if (size_[3] > 1) cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
826 for(k2=0; k2<size_[2]; k2++) {
827 if (size_[2] > 1) cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
828 for(k1=0; k1<size_[1]; k1++) {
829 if ( (size_[1] > 1) && (size_[0] > 10) ) cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
830 for(k0=0; k0<size_[0]; k0++) {
831 if(k0 > 0) os << ", ";
832 os << Elem(k0, k1, k2, k3, k4); npr++;
833 if (npr >= (uint_4) maxprt) {
834 if (npr < totsize_) os << "\n .... " << endl; return;
835 }
836 }
837 os << endl;
838 }
839 }
840 }
841 }
842 os << endl;
843}
844
845
846
847///////////////////////////////////////////////////////////////
848///////////////////////////////////////////////////////////////
849#ifdef __CXX_PRAGMA_TEMPLATES__
850/*
851#pragma define_template TArray<uint_1>
852#pragma define_template TArray<int_2>
853#pragma define_template TArray<uint_4>
854#pragma define_template TArray<uint_8>
855*/
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)
866/*
867template class TArray<uint_1>;
868template class TArray<int_2>;
869template class TArray<uint_4>;
870template class TArray<uint_8>;
871*/
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.