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

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

Compil CXX (ConvertAndCopy()) - Reza+CMV 24/7/2000

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