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

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

documentation cmv 12/4/00

File size: 24.6 KB
RevLine 
[772]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
[894]17////////////////////////// Les constructeurs / destructeurs
18
19//! Default constructor
[772]20template <class T>
21TArray<T>::TArray()
[804]22 : BaseArray() , mNDBlock()
[772]23{
24}
25
[894]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 */
[772]33template <class T>
[804]34TArray<T>::TArray(uint_4 ndim, const uint_4 * siz, uint_4 step)
35 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1))
[772]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
[894]41//! Constructor
42/*!
43 \param nx,ny,nz,nt,nu : sizes along first, second, third, fourth and fifth dimension
44 */
[772]45template <class T>
[804]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))
[772]48{
[787]49 uint_4 size[BASEARRAY_MAXNDIMS];
[772]50 size[0] = nx; size[1] = ny; size[2] = nz;
[804]51 size[3] = nt; size[4] = nu;
[772]52 int ndim = 1;
[804]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;
[772]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
[894]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 */
[772]71template <class T>
[804]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)
[772]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
[894]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 */
[772]91template <class T>
[804]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)
[772]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
[894]99//! Constructor by copy
[772]100template <class T>
101TArray<T>::TArray(const TArray<T>& a)
[804]102 : BaseArray() , mNDBlock(a.mNDBlock)
[772]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
[894]109//! Constructor by copy
110/*!
111 \param share : if true, data are shared, if false they are copied
112 */
[772]113template <class T>
114TArray<T>::TArray(const TArray<T>& a, bool share)
[804]115 : BaseArray() , mNDBlock(a.mNDBlock, share)
[772]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
[894]122//! Destructor
[772]123template <class T>
124TArray<T>::~TArray()
125{
126}
127
[894]128////////////////////////// Les methodes de copie/share
129
130//! Set array equal to \b a and return *this
[772]131template <class T>
[804]132TArray<T>& TArray<T>::Set(const TArray<T>& a)
[772]133{
134 if (this != &a) {
135 CloneOrShare(a);
[894]136 if (mInfo) {delete mInfo; mInfo = NULL;}
[772]137 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
138 }
139 return(*this);
140}
141
[894]142//! Clone array \b a
[772]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);
[894]149 if (mInfo) {delete mInfo; mInfo = NULL;}
[772]150 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
151}
152
[894]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 */
[772]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
[894]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 */
[772]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
[787]183
[894]184//! Compact dimensions in one or more is equal to 1.
[772]185template <class T>
[787]186TArray<T>& TArray<T>::CompactAllDimensions()
[772]187{
[787]188 CompactAllDim();
189 return(*this);
[772]190}
191
[894]192//! Compact dimensions if the last one is equal to 1.
[785]193template <class T>
[787]194TArray<T>& TArray<T>::CompactTrailingDimensions()
[785]195{
[787]196 CompactTrailingDim();
[785]197 return(*this);
198}
199
[894]200//! Give value (in \b double) for element at position \b ip..
[785]201template <class T>
[787]202double TArray<T>::ValueAtPosition(uint_8 ip) const
[785]203{
[787]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))) );
[785]208}
209
[894]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*/
[787]214double TArray< complex<r_4> >::ValueAtPosition(uint_8 ip) const
[785]215{
[787]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) );
[785]223}
224
[894]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*/
[787]229double TArray< complex<r_8> >::ValueAtPosition(uint_8 ip) const
[785]230{
[787]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) );
[785]238}
239
[894]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 */
[804]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
[785]265// SubArrays
[804]266// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
[894]267//! Extract a sub-array
268/*!
269 \param rx,ry,rz,rt,ru : range of extraction along dimensions
270 \sa Range
271 */
[785]272template <class T>
[804]273TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const
[785]274{
[804]275 if (NbDimensions() < 1)
276 throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
[785]277 uint_4 ndim = 0;
[787]278 uint_4 size[BASEARRAY_MAXNDIMS];
279 uint_4 step[BASEARRAY_MAXNDIMS];
280 uint_4 pos[BASEARRAY_MAXNDIMS];
[785]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;
[804]301 UpdateSubArraySizes(ra, ndim, size, pos, step);
[787]302 ra.DataBlock().Share(this->DataBlock());
[785]303 ra.SetTemp(true);
304 return(ra);
305}
306
[772]307// ...... Operation de calcul sur les tableaux ......
308// ------- Attention --------
309// Boucles normales prenant en compte les steps ....
[894]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 */
[772]317template <class T>
[813]318TArray<T>& TArray<T>::SetSeq(Sequence seq)
[772]319{
[804]320 if (NbDimensions() < 1)
[813]321 throw RangeCheckError("TArray<T>::SetSeq(Sequence ) - Not Allocated Array ! ");
[785]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 ...
[813]330 // uint_4 ka = MaxSizeKA();
331 uint_4 ka = 0;
[785]332 uint_8 step = Step(ka);
333 uint_8 gpas = Size(ka);
[813]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);
[785]338 }
339 }
[772]340 return(*this);
341}
342
343// >>>> Operations avec 2nd membre de type scalaire
344
[894]345//! Fill an array with a constant value \b x
[772]346template <class T>
[813]347TArray<T>& TArray<T>::SetT(T x)
[772]348{
[804]349 if (NbDimensions() < 1)
[813]350 throw RangeCheckError("TArray<T>::SetT(T ) - Not Allocated Array ! ");
[785]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;
[813]363 uint_8 naxa = Size()/Size(ka);
364 for(j=0; j<naxa; j++) {
365 pe = mNDBlock.Begin()+Offset(ka,j);
[785]366 for(k=0; k<gpas; k+=step) pe[k] = x;
367 }
368 }
[772]369 return(*this);
370}
371
[894]372//! Add a constant value \b x to an array
[772]373template <class T>
[804]374TArray<T>& TArray<T>::Add(T x)
[772]375{
[804]376 if (NbDimensions() < 1)
377 throw RangeCheckError("TArray<T>::Add(T ) - Not Allocated Array ! ");
[785]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;
[813]390 uint_8 naxa = Size()/Size(ka);
391 for(j=0; j<naxa; j++) {
392 pe = mNDBlock.Begin()+Offset(ka,j);
[785]393 for(k=0; k<gpas; k+=step) pe[k] += x;
394 }
395 }
[772]396 return(*this);
397}
398
[894]399//! Substract a constant value \b x to an array
[772]400template <class T>
[804]401TArray<T>& TArray<T>::Sub(T x)
[772]402{
[804]403 if (NbDimensions() < 1)
404 throw RangeCheckError("TArray<T>::Sub(T ) - Not Allocated Array ! ");
[785]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;
[813]417 uint_8 naxa = Size()/Size(ka);
418 for(j=0; j<naxa; j++) {
419 pe = mNDBlock.Begin()+Offset(ka,j);
[785]420 for(k=0; k<gpas; k+=step) pe[k] -= x;
421 }
422 }
[772]423 return(*this);
424}
425
[894]426//! Multiply an array by a constant value \b x
[772]427template <class T>
[804]428TArray<T>& TArray<T>::Mul(T x)
[772]429{
[804]430 if (NbDimensions() < 1)
431 throw RangeCheckError("TArray<T>::Mul(T ) - Not Allocated Array ! ");
[785]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;
[813]444 uint_8 naxa = Size()/Size(ka);
445 for(j=0; j<naxa; j++) {
446 pe = mNDBlock.Begin()+Offset(ka,j);
[785]447 for(k=0; k<gpas; k+=step) pe[k] *= x;
448 }
449 }
[772]450 return(*this);
451}
452
[894]453//! Divide an array by a constant value \b x
[772]454template <class T>
[804]455TArray<T>& TArray<T>::Div(T x)
[772]456{
[804]457 if (NbDimensions() < 1)
458 throw RangeCheckError("TArray<T>::Div(T ) - Not Allocated Array ! ");
[894]459 if (x == (T) 0 )
460 throw MathExc("TArray<T>::Div(T ) - Divide by zero ! ");
[785]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;
[813]473 uint_8 naxa = Size()/Size(ka);
474 for(j=0; j<naxa; j++) {
475 pe = mNDBlock.Begin()+Offset(ka,j);
[785]476 for(k=0; k<gpas; k+=step) pe[k] /= x;
477 }
478 }
[772]479 return(*this);
480}
481
482
[894]483//! Inverse substract : A = \b x - A
[804]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;
[813]501 uint_8 naxa = Size()/Size(ka);
502 for(j=0; j<naxa; j++) {
503 pe = mNDBlock.Begin()+Offset(ka,j);
[804]504 for(k=0; k<gpas; k+=step) pe[k] = x-pe[k];
505 }
506 }
507 return(*this);
508}
509
[894]510//! Inverse Divide : A(i,j,...) = x / A(i,j,...)
[804]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;
[813]528 uint_8 naxa = Size()/Size(ka);
529 for(j=0; j<naxa; j++) {
530 pe = mNDBlock.Begin()+Offset(ka,j);
[804]531 for(k=0; k<gpas; k+=step) pe[k] = x/pe[k];
532 }
533 }
534 return(*this);
535}
536
537
[772]538// >>>> Operations avec 2nd membre de type tableau
[894]539//! Add two TArrays
[772]540template <class T>
[804]541TArray<T>& TArray<T>::AddElt(const TArray<T>& a)
[772]542{
[804]543 if (NbDimensions() < 1)
544 throw RangeCheckError("TArray<T>::AddElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]545 if (!CompareSizes(a))
546 throw(SzMismatchError("TArray<T>::AddElt(const TArray<T>&) SizeMismatch")) ;
[785]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] ;
[772]558 }
[785]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;
[813]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);
[785]568 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] += pea[ka];
569 }
570 }
[772]571 return(*this);
572}
573
[894]574//! Substract two TArrays
[772]575template <class T>
[804]576TArray<T>& TArray<T>::SubElt(const TArray<T>& a)
[772]577{
[804]578 if (NbDimensions() < 1)
579 throw RangeCheckError("TArray<T>::SubElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]580 if (!CompareSizes(a))
581 throw(SzMismatchError("TArray<T>::SubElt(const TArray<T>&) SizeMismatch")) ;
[785]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] ;
[772]593 }
[785]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;
[813]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);
[785]603 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] -= pea[ka];
604 }
605 }
[772]606 return(*this);
607}
608
[894]609//! Multiply two TArrays (elements by elements)
[772]610template <class T>
[804]611TArray<T>& TArray<T>::MulElt(const TArray<T>& a)
[772]612{
[804]613 if (NbDimensions() < 1)
614 throw RangeCheckError("TArray<T>::MulElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]615 if (!CompareSizes(a))
616 throw(SzMismatchError("TArray<T>::MulElt(const TArray<T>&) SizeMismatch")) ;
[785]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] ;
[772]628 }
[785]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;
[813]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);
[785]638 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] *= pea[ka];
639 }
640 }
[772]641 return(*this);
642}
643
[804]644
[894]645//! Divide two TArrays (elements by elements)
[772]646template <class T>
647TArray<T>& TArray<T>::DivElt(const TArray<T>& a)
648{
[804]649 if (NbDimensions() < 1)
650 throw RangeCheckError("TArray<T>::DivElt(const TArray<T>& ) - Not Allocated Array ! ");
[813]651 if (!CompareSizes(a))
652 throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&) SizeMismatch")) ;
[785]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] ;
[772]664 }
[785]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;
[813]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);
[785]674 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] /= pea[ka];
675 }
676 }
[772]677 return(*this);
678}
679
[894]680//! Copy elements of \b a
[804]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 ! ");
[813]686 if (!CompareSizes(a))
687 throw(SzMismatchError("TArray<T>::MultElt(const TArray<T>&) SizeMismatch")) ;
[772]688
[804]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;
[813]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);
[804]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
[894]717//! Sum all elements
[804]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;
[813]736 uint_8 naxa = Size()/Size(ka);
737 for(j=0; j<naxa; j++) {
738 pe = mNDBlock.Begin()+Offset(ka,j);
[804]739 for(k=0; k<gpas; k+=step) ret += pe[k] ;
740 }
741 }
742 return ret;
743}
744
[894]745//! Multiply all elements
[804]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;
[813]764 uint_8 naxa = Size()/Size(ka);
765 for(j=0; j<naxa; j++) {
766 pe = mNDBlock.Begin()+Offset(ka,j);
[804]767 for(k=0; k<gpas; k+=step) ret *= pe[k] ;
768 }
769 }
770 return ret;
771}
772
773
774
[772]775// ----------------------------------------------------
776// Impression, etc ...
777// ----------------------------------------------------
778
[894]779//! Return a string that contain the type \b T of the array
[772]780template <class T>
[813]781string TArray<T>::InfoString() const
[772]782{
[813]783 string rs = "TArray<" ;
784 rs += typeid(T).name();
785 rs += "> ";
[787]786 return(rs);
[772]787}
788
[894]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 */
[772]796template <class T>
797void TArray<T>::Print(ostream& os, int_4 maxprt, bool si) const
798{
799 if (maxprt < 0) maxprt = max_nprt_;
[804]800 int_4 npr = 0;
[772]801 Show(os, si);
[850]802 if (ndim_ < 1) return;
[804]803 uint_4 k0,k1,k2,k3,k4;
[772]804 for(k4=0; k4<size_[4]; k4++) {
[785]805 if (size_[4] > 1) cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
[772]806 for(k3=0; k3<size_[3]; k3++) {
[785]807 if (size_[3] > 1) cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
[772]808 for(k2=0; k2<size_[2]; k2++) {
[785]809 if (size_[2] > 1) cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
[772]810 for(k1=0; k1<size_[1]; k1++) {
[785]811 if ( (size_[1] > 1) && (size_[0] > 10) ) cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
[772]812 for(k0=0; k0<size_[0]; k0++) {
[785]813 if(k0 > 0) os << ", ";
814 os << Elem(k0, k1, k2, k3, k4); npr++;
[772]815 if (npr >= maxprt) {
816 if (npr < totsize_) os << "\n .... " << endl; return;
817 }
818 }
819 os << endl;
820 }
821 }
822 }
823 }
[813]824 os << endl;
[772]825}
826
[894]827//! Clone if \b a is not temporary, share if temporary
[772]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
[894]836//! Share data with a
[772]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
[785]846
[772]847///////////////////////////////////////////////////////////////
848///////////////////////////////////////////////////////////////
849#ifdef __CXX_PRAGMA_TEMPLATES__
[804]850/*
[772]851#pragma define_template TArray<uint_1>
[804]852#pragma define_template TArray<int_2>
853#pragma define_template TArray<uint_4>
854#pragma define_template TArray<uint_8>
855*/
[772]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)
[804]866/*
867template class TArray<uint_1>;
868template class TArray<int_2>;
869template class TArray<uint_4>;
870template class TArray<uint_8>;
871*/
[772]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.