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

Last change on this file since 2569 was 2569, checked in by ansari, 21 years ago

Corrections bug apres modifs methods Add/Sub/Mul/DivCst(x,res) - Reza 27 Juillet 2004

File size: 38.7 KB
Line 
1// template array class for numerical types
2// R. Ansari, C.Magneville 03/2000
3
4#include "machdefs.h"
5#include <stdio.h>
6#include <stdlib.h>
7#include <math.h>
8#include "pexceptions.h"
9#include "tarray.h"
10
11/*!
12 \class SOPHYA::TArray
13 \ingroup TArray
14 Class for template arrays with numerical data types (int, float, complex).
15
16 This class implements arrays with number of dimensions up to
17 \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS"
18
19 Standard arithmetic operations on numerical arrays are implemented,
20 as well as sub-array manipulation services.
21 \b Array is a typedef for double precision floating point arrays ( TArray<r_8> )
22 \sa SOPHYA::Range
23 \sa SOPHYA::Sequence
24 \sa SOPHYA::MathArray
25
26 \code
27 #include "array.h"
28 // ...
29 // Creating and initialising a 1-D array of integers
30 TArray<int> ia(5);
31 EnumeratedSequence es;
32 es = 24, 35, 46, 57, 68;
33 ia = es;
34 cout << "Array<int> ia = " << ia;
35 // 2-D array of floats
36 TArray<r_4> b(6,4), c(6,4);
37 // Initializing b with a constant
38 b = 2.71828;
39 // Filling c with random numbers
40 c = RandomSequence();
41 // Arithmetic operations
42 TArray<r_4> d = b+0.3f*c;
43 cout << "Array<float> d = " << d;
44 \endcode
45
46*/
47
48/*! \ingroup TArray
49 \typedef sa_size_t
50 \brief Array index range and size, defined to be a 4-byte or 8-byte integer
51*/
52
53// -------------------------------------------------------
54// Methodes de la classe
55// -------------------------------------------------------
56
57////////////////////////// Les constructeurs / destructeurs
58
59//! Default constructor
60template <class T>
61TArray<T>::TArray()
62 : BaseArray() , mNDBlock()
63{
64}
65
66//! Constructor
67/*!
68 \param ndim : number of dimensions (less or equal to
69 \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS")
70 \param siz[ndim] : size along each dimension
71 \param step : step (same for all dimensions)
72 \param fzero : if \b true , set array elements to zero
73 */
74template <class T>
75TArray<T>::TArray(int_4 ndim, const sa_size_t * siz, sa_size_t step, bool fzero)
76 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), fzero)
77{
78 string exmsg = "TArray<T>::TArray(int_4, sa_size_t *, sa_size_t)";
79 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
80}
81
82//! Constructor
83/*!
84 \param nx,ny,nz,nt,nu : sizes along first, second, third, fourth and fifth dimension
85 \param fzero : if \b true , set array elements to zero
86 */
87template <class T>
88TArray<T>::TArray(sa_size_t nx, sa_size_t ny, sa_size_t nz, sa_size_t nt, sa_size_t nu, bool fzero)
89 : BaseArray() , mNDBlock(nx*((ny>0)?ny:1)*((nz>0)?nz:1)*((nt>0)?nt:1)*((nu>0)?nu:1))
90{
91 sa_size_t size[BASEARRAY_MAXNDIMS];
92 size[0] = nx; size[1] = ny; size[2] = nz;
93 size[3] = nt; size[4] = nu;
94 int_4 ndim = 1;
95 if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) && (size[4] > 0) ) ndim = 5;
96 else if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) ) ndim = 4;
97 else if ((size[1] > 0) && (size[2] > 0)) ndim = 3;
98 else if (size[1] > 0) ndim = 2;
99 else ndim = 1;
100 string exmsg = "TArray<T>::TArray(sa_size_t, sa_size_t, sa_size_t, sa_size_t, sa_size_t)";
101 if (!UpdateSizes(ndim, size, 1, 0, exmsg)) throw( ParmError(exmsg) );
102}
103
104//! Constructor
105/*!
106 \param ndim : number of dimensions
107 \param siz[ndim] : size along each dimension
108 \param db : datas are given by this NDataBlock
109 \param share : if true, data are shared, if false they are copied
110 \param step : step (same for all dimensions) in data block
111 \param offset : offset for first element in data block
112 */
113template <class T>
114TArray<T>::TArray(int_4 ndim, const sa_size_t * siz, NDataBlock<T> & db, bool share, sa_size_t step, sa_size_t offset)
115 : BaseArray() , mNDBlock(db, share)
116{
117 string exmsg = "TArray<T>::TArray(int_4, sa_size_t *, NDataBlock<T> & ... )";
118 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
119 if (mNDBlock.Size() < ComputeTotalSize(ndim, siz, step, offset)) {
120 exmsg += " DataBlock.Size() < ComputeTotalSize(...) " ;
121 throw( ParmError(exmsg) );
122 }
123}
124
125//! Constructor
126/*!
127 \param ndim : number of dimensions
128 \param siz[ndim] : size along each dimension
129 \param values : datas are given by this pointer
130 \param share : if true, data are shared, if false they are copied
131 \param step : step (same for all dimensions) in data block
132 \param offset : offset for first element in data block
133 \param br : if not NULL, dats are bridge with other datas
134 \sa NDataBlock
135 */
136template <class T>
137TArray<T>::TArray(int_4 ndim, const sa_size_t * siz, T* values, sa_size_t step, sa_size_t offset, Bridge* br)
138 : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), values, br)
139{
140 string exmsg = "TArray<T>::TArray(int_4, sa_size_t *, T* ... )";
141 if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) );
142}
143
144//! Constructor by copy
145/*!
146 \warning datas are \b SHARED with \b a.
147 \sa NDataBlock::NDataBlock(const NDataBlock<T>&)
148 */
149template <class T>
150TArray<T>::TArray(const TArray<T>& a)
151 : BaseArray() , mNDBlock(a.mNDBlock)
152{
153 string exmsg = "TArray<T>::TArray(const TArray<T>&)";
154 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
155 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
156}
157
158//! Constructor by copy
159/*!
160 \param share : if true, data are shared, if false they are copied
161 */
162template <class T>
163TArray<T>::TArray(const TArray<T>& a, bool share)
164 : BaseArray() , mNDBlock(a.mNDBlock, share)
165{
166 if (a.NbDimensions() == 0) return;
167 string exmsg = "TArray<T>::TArray(const TArray<T>&, bool)";
168 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
169 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
170}
171
172//! Constructor with size and contents copied (after conversion) from a different type TArray
173template <class T>
174TArray<T>::TArray(const BaseArray& a)
175 : BaseArray() , mNDBlock()
176{
177 if (a.NbDimensions() == 0) return;
178 string exmsg = "TArray<T>::TArray(const BaseArray&)";
179 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
180 mNDBlock.ReSize(totsize_);
181 // if (a.mInfo) mInfo = new DVList(*(a.mInfo)); - pb protected !
182 ConvertAndCopyElt(a);
183}
184
185//! Destructor
186template <class T>
187TArray<T>::~TArray()
188{
189}
190
191////////////////////////// Les methodes de copie/share
192
193//! Set array equal to \b a and return *this
194/*!
195 If the array is already allocated, CopyElt() is called
196 for checking that the two arrays have the same size and
197 for copying the array element values. For non allocated
198 arrays, CloneOrShare() is called. The array memory
199 organization is also copied from \b a.
200 \warning Datas are copied (cloned) from \b a.
201 \sa CopyElt
202 \sa CloneOrShare
203 \sa NDataBlock::operator=(const NDataBlock<T>&)
204*/
205template <class T>
206TArray<T>& TArray<T>::Set(const TArray<T>& a)
207{
208 if (this == &a) return(*this);
209 if (a.NbDimensions() < 1)
210 throw RangeCheckError("TArray<T>::Set(a ) - Array a not allocated ! ");
211 if (NbDimensions() < 1) CloneOrShare(a);
212 else CopyElt(a);
213 return(*this);
214}
215
216//! Set array elements equal to the \b a array elements, after conversion
217template <class T>
218TArray<T>& TArray<T>::SetBA(const BaseArray& a)
219{
220 if (this == &a) return(*this);
221 if (a.NbDimensions() < 1)
222 throw RangeCheckError("TArray<T>::SetBA(a ) - Array a not allocated ! ");
223 if (NbDimensions() < 1) {
224 string exmsg = "TArray<T>::SetBA(const BaseArray& a)";
225 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
226 mNDBlock.ReSize(totsize_);
227 }
228 ConvertAndCopyElt(a);
229 return(*this);
230}
231
232//! Clone array \b a
233template <class T>
234void TArray<T>::Clone(const TArray<T>& a)
235{
236 string exmsg = "TArray<T>::Clone()";
237 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
238 mNDBlock.Clone(a.mNDBlock);
239 if (mInfo) {delete mInfo; mInfo = NULL;}
240 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
241}
242
243//! Clone if \b a is not temporary, share if temporary
244/*! \sa NDataBlock::CloneOrShare(const NDataBlock<T>&) */
245template <class T>
246void TArray<T>::CloneOrShare(const TArray<T>& a)
247{
248 string exmsg = "TArray<T>::CloneOrShare()";
249 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
250 mNDBlock.CloneOrShare(a.mNDBlock);
251 if (mInfo) {delete mInfo; mInfo = NULL;}
252 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
253}
254
255//! Share data with a
256template <class T>
257void TArray<T>::Share(const TArray<T>& a)
258{
259 string exmsg = "TArray<T>::Share()";
260 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
261 mNDBlock.Share(a.mNDBlock);
262 if (mInfo) {delete mInfo; mInfo = NULL;}
263 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
264}
265
266
267//! Sets or changes the array size
268/*!
269 \param ndim : number of dimensions
270 \param siz[ndim] : size along each dimension
271 \param step : step (same for all dimensions)
272 \param fzero : if \b true , set array elements to zero
273 */
274template <class T>
275void TArray<T>::ReSize(int_4 ndim, sa_size_t * siz, sa_size_t step, bool fzero)
276{
277 if (arrtype_ != 0) {
278 if (ndim != 2)
279 throw( ParmError("TArray<T>::ReSize(ndim!=2,...) for Matrix" ) );
280 if ((arrtype_ == 2) && (siz[0] > 1) && (siz[1] > 1))
281 throw( ParmError("TArray<T>::ReSize(,siz[0]>1 && size[1]>1) for Vector" ) );
282 }
283 string exmsg = "TArray<T>::ReSize(int_4 ...)";
284 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
285 mNDBlock.ReSize(totsize_, fzero);
286}
287
288//! Sets or changes the array size.
289/*!
290 The array size and memory layout are copied from the array \b a.
291 \param a : Array used as template for setting the size and memory layout.
292 \param pack : if \b true , create a packed array, else same memory layout as \b a.
293 \param fzero : if \b true , set array elements to zero
294 */
295template <class T>
296void TArray<T>::ReSize(const BaseArray& a, bool pack, bool fzero)
297{
298 if (arrtype_ != 0) {
299 if (a.NbDimensions() != 2)
300 throw( ParmError("TArray<T>::ReSize(a.NbDimensions()!=2,...) for Matrix" ) );
301 if ((arrtype_ == 2) && (a.Size(0) > 1) && (a.Size(1) > 1))
302 throw( ParmError("TArray<T>::ReSize(a.Size(0)>1 && a.Size(1)>1) for Vector" ) );
303 }
304 string exmsg = "TArray<T>::ReSize(const TArray<T>&)";
305 if (pack) {
306 sa_size_t siz[BASEARRAY_MAXNDIMS];
307 int ksz;
308 for(ksz=0; ksz<a.NbDimensions(); ksz++) siz[ksz] = a.Size(ksz);
309 for(ksz=a.NbDimensions(); ksz<BASEARRAY_MAXNDIMS; ksz++) siz[ksz] = 1;
310 if (!UpdateSizes(a.NbDimensions(), siz, 1, 0, exmsg)) throw( ParmError(exmsg) );
311 SetMemoryMapping(a.GetMemoryMapping());
312 mNDBlock.ReSize(totsize_, fzero);
313 }
314 else {
315 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
316 mNDBlock.ReSize(totsize_);
317 }
318}
319
320//! Re-allocate space for array
321/*!
322 \param ndim : number of dimensions
323 \param siz[ndim] : size along each dimension
324 \param step : step (same for all dimensions)
325 \param force : if true re-allocation is forced, if not it occurs
326 only if the required space is greater than the old one.
327 */
328template <class T>
329void TArray<T>::Realloc(int_4 ndim, sa_size_t * siz, sa_size_t step, bool force)
330{
331 if (arrtype_ != 0) {
332 if (ndim != 2)
333 throw( ParmError("TArray<T>::Realloc(ndim!=2,...) for Matrix" ) );
334 if ((arrtype_ == 2) && (siz[0] > 1) && (siz[1] > 1))
335 throw( ParmError("TArray<T>::Realloc(,siz[0]>1 && size[1]>1) for Vector" ) );
336 }
337 string exmsg = "TArray<T>::Realloc()";
338 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
339 mNDBlock.Realloc(totsize_, force);
340}
341
342
343//! Compact dimensions in one or more is equal to 1.
344template <class T>
345TArray<T>& TArray<T>::CompactAllDimensions()
346{
347 CompactAllDim();
348 return(*this);
349}
350
351//! Compact dimensions if the last one is equal to 1.
352template <class T>
353TArray<T>& TArray<T>::CompactTrailingDimensions()
354{
355 CompactTrailingDim();
356 return(*this);
357}
358
359//! Give value (in \b double) for element at position \b ip..
360template <class T>
361MuTyV & TArray<T>::ValueAtPosition(sa_size_t ip) const
362{
363#ifdef SO_BOUNDCHECKING
364 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(sa_size_t ip) Out-of-bound Error") );
365#endif
366 my_mtv = *(mNDBlock.Begin()+Offset(ip));
367 return( my_mtv );
368}
369
370//! Return array with elements packed
371/*!
372 \param force : if true, pack elements in a new array.
373 If false and array is already packed, return
374 an array that share data with the current one.
375 \return packed array
376 */
377template <class T>
378TArray<T> TArray<T>::PackElements(bool force) const
379{
380 if (NbDimensions() < 1)
381 throw RangeCheckError("TArray<T>::PackElements() - Not Allocated Array ! ");
382 if ( !force && (AvgStep() == 1) ) {
383 TArray<T> ra;
384 ra.Share(*this);
385 ra.SetTemp(true);
386 return(ra);
387 }
388 else {
389 TArray<T> ra(ndim_, size_, 1);
390 ra.CopyElt(*this);
391 ra.SetTemp(true);
392 return(ra);
393 }
394}
395
396// SubArrays
397// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
398//! Extract a sub-array
399/*!
400 \param rx,ry,rz,rt,ru : range of extraction along dimensions
401 \sa Range
402 */
403template <class T>
404TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const
405{
406 if (NbDimensions() < 1)
407 throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
408 int_4 ndim = 0;
409 sa_size_t size[BASEARRAY_MAXNDIMS];
410 sa_size_t step[BASEARRAY_MAXNDIMS];
411 sa_size_t pos[BASEARRAY_MAXNDIMS];
412 size[0] = rx.Size();
413 size[1] = ry.Size();
414 size[2] = rz.Size();
415 size[3] = rt.Size();
416 size[4] = ru.Size();
417
418 step[0] = rx.Step();
419 step[1] = ry.Step();
420 step[2] = rz.Step();
421 step[3] = rt.Step();
422 step[4] = ru.Step();
423
424 pos[0] = rx.Start();
425 pos[1] = ry.Start();
426 pos[2] = rz.Start();
427 pos[3] = rt.Start();
428 pos[4] = ru.Start();
429
430 ndim = ndim_;
431 TArray<T> ra;
432 UpdateSubArraySizes(ra, ndim, size, pos, step);
433 ra.DataBlock().Share(this->DataBlock());
434 ra.SetTemp(true);
435 return(ra);
436}
437
438// ...... Operation de calcul sur les tableaux ......
439// ------- Attention --------
440// Boucles normales prenant en compte les steps ....
441// Possibilite de // , vectorisation
442
443//! Fill TArray with Sequence \b seq
444/*!
445 \param seq : sequence to fill the array
446 \sa Sequence
447 */
448template <class T>
449TArray<T>& TArray<T>::SetSeq(Sequence const & seq)
450{
451 if (NbDimensions() < 1)
452 throw RangeCheckError("TArray<T>::SetSeq(Sequence ) - Not Allocated Array ! ");
453
454 T * pe;
455 sa_size_t j,k;
456 int_4 ka;
457 if (arrtype_ == 0) ka = 0;
458 else ka = macoli_;
459 sa_size_t step = Step(ka);
460 sa_size_t gpas = Size(ka);
461 sa_size_t naxa = Size()/Size(ka);
462 for(j=0; j<naxa; j++) {
463 pe = mNDBlock.Begin()+Offset(ka,j);
464/*
465 Appel explicite de l'operateur de conversion
466 suite a la suggestion de M. Reinecke, Reza 31/7/2002
467#if !defined(__GNUG__)
468 for(k=0; k<gpas; k++) pe[k*step] = (T) seq(j*gpas+k);
469#else
470 // g++ (up to 2.95.1) se melange les pinceaux s'il y a le cast (T) pour l'instanciation des complexes
471 for(k=0; k<gpas; k++) pe[k*step] = seq(j*gpas+k);
472#endif
473 --- Appel explicite de l'operateur de conversion sur l'objet MuTyV
474*/
475 for(k=0; k<gpas; k++) pe[k*step] = seq(j*gpas+k).operator T();
476 }
477 return(*this);
478}
479
480// >>>> Operations avec 2nd membre de type scalaire
481
482//! Fill an array with a constant value \b x
483template <class T>
484TArray<T>& TArray<T>::SetT(T x)
485{
486 if (NbDimensions() < 1)
487 throw RangeCheckError("TArray<T>::SetT(T ) - Not Allocated Array ! ");
488 T * pe;
489 sa_size_t j,k;
490 if (AvgStep() > 0) { // regularly spaced elements
491 sa_size_t step = AvgStep();
492 sa_size_t maxx = totsize_*step;
493 pe = Data();
494 for(k=0; k<maxx; k+=step ) pe[k] = x;
495 }
496 else { // Non regular data spacing ...
497 int_4 ka = MaxSizeKA();
498 sa_size_t step = Step(ka);
499 sa_size_t gpas = Size(ka)*step;
500 sa_size_t naxa = Size()/Size(ka);
501 for(j=0; j<naxa; j++) {
502 pe = mNDBlock.Begin()+Offset(ka,j);
503 for(k=0; k<gpas; k+=step) pe[k] = x;
504 }
505 }
506 return(*this);
507}
508
509//! Add a constant value \b x to the source array and store the result in \b res.
510/*!
511Add a constant to the source array \b this and store the result in \b res (res = *this+x).
512If not initially allocated, the output array \b res is automatically
513resized as a packed array with the same sizes as the source (this) array.
514Returns a reference to the output array \b res.
515\param x : constant to add to the array elements
516\param res : Output array containing the result (res=this+x).
517*/
518template <class T>
519TArray<T>& TArray<T>::AddCst(T x, TArray<T>& res) const
520{
521 if (NbDimensions() < 1)
522 throw RangeCheckError("TArray<T>::AddCst(T,res) - Not allocated source array ");
523 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
524 bool smo;
525 if (!CompareSizes(res, smo))
526 throw(SzMismatchError("TArray<T>::AddCst(T, res) SizeMismatch(this,res) ")) ;
527
528 const T * pe;
529 T * per;
530 sa_size_t j,k,kr;
531 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
532 sa_size_t maxx = totsize_;
533 pe = Data();
534 per = res.Data();
535 for(k=0; k<maxx; k++) { *per = (*pe)+x; per++; pe++; }
536 }
537 else { // Non regular data spacing ...
538 int_4 ax,axr;
539 sa_size_t step, stepr;
540 sa_size_t gpas, naxr;
541 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
542 for(j=0; j<naxr; j++) {
543 pe = mNDBlock.Begin()+Offset(ax,j);
544 per = res.DataBlock().Begin()+res.Offset(axr,j);
545 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]+x;
546 }
547 }
548 return(res);
549}
550
551//! Subtract a constant value \b x from the source array and store the result in \b res.
552/*!
553Subtract a constant from the source array \b this and store the result in \b res (res = *this-x).
554If not initially allocated, the output array \b res is automatically
555resized as a packed array with the same sizes as the source (this) array.
556Returns a reference to the output array \b res.
557\param x : constant to subtract from the array elements
558\param res : Output array containing the result (res=this+x or res=x-this).
559\param fginv == true : Invert subtraction argument order (*this = x-(*this))
560*/
561template <class T>
562TArray<T>& TArray<T>::SubCst(T x, TArray<T>& res, bool fginv) const
563{
564 if (NbDimensions() < 1)
565 throw RangeCheckError("TArray<T>::SubCst(T,res) - Not allocated source array ");
566 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
567 bool smo;
568 if (!CompareSizes(res, smo))
569 throw(SzMismatchError("TArray<T>::SubCst(T, res) SizeMismatch(this,res) ")) ;
570
571 const T * pe;
572 T * per;
573 sa_size_t j,k,kr;
574 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
575 sa_size_t maxx = totsize_;
576 pe = Data();
577 per = res.Data();
578 if (!fginv)
579 for(k=0; k<maxx; k++) { *per = (*pe)-x; per++; pe++; }
580 else
581 for(k=0; k<maxx; k++) { *per = x-(*pe); per++; pe++; }
582 }
583 else { // Non regular data spacing ...
584 int_4 ax,axr;
585 sa_size_t step, stepr;
586 sa_size_t gpas, naxr;
587 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
588 for(j=0; j<naxr; j++) {
589 pe = mNDBlock.Begin()+Offset(ax,j);
590 per = res.DataBlock().Begin()+res.Offset(axr,j);
591 if (!fginv)
592 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]-x;
593 else
594 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = x-pe[k];
595 }
596 }
597 return(res);
598}
599
600//! Multiply the source array by a constant value \b x and store the result in \b res.
601/*!
602Multiply the source array \b this by a constant \b x and store the result in \b res (res = *this*x).
603If not initially allocated, the output array \b res is automatically
604resized as a packed array with the same sizes as the source (this) array.
605Returns a reference to the output array \b res.
606\param x : Array elements are multiplied by x
607\param res : Output array containing the result (res=this*x).
608*/
609template <class T>
610TArray<T>& TArray<T>::MulCst(T x, TArray<T>& res) const
611{
612 if (NbDimensions() < 1)
613 throw RangeCheckError("TArray<T>::MulCst(T,res) - Not allocated source array ");
614 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
615 bool smo;
616 if (!CompareSizes(res, smo))
617 throw(SzMismatchError("TArray<T>::MulCst(T, res) SizeMismatch(this,res) ")) ;
618
619 const T * pe;
620 T * per;
621 sa_size_t j,k,kr;
622 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
623 sa_size_t maxx = totsize_;
624 pe = Data();
625 per = res.Data();
626 for(k=0; k<maxx; k++) { *per = (*pe)*x; per++; pe++; }
627 }
628 else { // Non regular data spacing ...
629 int_4 ax,axr;
630 sa_size_t step, stepr;
631 sa_size_t gpas, naxr;
632 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
633 for(j=0; j<naxr; j++) {
634 pe = mNDBlock.Begin()+Offset(ax,j);
635 per = res.DataBlock().Begin()+res.Offset(axr,j);
636 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]*x;
637 }
638 }
639 return(res);
640}
641
642//! Divide the source array by a constant value \b x and store the result in \b res.
643/*!
644Divide the source array \b this by a constant \b x and store the result in \b res (res = *this/x).
645If not initially allocated, the output array \b res is automatically
646resized as a packed array with the same sizes as the source (this) array.
647Returns a reference to the output array \b res.
648\param x : Array elements are divied by x
649\param res : Output array containing the result (res=(*this)/x or res=x/(*this)).
650\param fginv == true : Invert the operation order (res = x/(*this))
651*/
652template <class T>
653TArray<T>& TArray<T>::DivCst(T x, TArray<T>& res, bool fginv) const
654{
655 if (NbDimensions() < 1)
656 throw RangeCheckError("TArray<T>::DivCst(T,res) - Not allocated source array ! ");
657 if (!fginv && (x == (T) 0) )
658 throw MathExc("TArray<T>::DivCst(T,res) - Divide by zero ! ");
659 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
660 bool smo;
661 if (!CompareSizes(res, smo))
662 throw(SzMismatchError("TArray<T>::DivCst(T, res) SizeMismatch(this,res) ")) ;
663
664 const T * pe;
665 T * per;
666 sa_size_t j,k,kr;
667 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
668 sa_size_t maxx = totsize_;
669 pe = Data();
670 per = res.Data();
671 if (!fginv)
672 for(k=0; k<maxx; k++) { *per = (*pe)/x; per++; pe++; }
673 else
674 for(k=0; k<maxx; k++) { *per = x/(*pe); per++; pe++; }
675 }
676 else { // Non regular data spacing ...
677 int_4 ax,axr;
678 sa_size_t step, stepr;
679 sa_size_t gpas, naxr;
680 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
681 for(j=0; j<naxr; j++) {
682 pe = mNDBlock.Begin()+Offset(ax,j);
683 per = res.DataBlock().Begin()+res.Offset(axr,j);
684 if (!fginv)
685 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]/x;
686 else
687 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = x/pe[k];
688 }
689 }
690 return(res);
691}
692
693
694//! Stores the opposite of the source array in \b res (res=-(*this)).
695/*!
696If not initially allocated, the output array \b res is automatically
697resized as a packed array with the same sizes as the source (this) array.
698Returns a reference to the output array \b res.
699*/
700template <class T>
701TArray<T>& TArray<T>::NegateElt(TArray<T>& res) const
702{
703 if (NbDimensions() < 1)
704 throw RangeCheckError("TArray<T>::NegateElt(res) - Not allocated source array ");
705 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
706 bool smo;
707 if (!CompareSizes(res, smo))
708 throw(SzMismatchError("TArray<T>::NegateElt(res) SizeMismatch(this,res) ")) ;
709
710 const T * pe;
711 T * per;
712 sa_size_t j,k,kr;
713 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
714 sa_size_t maxx = totsize_;
715 pe = Data();
716 per = res.Data();
717 for(k=0; k<maxx; k++) { *per = -(*pe); per++; pe++; }
718 }
719 else { // Non regular data spacing ...
720 int_4 ax,axr;
721 sa_size_t step, stepr;
722 sa_size_t gpas, naxr;
723 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
724 for(j=0; j<naxr; j++) {
725 pe = mNDBlock.Begin()+Offset(ax,j);
726 per = res.DataBlock().Begin()+res.Offset(axr,j);
727 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = -pe[k];
728 }
729 }
730 return(res);
731}
732
733// >>>> Operations avec 2nd membre de type tableau
734//! Add two TArrays
735template <class T>
736TArray<T>& TArray<T>::AddElt(const TArray<T>& a)
737{
738 if (NbDimensions() < 1)
739 throw RangeCheckError("TArray<T>::AddElt(const TArray<T>& ) - Not Allocated Array ! ");
740 bool smo;
741 if (!CompareSizes(a, smo))
742 throw(SzMismatchError("TArray<T>::AddElt(const TArray<T>&) SizeMismatch")) ;
743
744 T * pe;
745 const T * pea;
746 sa_size_t j,k,ka;
747 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0)) { // regularly spaced elements
748 sa_size_t step = AvgStep();
749 sa_size_t stepa = a.AvgStep();
750 sa_size_t maxx = totsize_*step;
751 pe = Data();
752 pea = a.Data();
753 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] += pea[ka] ;
754 }
755 else { // Non regular data spacing ...
756 int_4 ax,axa;
757 sa_size_t step, stepa;
758 sa_size_t gpas, naxa;
759 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
760 for(j=0; j<naxa; j++) {
761 pe = mNDBlock.Begin()+Offset(ax,j);
762 pea = a.DataBlock().Begin()+a.Offset(axa,j);
763 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] += pea[ka];
764 }
765 }
766 return(*this);
767}
768
769//! Substract two TArrays
770/*!
771Substract two TArrays *this = *this-a
772\param fginv == true : Perfoms the inverse subtraction (*this = a-(*this))
773*/
774template <class T>
775TArray<T>& TArray<T>::SubElt(const TArray<T>& a, bool fginv)
776{
777 if (NbDimensions() < 1)
778 throw RangeCheckError("TArray<T>::SubElt(const TArray<T>& ) - Not Allocated Array ! ");
779 bool smo;
780 if (!CompareSizes(a, smo))
781 throw(SzMismatchError("TArray<T>::SubElt(const TArray<T>&) SizeMismatch")) ;
782
783 T * pe;
784 const T * pea;
785 sa_size_t j,k,ka;
786 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
787 sa_size_t step = AvgStep();
788 sa_size_t stepa = a.AvgStep();
789 sa_size_t maxx = totsize_*step;
790 pe = Data();
791 pea = a.Data();
792 if (fginv)
793 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka]-pe[k] ;
794 else
795 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] -= pea[ka] ;
796 }
797 else { // Non regular data spacing ...
798 int_4 ax,axa;
799 sa_size_t step, stepa;
800 sa_size_t gpas, naxa;
801 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
802 for(j=0; j<naxa; j++) {
803 pe = mNDBlock.Begin()+Offset(ax,j);
804 pea = a.DataBlock().Begin()+a.Offset(axa,j);
805 if (fginv)
806 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka]-pe[k] ;
807 else
808 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] -= pea[ka];
809 }
810 }
811 return(*this);
812}
813
814
815//! Multiply two TArrays (elements by elements)
816template <class T>
817TArray<T>& TArray<T>::MulElt(const TArray<T>& a)
818{
819 if (NbDimensions() < 1)
820 throw RangeCheckError("TArray<T>::MulElt(const TArray<T>& ) - Not Allocated Array ! ");
821 bool smo;
822 if (!CompareSizes(a, smo))
823 throw(SzMismatchError("TArray<T>::MulElt(const TArray<T>&) SizeMismatch")) ;
824
825 T * pe;
826 const T * pea;
827 sa_size_t j,k,ka;
828 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
829 sa_size_t step = AvgStep();
830 sa_size_t stepa = a.AvgStep();
831 sa_size_t maxx = totsize_*step;
832 pe = Data();
833 pea = a.Data();
834 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] *= pea[ka] ;
835 }
836 else { // Non regular data spacing ...
837 int_4 ax,axa;
838 sa_size_t step, stepa;
839 sa_size_t gpas, naxa;
840 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
841 for(j=0; j<naxa; j++) {
842 pe = mNDBlock.Begin()+Offset(axa,j);
843 pea = a.DataBlock().Begin()+a.Offset(axa,j);
844 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] *= pea[ka];
845 }
846 }
847 return(*this);
848}
849
850
851//! Divide two TArrays (elements by elements)
852/*!
853Divide two TArrays *this = (*this)/a
854\param fginv == true : Perfoms the inverse division (*this = a/(*this))
855\param divzero == true : if a(i)==0. result is set to zero: (*this)(i)==0.
856*/
857template <class T>
858TArray<T>& TArray<T>::DivElt(const TArray<T>& a, bool fginv, bool divzero)
859{
860 if (NbDimensions() < 1)
861 throw RangeCheckError("TArray<T>::DivElt(const TArray<T>& ) - Not Allocated Array ! ");
862 bool smo;
863 if (!CompareSizes(a, smo))
864 throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&) SizeMismatch")) ;
865
866 T * pe;
867 const T * pea;
868 sa_size_t j,k,ka;
869 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
870 sa_size_t step = AvgStep();
871 sa_size_t stepa = a.AvgStep();
872 sa_size_t maxx = totsize_*step;
873 pe = Data();
874 pea = a.Data();
875 if(divzero) {
876 if (fginv)
877 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa )
878 {if(pe[k]==(T)0) pe[k] = (T)0; else pe[k] = pea[ka]/pe[k];}
879 else
880 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa )
881 {if(pea[k]==(T)0) pe[k] = (T)0; else pe[k] /= pea[ka] ;}
882 } else {
883 if (fginv)
884 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka]/pe[k];
885 else
886 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] /= pea[ka] ;
887 }
888 }
889 else { // Non regular data spacing ...
890 int_4 ax,axa;
891 sa_size_t step, stepa;
892 sa_size_t gpas, naxa;
893 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
894 for(j=0; j<naxa; j++) {
895 pe = mNDBlock.Begin()+Offset(ax,j);
896 pea = a.DataBlock().Begin()+a.Offset(axa,j);
897 if(divzero) {
898 if (fginv)
899 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa)
900 {if(pe[k]==(T)0) pe[k] = (T)0; else pe[k] = pea[ka]/pe[k];}
901 else
902 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa)
903 {if(pea[k]==(T)0) pe[k] = (T)0; else pe[k] /= pea[ka];}
904 } else {
905 if (fginv)
906 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka]/pe[k];
907 else
908 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] /= pea[ka];
909 }
910 }
911 }
912 return(*this);
913}
914
915//! Copy elements of \b a
916template <class T>
917TArray<T>& TArray<T>::CopyElt(const TArray<T>& a)
918{
919 if (NbDimensions() < 1)
920 throw RangeCheckError("TArray<T>::CopyElt(const TArray<T>& ) - Not Allocated Array ! ");
921 bool smo;
922 if (!CompareSizes(a, smo))
923 throw(SzMismatchError("TArray<T>::CopyElt(const TArray<T>&) SizeMismatch")) ;
924
925 T * pe;
926 const T * pea;
927 sa_size_t j,k,ka;
928 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
929 sa_size_t step = AvgStep();
930 sa_size_t stepa = a.AvgStep();
931 sa_size_t maxx = totsize_*step;
932 pe = Data();
933 pea = a.Data();
934 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka] ;
935 }
936 else { // Non regular data spacing ...
937 int_4 ax,axa;
938 sa_size_t step, stepa;
939 sa_size_t gpas, naxa;
940 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
941 for(j=0; j<naxa; j++) {
942 pe = mNDBlock.Begin()+Offset(ax,j);
943 pea = a.DataBlock().Begin()+a.Offset(axa,j);
944 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka];
945 }
946 }
947 return(*this);
948}
949
950//! Converts and Copy elements of \b a
951template <class T>
952TArray<T>& TArray<T>::ConvertAndCopyElt(const BaseArray& a)
953{
954 if (NbDimensions() < 1)
955 throw RangeCheckError("TArray<T>::ConvertAndCopyElt(const TArray<T>& ) - Not Allocated Array ! ");
956 bool smo;
957 if (!CompareSizes(a, smo))
958 throw(SzMismatchError("TArray<T>::ConvertAndCopyElt(const TArray<T>&) SizeMismatch")) ;
959
960 T * pe;
961 sa_size_t j,k,ka;
962 sa_size_t offa;
963 // Non regular data spacing ...
964 int_4 ax,axa;
965 sa_size_t step, stepa;
966 sa_size_t gpas, naxa;
967 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
968 for(j=0; j<naxa; j++) {
969 pe = mNDBlock.Begin()+Offset(ax,j);
970 offa = a.Offset(axa,j);
971/*
972 Appel explicite de l'operateur de conversion
973 suite a la suggestion de M. Reinecke, Reza 31/7/2002
974#if !defined(__GNUG__)
975 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = (T)a.ValueAtPosition(offa+ka);
976#else
977 // g++ (up to 2.95.1) se melange les pinceaux s'il y a le cast (T) pour l'instanciation des complexes
978 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = a.ValueAtPosition(offa+ka);
979#endif
980 --- Appel explicite de l'operateur de conversion sur l'objet MuTyV
981*/
982 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa)
983 pe[k] = a.ValueAtPosition(offa+ka).operator T();
984 }
985 return(*this);
986}
987
988
989// Somme et produit des elements
990//! Sum all elements
991template <class T>
992T TArray<T>::Sum() const
993{
994 if (NbDimensions() < 1)
995 throw RangeCheckError("TArray<T>::Sum() - Not Allocated Array ! ");
996 T ret=0;
997 const T * pe;
998 sa_size_t j,k;
999 if (AvgStep() > 0) { // regularly spaced elements
1000 sa_size_t step = AvgStep();
1001 sa_size_t maxx = totsize_*step;
1002 pe = Data();
1003 for(k=0; k<maxx; k+=step ) ret += pe[k];
1004 }
1005 else { // Non regular data spacing ...
1006 int_4 ka = MaxSizeKA();
1007 sa_size_t step = Step(ka);
1008 sa_size_t gpas = Size(ka)*step;
1009 sa_size_t naxa = Size()/Size(ka);
1010 for(j=0; j<naxa; j++) {
1011 pe = mNDBlock.Begin()+Offset(ka,j);
1012 for(k=0; k<gpas; k+=step) ret += pe[k] ;
1013 }
1014 }
1015 return ret;
1016}
1017
1018//! Multiply all elements
1019template <class T>
1020T TArray<T>::Product() const
1021{
1022 if (NbDimensions() < 1)
1023 throw RangeCheckError("TArray<T>::Product() - Not Allocated Array ! ");
1024 T ret=(T)1;
1025 const T * pe;
1026 sa_size_t j,k;
1027 if (AvgStep() > 0) { // regularly spaced elements
1028 sa_size_t step = AvgStep();
1029 sa_size_t maxx = totsize_*step;
1030 pe = Data();
1031 for(k=0; k<maxx; k+=step ) ret *= pe[k];
1032 }
1033 else { // Non regular data spacing ...
1034 int_4 ka = MaxSizeKA();
1035 sa_size_t step = Step(ka);
1036 sa_size_t gpas = Size(ka)*step;
1037 sa_size_t naxa = Size()/Size(ka);
1038 for(j=0; j<naxa; j++) {
1039 pe = mNDBlock.Begin()+Offset(ka,j);
1040 for(k=0; k<gpas; k+=step) ret *= pe[k] ;
1041 }
1042 }
1043 return ret;
1044}
1045
1046//! Returns the sum of all elements squared (Sum
1047template <class T>
1048T TArray<T>::SumX2() const
1049{
1050 if (NbDimensions() < 1)
1051 throw RangeCheckError("TArray<T>::SumX2() - Not Allocated Array ! ");
1052 T ret=0;
1053 const T * pe;
1054 sa_size_t j,k;
1055 if (AvgStep() > 0) { // regularly spaced elements
1056 sa_size_t step = AvgStep();
1057 sa_size_t maxx = totsize_*step;
1058 pe = Data();
1059 for(k=0; k<maxx; k+=step ) ret += pe[k]*pe[k];
1060 }
1061 else { // Non regular data spacing ...
1062 int_4 ka = MaxSizeKA();
1063 sa_size_t step = Step(ka);
1064 sa_size_t gpas = Size(ka)*step;
1065 sa_size_t naxa = Size()/Size(ka);
1066 for(j=0; j<naxa; j++) {
1067 pe = mNDBlock.Begin()+Offset(ka,j);
1068 for(k=0; k<gpas; k+=step) ret += pe[k]*pe[k] ;
1069 }
1070 }
1071 return ret;
1072}
1073
1074//! Return the minimum and the maximum values of the array elements
1075/*!
1076 This method generates an exception (\c MathExc) if called for complex arrays
1077*/
1078
1079template <class T>
1080void TArray<T>::MinMax(T& min, T& max) const
1081{
1082 const T * pe;
1083 sa_size_t j,k;
1084 int_4 ka = MaxSizeKA();
1085 sa_size_t step = Step(ka);
1086 sa_size_t gpas = Size(ka)*step;
1087 sa_size_t naxa = Size()/Size(ka);
1088 min = (*this)[0];
1089 max = (*this)[0];
1090 for(j=0; j<naxa; j++) {
1091 pe = mNDBlock.Begin()+Offset(ka,j);
1092 for(k=0; k<gpas; k+=step) {
1093 if (pe[k]<min) min = pe[k];
1094 else if (pe[k]>max) max = pe[k];
1095 }
1096 }
1097 return;
1098}
1099
1100DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
1101void TArray< complex<r_4> >::MinMax(complex<r_4>& min, complex<r_4>& max) const
1102{
1103 throw MathExc("TArray< complex<r_4> >::MinMax(...) - No order in complex");
1104}
1105DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
1106void TArray< complex<r_8> >::MinMax(complex<r_8>& min, complex<r_8>& max) const
1107{
1108 throw MathExc("TArray< complex<r_4> >::MinMax(...) - No order in complex");
1109}
1110
1111
1112// ----------------------------------------------------
1113// Impression, etc ...
1114// ----------------------------------------------------
1115
1116//! Return a string that contain the type \b T of the array
1117template <class T>
1118string TArray<T>::InfoString() const
1119{
1120 string rs = "TArray<" ;
1121 rs += typeid(T).name();
1122 rs += "> ";
1123 return(rs);
1124}
1125
1126//! Print array
1127/*!
1128 \param os : output stream
1129 \param maxprt : maximum numer of print
1130 \param si : if true, display attached DvList
1131 \param ascd : if true, suppresses the display of line numbers,
1132 suitable for ascii dump format.
1133 \sa SetMaxPrint
1134 \sa WriteASCII
1135 */
1136template <class T>
1137void TArray<T>::Print(ostream& os, sa_size_t maxprt, bool si, bool ascd) const
1138{
1139 if (maxprt < 0) maxprt = max_nprt_;
1140 sa_size_t npr = 0;
1141 Show(os, si);
1142 if (ndim_ < 1) return;
1143 sa_size_t k0,k1,k2,k3,k4;
1144 for(k4=0; k4<size_[4]; k4++) {
1145 if ((size_[4] > 1) && ascd)
1146 cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
1147 for(k3=0; k3<size_[3]; k3++) {
1148 if ((size_[3] > 1) && ascd)
1149 cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
1150 for(k2=0; k2<size_[2]; k2++) {
1151 if ((size_[2] > 1) & ascd)
1152 cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
1153 for(k1=0; k1<size_[1]; k1++) {
1154 if ( (size_[1] > 1) && (size_[0] > 10) && ascd)
1155 cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
1156 for(k0=0; k0<size_[0]; k0++) {
1157 if(k0 > 0) os << " ";
1158 os << Elem(k0, k1, k2, k3, k4); npr++;
1159 if (npr >= (sa_size_t) maxprt) {
1160 if (npr < totsize_) os << "\n .... " << endl; return;
1161 }
1162 }
1163 os << endl;
1164 }
1165 }
1166 }
1167 }
1168 os << endl;
1169}
1170
1171//! Fill the array, decoding the ASCII input stream
1172/*!
1173 \param is : input stream (ASCII)
1174 \param nr : Number of non empty (or comment) lines in stream (return value)
1175 \param nc : Number of columns (= ntot/nlines) (return value)
1176 \param clm : Lines starting with clm character are treated as comment lines
1177 \param sep : word separator in lines
1178 \return Number of decoded elements
1179*/
1180template <class T>
1181sa_size_t TArray<T>::ReadASCII(istream& is, sa_size_t & nr, sa_size_t & nc,
1182 char clm, const char* sep)
1183{
1184 EnumeratedSequence es;
1185 sa_size_t n = es.FillFromFile(is, nr, nc, clm, sep);
1186 if ( (n < 1) || (nr < 1) || (nc < 1) ) return(n);
1187 if (!IsAllocated()) {
1188 sa_size_t sz[2];
1189 if (arrtype_ == 2) { // C'est un vecteur
1190 sz[0] = sz[1] = 1;
1191 sz[veceli_] = n;
1192 }
1193 else {
1194 sz[RowsKA()] = nr;
1195 sz[ColsKA()] = nc;
1196 }
1197 ReSize(2, sz);
1198 }
1199 SetSeq(es);
1200 cout << "TArray<T>::ReadASCII()/Info: " << n << " elements read from stream "
1201 << " (Row,Col= " << nr << "," << nc << ")" << endl;
1202 return(n);
1203}
1204
1205//! Writes the array content to the output stream, (in ASCII)
1206/*!
1207 \param os : output stream (ASCII)
1208 \sa Print
1209 */
1210template <class T>
1211void TArray<T>::WriteASCII(ostream& os) const
1212{
1213 Print(os, Size(), false, true);
1214}
1215
1216
1217
1218///////////////////////////////////////////////////////////////
1219///////////////////////////////////////////////////////////////
1220#ifdef __CXX_PRAGMA_TEMPLATES__
1221/*
1222#pragma define_template TArray<uint_1>
1223#pragma define_template TArray<int_2>
1224#pragma define_template TArray<uint_4>
1225*/
1226#pragma define_template TArray<uint_2>
1227#pragma define_template TArray<uint_8>
1228#pragma define_template TArray<int_4>
1229#pragma define_template TArray<int_8>
1230#pragma define_template TArray<r_4>
1231#pragma define_template TArray<r_8>
1232#pragma define_template TArray< complex<r_4> >
1233#pragma define_template TArray< complex<r_8> >
1234#endif
1235
1236#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1237/*
1238template class TArray<uint_1>;
1239template class TArray<int_2>;
1240template class TArray<uint_4>;
1241*/
1242template class TArray<uint_2>;
1243template class TArray<uint_8>;
1244template class TArray<int_4>;
1245template class TArray<int_8>;
1246template class TArray<r_4>;
1247template class TArray<r_8>;
1248template class TArray< complex<r_4> >;
1249template class TArray< complex<r_8> >;
1250#endif
1251
1252
Note: See TracBrowser for help on using the repository browser.