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

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

pb compil sur SGI avec sqrt - Reza 13/4/2000

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