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

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

doc pour preparation inverse logique de NDataBlock cmv 21/4/00

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