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

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

documentation cmv 12/4/00

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