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

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

documentation cmv 13/4/00

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