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

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

Remplacement methodes Add/Mul/Sub/Div(T x) par AddCst/MulCst/SubCst/DivCst(T x, TArray<T> res) ds TArray - Reza 26 Juillet 2004

File size: 38.6 KB
Line 
1// template array class for numerical types
2// R. Ansari, C.Magneville 03/2000
3
4#include "machdefs.h"
5#include <stdio.h>
6#include <stdlib.h>
7#include <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 for(int ksz=0; ksz<BASEARRAY_MAXNDIMS; ksz++) siz[ksz] = a.Size(ksz);
308 if (!UpdateSizes(a.NbDimensions(), siz, 1, 0, exmsg)) throw( ParmError(exmsg) );
309 mNDBlock.ReSize(totsize_, fzero);
310 }
311 else {
312 if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) );
313 mNDBlock.ReSize(totsize_);
314 }
315}
316
317//! Re-allocate space for array
318/*!
319 \param ndim : number of dimensions
320 \param siz[ndim] : size along each dimension
321 \param step : step (same for all dimensions)
322 \param force : if true re-allocation is forced, if not it occurs
323 only if the required space is greater than the old one.
324 */
325template <class T>
326void TArray<T>::Realloc(int_4 ndim, sa_size_t * siz, sa_size_t step, bool force)
327{
328 if (arrtype_ != 0) {
329 if (ndim != 2)
330 throw( ParmError("TArray<T>::Realloc(ndim!=2,...) for Matrix" ) );
331 if ((arrtype_ == 2) && (siz[0] > 1) && (siz[1] > 1))
332 throw( ParmError("TArray<T>::Realloc(,siz[0]>1 && size[1]>1) for Vector" ) );
333 }
334 string exmsg = "TArray<T>::Realloc()";
335 if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) );
336 mNDBlock.Realloc(totsize_, force);
337}
338
339
340//! Compact dimensions in one or more is equal to 1.
341template <class T>
342TArray<T>& TArray<T>::CompactAllDimensions()
343{
344 CompactAllDim();
345 return(*this);
346}
347
348//! Compact dimensions if the last one is equal to 1.
349template <class T>
350TArray<T>& TArray<T>::CompactTrailingDimensions()
351{
352 CompactTrailingDim();
353 return(*this);
354}
355
356//! Give value (in \b double) for element at position \b ip..
357template <class T>
358MuTyV & TArray<T>::ValueAtPosition(sa_size_t ip) const
359{
360#ifdef SO_BOUNDCHECKING
361 if (ip >= totsize_) throw( ParmError("TArray<T>::ValueAtPosition(sa_size_t ip) Out-of-bound Error") );
362#endif
363 my_mtv = *(mNDBlock.Begin()+Offset(ip));
364 return( my_mtv );
365}
366
367//! Return array with elements packed
368/*!
369 \param force : if true, pack elements in a new array.
370 If false and array is already packed, return
371 an array that share data with the current one.
372 \return packed array
373 */
374template <class T>
375TArray<T> TArray<T>::PackElements(bool force) const
376{
377 if (NbDimensions() < 1)
378 throw RangeCheckError("TArray<T>::PackElements() - Not Allocated Array ! ");
379 if ( !force && (AvgStep() == 1) ) {
380 TArray<T> ra;
381 ra.Share(*this);
382 ra.SetTemp(true);
383 return(ra);
384 }
385 else {
386 TArray<T> ra(ndim_, size_, 1);
387 ra.CopyElt(*this);
388 ra.SetTemp(true);
389 return(ra);
390 }
391}
392
393// SubArrays
394// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
395//! Extract a sub-array
396/*!
397 \param rx,ry,rz,rt,ru : range of extraction along dimensions
398 \sa Range
399 */
400template <class T>
401TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const
402{
403 if (NbDimensions() < 1)
404 throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
405 int_4 ndim = 0;
406 sa_size_t size[BASEARRAY_MAXNDIMS];
407 sa_size_t step[BASEARRAY_MAXNDIMS];
408 sa_size_t pos[BASEARRAY_MAXNDIMS];
409 size[0] = rx.Size();
410 size[1] = ry.Size();
411 size[2] = rz.Size();
412 size[3] = rt.Size();
413 size[4] = ru.Size();
414
415 step[0] = rx.Step();
416 step[1] = ry.Step();
417 step[2] = rz.Step();
418 step[3] = rt.Step();
419 step[4] = ru.Step();
420
421 pos[0] = rx.Start();
422 pos[1] = ry.Start();
423 pos[2] = rz.Start();
424 pos[3] = rt.Start();
425 pos[4] = ru.Start();
426
427 ndim = ndim_;
428 TArray<T> ra;
429 UpdateSubArraySizes(ra, ndim, size, pos, step);
430 ra.DataBlock().Share(this->DataBlock());
431 ra.SetTemp(true);
432 return(ra);
433}
434
435// ...... Operation de calcul sur les tableaux ......
436// ------- Attention --------
437// Boucles normales prenant en compte les steps ....
438// Possibilite de // , vectorisation
439
440//! Fill TArray with Sequence \b seq
441/*!
442 \param seq : sequence to fill the array
443 \sa Sequence
444 */
445template <class T>
446TArray<T>& TArray<T>::SetSeq(Sequence const & seq)
447{
448 if (NbDimensions() < 1)
449 throw RangeCheckError("TArray<T>::SetSeq(Sequence ) - Not Allocated Array ! ");
450
451 T * pe;
452 sa_size_t j,k;
453 int_4 ka;
454 if (arrtype_ == 0) ka = 0;
455 else ka = macoli_;
456 sa_size_t step = Step(ka);
457 sa_size_t gpas = Size(ka);
458 sa_size_t naxa = Size()/Size(ka);
459 for(j=0; j<naxa; j++) {
460 pe = mNDBlock.Begin()+Offset(ka,j);
461/*
462 Appel explicite de l'operateur de conversion
463 suite a la suggestion de M. Reinecke, Reza 31/7/2002
464#if !defined(__GNUG__)
465 for(k=0; k<gpas; k++) pe[k*step] = (T) seq(j*gpas+k);
466#else
467 // g++ (up to 2.95.1) se melange les pinceaux s'il y a le cast (T) pour l'instanciation des complexes
468 for(k=0; k<gpas; k++) pe[k*step] = seq(j*gpas+k);
469#endif
470 --- Appel explicite de l'operateur de conversion sur l'objet MuTyV
471*/
472 for(k=0; k<gpas; k++) pe[k*step] = seq(j*gpas+k).operator T();
473 }
474 return(*this);
475}
476
477// >>>> Operations avec 2nd membre de type scalaire
478
479//! Fill an array with a constant value \b x
480template <class T>
481TArray<T>& TArray<T>::SetT(T x)
482{
483 if (NbDimensions() < 1)
484 throw RangeCheckError("TArray<T>::SetT(T ) - Not Allocated Array ! ");
485 T * pe;
486 sa_size_t j,k;
487 if (AvgStep() > 0) { // regularly spaced elements
488 sa_size_t step = AvgStep();
489 sa_size_t maxx = totsize_*step;
490 pe = Data();
491 for(k=0; k<maxx; k+=step ) pe[k] = x;
492 }
493 else { // Non regular data spacing ...
494 int_4 ka = MaxSizeKA();
495 sa_size_t step = Step(ka);
496 sa_size_t gpas = Size(ka)*step;
497 sa_size_t naxa = Size()/Size(ka);
498 for(j=0; j<naxa; j++) {
499 pe = mNDBlock.Begin()+Offset(ka,j);
500 for(k=0; k<gpas; k+=step) pe[k] = x;
501 }
502 }
503 return(*this);
504}
505
506//! Add a constant value \b x to the source array and store the result in \b res.
507/*!
508Add a constant to the source array \b this and store the result in \b res (res = *this+x).
509If not initially allocated, the output array \b res is automatically
510resized as a packed array with the same sizes as the source (this) array.
511Returns a reference to the output array \b res.
512\param x : constant to add to the array elements
513\param res : Output array containing the result (res=this+x).
514*/
515template <class T>
516TArray<T>& TArray<T>::AddCst(T x, TArray<T>& res) const
517{
518 if (NbDimensions() < 1)
519 throw RangeCheckError("TArray<T>::AddCst(T,res) - Not allocated source array ");
520 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
521 bool smo;
522 if (!CompareSizes(res, smo))
523 throw(SzMismatchError("TArray<T>::AddCst(T, res) SizeMismatch(this,res) ")) ;
524
525 const T * pe;
526 T * per;
527 sa_size_t j,k,kr;
528 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
529 sa_size_t maxx = totsize_;
530 pe = Data();
531 per = res.Data();
532 for(k=0; k<maxx; k++) { *per = (*pe)+x; per++; pe++; }
533 }
534 else { // Non regular data spacing ...
535 int_4 ax,axr;
536 sa_size_t step, stepr;
537 sa_size_t gpas, naxr;
538 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
539 for(j=0; j<naxr; j++) {
540 pe = mNDBlock.Begin()+Offset(ax,j);
541 per = res.DataBlock().Begin()+res.Offset(axr,j);
542 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]+x;
543 }
544 }
545 return(res);
546}
547
548//! Subtract a constant value \b x from the source array and store the result in \b res.
549/*!
550Subtract a constant from the source array \b this and store the result in \b res (res = *this-x).
551If not initially allocated, the output array \b res is automatically
552resized as a packed array with the same sizes as the source (this) array.
553Returns a reference to the output array \b res.
554\param x : constant to subtract from the array elements
555\param res : Output array containing the result (res=this+x or res=x-this).
556\param fginv == true : Invert subtraction argument order (*this = x-(*this))
557*/
558template <class T>
559TArray<T>& TArray<T>::SubCst(T x, TArray<T>& res, bool fginv) const
560{
561 if (NbDimensions() < 1)
562 throw RangeCheckError("TArray<T>::SubCst(T,res) - Not allocated source array ");
563 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
564 bool smo;
565 if (!CompareSizes(res, smo))
566 throw(SzMismatchError("TArray<T>::SubCst(T, res) SizeMismatch(this,res) ")) ;
567
568 const T * pe;
569 T * per;
570 sa_size_t j,k,kr;
571 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
572 sa_size_t maxx = totsize_;
573 pe = Data();
574 per = res.Data();
575 if (!fginv)
576 for(k=0; k<maxx; k++) { *per = (*pe)-x; per++; pe++; }
577 else
578 for(k=0; k<maxx; k++) { *per = x-(*pe); per++; pe++; }
579 }
580 else { // Non regular data spacing ...
581 int_4 ax,axr;
582 sa_size_t step, stepr;
583 sa_size_t gpas, naxr;
584 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
585 for(j=0; j<naxr; j++) {
586 pe = mNDBlock.Begin()+Offset(ax,j);
587 per = res.DataBlock().Begin()+res.Offset(axr,j);
588 if (!fginv)
589 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]-x;
590 else
591 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = x-pe[k];
592 }
593 }
594 return(res);
595}
596
597//! Multiply the source array by a constant value \b x and store the result in \b res.
598/*!
599Multiply the source array \b this by a constant \b x and store the result in \b res (res = *this*x).
600If not initially allocated, the output array \b res is automatically
601resized as a packed array with the same sizes as the source (this) array.
602Returns a reference to the output array \b res.
603\param x : Array elements are multiplied by x
604\param res : Output array containing the result (res=this*x).
605*/
606template <class T>
607TArray<T>& TArray<T>::MulCst(T x, TArray<T>& res) const
608{
609 if (NbDimensions() < 1)
610 throw RangeCheckError("TArray<T>::MulCst(T,res) - Not allocated source array ");
611 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
612 bool smo;
613 if (!CompareSizes(res, smo))
614 throw(SzMismatchError("TArray<T>::MulCst(T, res) SizeMismatch(this,res) ")) ;
615
616 const T * pe;
617 T * per;
618 sa_size_t j,k,kr;
619 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
620 sa_size_t maxx = totsize_;
621 pe = Data();
622 per = res.Data();
623 for(k=0; k<maxx; k++) { *per = (*pe)*x; per++; pe++; }
624 }
625 else { // Non regular data spacing ...
626 int_4 ax,axr;
627 sa_size_t step, stepr;
628 sa_size_t gpas, naxr;
629 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
630 for(j=0; j<naxr; j++) {
631 pe = mNDBlock.Begin()+Offset(ax,j);
632 per = res.DataBlock().Begin()+res.Offset(axr,j);
633 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]*x;
634 }
635 }
636 return(res);
637}
638
639//! Divide the source array by a constant value \b x and store the result in \b res.
640/*!
641Divide the source array \b this by a constant \b x and store the result in \b res (res = *this/x).
642If not initially allocated, the output array \b res is automatically
643resized as a packed array with the same sizes as the source (this) array.
644Returns a reference to the output array \b res.
645\param x : Array elements are divied by x
646\param res : Output array containing the result (res=(*this)/x or res=x/(*this)).
647\param fginv == true : Invert the operation order (res = x/(*this))
648*/
649template <class T>
650TArray<T>& TArray<T>::DivCst(T x, TArray<T>& res, bool fginv) const
651{
652 if (NbDimensions() < 1)
653 throw RangeCheckError("TArray<T>::DivCst(T,res) - Not allocated source array ! ");
654 if (!fginv && (x == (T) 0) )
655 throw MathExc("TArray<T>::DivCst(T,res) - Divide by zero ! ");
656 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
657 bool smo;
658 if (!CompareSizes(res, smo))
659 throw(SzMismatchError("TArray<T>::DivCst(T, res) SizeMismatch(this,res) ")) ;
660
661 const T * pe;
662 T * per;
663 sa_size_t j,k,kr;
664 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
665 sa_size_t maxx = totsize_;
666 pe = Data();
667 per = res.Data();
668 if (!fginv)
669 for(k=0; k<maxx; k++) { *per = (*pe)/x; per++; pe++; }
670 else
671 for(k=0; k<maxx; k++) { *per = x/(*pe); per++; pe++; }
672 }
673 else { // Non regular data spacing ...
674 int_4 ax,axr;
675 sa_size_t step, stepr;
676 sa_size_t gpas, naxr;
677 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
678 for(j=0; j<naxr; j++) {
679 pe = mNDBlock.Begin()+Offset(ax,j);
680 per = res.DataBlock().Begin()+res.Offset(axr,j);
681 if (!fginv)
682 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = pe[k]/x;
683 else
684 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = x/pe[k];
685 }
686 }
687 return(res);
688}
689
690
691//! Stores the opposite of the source array in \b res (res=-(*this)).
692/*!
693If not initially allocated, the output array \b res is automatically
694resized as a packed array with the same sizes as the source (this) array.
695Returns a reference to the output array \b res.
696*/
697template <class T>
698TArray<T>& TArray<T>::NegateElt(TArray<T>& res) const
699{
700 if (NbDimensions() < 1)
701 throw RangeCheckError("TArray<T>::NegateElt(res) - Not allocated source array ");
702 if (res.NbDimensions() < 1) res.SetSize(*this, true, false);
703 bool smo;
704 if (!CompareSizes(res, smo))
705 throw(SzMismatchError("TArray<T>::NegateElt(res) SizeMismatch(this,res) ")) ;
706
707 const T * pe;
708 T * per;
709 sa_size_t j,k,kr;
710 if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements
711 sa_size_t maxx = totsize_;
712 pe = Data();
713 per = res.Data();
714 for(k=0; k<maxx; k++) { *per = -(*pe); per++; pe++; }
715 }
716 else { // Non regular data spacing ...
717 int_4 ax,axr;
718 sa_size_t step, stepr;
719 sa_size_t gpas, naxr;
720 GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxr);
721 for(j=0; j<naxr; j++) {
722 pe = mNDBlock.Begin()+Offset(ax,j);
723 per = res.DataBlock().Begin()+res.Offset(axr,j);
724 for(k=0, kr=0; k<gpas; k+=step, kr+=stepr) per[kr] = -pe[k];
725 }
726 }
727 return(res);
728}
729
730// >>>> Operations avec 2nd membre de type tableau
731//! Add two TArrays
732template <class T>
733TArray<T>& TArray<T>::AddElt(const TArray<T>& a)
734{
735 if (NbDimensions() < 1)
736 throw RangeCheckError("TArray<T>::AddElt(const TArray<T>& ) - Not Allocated Array ! ");
737 bool smo;
738 if (!CompareSizes(a, smo))
739 throw(SzMismatchError("TArray<T>::AddElt(const TArray<T>&) SizeMismatch")) ;
740
741 T * pe;
742 const T * pea;
743 sa_size_t j,k,ka;
744 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0)) { // regularly spaced elements
745 sa_size_t step = AvgStep();
746 sa_size_t stepa = a.AvgStep();
747 sa_size_t maxx = totsize_*step;
748 pe = Data();
749 pea = a.Data();
750 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] += pea[ka] ;
751 }
752 else { // Non regular data spacing ...
753 int_4 ax,axa;
754 sa_size_t step, stepa;
755 sa_size_t gpas, naxa;
756 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
757 for(j=0; j<naxa; j++) {
758 pe = mNDBlock.Begin()+Offset(ax,j);
759 pea = a.DataBlock().Begin()+a.Offset(axa,j);
760 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] += pea[ka];
761 }
762 }
763 return(*this);
764}
765
766//! Substract two TArrays
767/*!
768Substract two TArrays *this = *this-a
769\param fginv == true : Perfoms the inverse subtraction (*this = a-(*this))
770*/
771template <class T>
772TArray<T>& TArray<T>::SubElt(const TArray<T>& a, bool fginv)
773{
774 if (NbDimensions() < 1)
775 throw RangeCheckError("TArray<T>::SubElt(const TArray<T>& ) - Not Allocated Array ! ");
776 bool smo;
777 if (!CompareSizes(a, smo))
778 throw(SzMismatchError("TArray<T>::SubElt(const TArray<T>&) SizeMismatch")) ;
779
780 T * pe;
781 const T * pea;
782 sa_size_t j,k,ka;
783 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
784 sa_size_t step = AvgStep();
785 sa_size_t stepa = a.AvgStep();
786 sa_size_t maxx = totsize_*step;
787 pe = Data();
788 pea = a.Data();
789 if (fginv)
790 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka]-pe[k] ;
791 else
792 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] -= pea[ka] ;
793 }
794 else { // Non regular data spacing ...
795 int_4 ax,axa;
796 sa_size_t step, stepa;
797 sa_size_t gpas, naxa;
798 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
799 for(j=0; j<naxa; j++) {
800 pe = mNDBlock.Begin()+Offset(ax,j);
801 pea = a.DataBlock().Begin()+a.Offset(axa,j);
802 if (fginv)
803 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka]-pe[k] ;
804 else
805 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] -= pea[ka];
806 }
807 }
808 return(*this);
809}
810
811
812//! Multiply two TArrays (elements by elements)
813template <class T>
814TArray<T>& TArray<T>::MulElt(const TArray<T>& a)
815{
816 if (NbDimensions() < 1)
817 throw RangeCheckError("TArray<T>::MulElt(const TArray<T>& ) - Not Allocated Array ! ");
818 bool smo;
819 if (!CompareSizes(a, smo))
820 throw(SzMismatchError("TArray<T>::MulElt(const TArray<T>&) SizeMismatch")) ;
821
822 T * pe;
823 const T * pea;
824 sa_size_t j,k,ka;
825 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
826 sa_size_t step = AvgStep();
827 sa_size_t stepa = a.AvgStep();
828 sa_size_t maxx = totsize_*step;
829 pe = Data();
830 pea = a.Data();
831 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] *= pea[ka] ;
832 }
833 else { // Non regular data spacing ...
834 int_4 ax,axa;
835 sa_size_t step, stepa;
836 sa_size_t gpas, naxa;
837 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
838 for(j=0; j<naxa; j++) {
839 pe = mNDBlock.Begin()+Offset(axa,j);
840 pea = a.DataBlock().Begin()+a.Offset(axa,j);
841 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] *= pea[ka];
842 }
843 }
844 return(*this);
845}
846
847
848//! Divide two TArrays (elements by elements)
849/*!
850Divide two TArrays *this = (*this)/a
851\param fginv == true : Perfoms the inverse division (*this = a/(*this))
852\param divzero == true : if a(i)==0. result is set to zero: (*this)(i)==0.
853*/
854template <class T>
855TArray<T>& TArray<T>::DivElt(const TArray<T>& a, bool fginv, bool divzero)
856{
857 if (NbDimensions() < 1)
858 throw RangeCheckError("TArray<T>::DivElt(const TArray<T>& ) - Not Allocated Array ! ");
859 bool smo;
860 if (!CompareSizes(a, smo))
861 throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&) SizeMismatch")) ;
862
863 T * pe;
864 const T * pea;
865 sa_size_t j,k,ka;
866 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
867 sa_size_t step = AvgStep();
868 sa_size_t stepa = a.AvgStep();
869 sa_size_t maxx = totsize_*step;
870 pe = Data();
871 pea = a.Data();
872 if(divzero) {
873 if (fginv)
874 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa )
875 {if(pe[k]==(T)0) pe[k] = (T)0; else pe[k] = pea[ka]/pe[k];}
876 else
877 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa )
878 {if(pea[k]==(T)0) pe[k] = (T)0; else pe[k] /= pea[ka] ;}
879 } else {
880 if (fginv)
881 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka]/pe[k];
882 else
883 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] /= pea[ka] ;
884 }
885 }
886 else { // Non regular data spacing ...
887 int_4 ax,axa;
888 sa_size_t step, stepa;
889 sa_size_t gpas, naxa;
890 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
891 for(j=0; j<naxa; j++) {
892 pe = mNDBlock.Begin()+Offset(ax,j);
893 pea = a.DataBlock().Begin()+a.Offset(axa,j);
894 if(divzero) {
895 if (fginv)
896 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa)
897 {if(pe[k]==(T)0) pe[k] = (T)0; else pe[k] = pea[ka]/pe[k];}
898 else
899 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa)
900 {if(pea[k]==(T)0) pe[k] = (T)0; else pe[k] /= pea[ka];}
901 } else {
902 if (fginv)
903 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka]/pe[k];
904 else
905 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] /= pea[ka];
906 }
907 }
908 }
909 return(*this);
910}
911
912//! Copy elements of \b a
913template <class T>
914TArray<T>& TArray<T>::CopyElt(const TArray<T>& a)
915{
916 if (NbDimensions() < 1)
917 throw RangeCheckError("TArray<T>::CopyElt(const TArray<T>& ) - Not Allocated Array ! ");
918 bool smo;
919 if (!CompareSizes(a, smo))
920 throw(SzMismatchError("TArray<T>::CopyElt(const TArray<T>&) SizeMismatch")) ;
921
922 T * pe;
923 const T * pea;
924 sa_size_t j,k,ka;
925 if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements
926 sa_size_t step = AvgStep();
927 sa_size_t stepa = a.AvgStep();
928 sa_size_t maxx = totsize_*step;
929 pe = Data();
930 pea = a.Data();
931 for(k=0, ka=0; k<maxx; k+=step, ka+=stepa ) pe[k] = pea[ka] ;
932 }
933 else { // Non regular data spacing ...
934 int_4 ax,axa;
935 sa_size_t step, stepa;
936 sa_size_t gpas, naxa;
937 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
938 for(j=0; j<naxa; j++) {
939 pe = mNDBlock.Begin()+Offset(ax,j);
940 pea = a.DataBlock().Begin()+a.Offset(axa,j);
941 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = pea[ka];
942 }
943 }
944 return(*this);
945}
946
947//! Converts and Copy elements of \b a
948template <class T>
949TArray<T>& TArray<T>::ConvertAndCopyElt(const BaseArray& a)
950{
951 if (NbDimensions() < 1)
952 throw RangeCheckError("TArray<T>::ConvertAndCopyElt(const TArray<T>& ) - Not Allocated Array ! ");
953 bool smo;
954 if (!CompareSizes(a, smo))
955 throw(SzMismatchError("TArray<T>::ConvertAndCopyElt(const TArray<T>&) SizeMismatch")) ;
956
957 T * pe;
958 sa_size_t j,k,ka;
959 sa_size_t offa;
960 // Non regular data spacing ...
961 int_4 ax,axa;
962 sa_size_t step, stepa;
963 sa_size_t gpas, naxa;
964 GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
965 for(j=0; j<naxa; j++) {
966 pe = mNDBlock.Begin()+Offset(ax,j);
967 offa = a.Offset(axa,j);
968/*
969 Appel explicite de l'operateur de conversion
970 suite a la suggestion de M. Reinecke, Reza 31/7/2002
971#if !defined(__GNUG__)
972 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = (T)a.ValueAtPosition(offa+ka);
973#else
974 // g++ (up to 2.95.1) se melange les pinceaux s'il y a le cast (T) pour l'instanciation des complexes
975 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa) pe[k] = a.ValueAtPosition(offa+ka);
976#endif
977 --- Appel explicite de l'operateur de conversion sur l'objet MuTyV
978*/
979 for(k=0, ka=0; k<gpas; k+=step, ka+=stepa)
980 pe[k] = a.ValueAtPosition(offa+ka).operator T();
981 }
982 return(*this);
983}
984
985
986// Somme et produit des elements
987//! Sum all elements
988template <class T>
989T TArray<T>::Sum() const
990{
991 if (NbDimensions() < 1)
992 throw RangeCheckError("TArray<T>::Sum() - Not Allocated Array ! ");
993 T ret=0;
994 const T * pe;
995 sa_size_t j,k;
996 if (AvgStep() > 0) { // regularly spaced elements
997 sa_size_t step = AvgStep();
998 sa_size_t maxx = totsize_*step;
999 pe = Data();
1000 for(k=0; k<maxx; k+=step ) ret += pe[k];
1001 }
1002 else { // Non regular data spacing ...
1003 int_4 ka = MaxSizeKA();
1004 sa_size_t step = Step(ka);
1005 sa_size_t gpas = Size(ka)*step;
1006 sa_size_t naxa = Size()/Size(ka);
1007 for(j=0; j<naxa; j++) {
1008 pe = mNDBlock.Begin()+Offset(ka,j);
1009 for(k=0; k<gpas; k+=step) ret += pe[k] ;
1010 }
1011 }
1012 return ret;
1013}
1014
1015//! Multiply all elements
1016template <class T>
1017T TArray<T>::Product() const
1018{
1019 if (NbDimensions() < 1)
1020 throw RangeCheckError("TArray<T>::Product() - Not Allocated Array ! ");
1021 T ret=(T)1;
1022 const T * pe;
1023 sa_size_t j,k;
1024 if (AvgStep() > 0) { // regularly spaced elements
1025 sa_size_t step = AvgStep();
1026 sa_size_t maxx = totsize_*step;
1027 pe = Data();
1028 for(k=0; k<maxx; k+=step ) ret *= pe[k];
1029 }
1030 else { // Non regular data spacing ...
1031 int_4 ka = MaxSizeKA();
1032 sa_size_t step = Step(ka);
1033 sa_size_t gpas = Size(ka)*step;
1034 sa_size_t naxa = Size()/Size(ka);
1035 for(j=0; j<naxa; j++) {
1036 pe = mNDBlock.Begin()+Offset(ka,j);
1037 for(k=0; k<gpas; k+=step) ret *= pe[k] ;
1038 }
1039 }
1040 return ret;
1041}
1042
1043//! Returns the sum of all elements squared (Sum
1044template <class T>
1045T TArray<T>::SumX2() const
1046{
1047 if (NbDimensions() < 1)
1048 throw RangeCheckError("TArray<T>::SumX2() - Not Allocated Array ! ");
1049 T ret=0;
1050 const T * pe;
1051 sa_size_t j,k;
1052 if (AvgStep() > 0) { // regularly spaced elements
1053 sa_size_t step = AvgStep();
1054 sa_size_t maxx = totsize_*step;
1055 pe = Data();
1056 for(k=0; k<maxx; k+=step ) ret += pe[k]*pe[k];
1057 }
1058 else { // Non regular data spacing ...
1059 int_4 ka = MaxSizeKA();
1060 sa_size_t step = Step(ka);
1061 sa_size_t gpas = Size(ka)*step;
1062 sa_size_t naxa = Size()/Size(ka);
1063 for(j=0; j<naxa; j++) {
1064 pe = mNDBlock.Begin()+Offset(ka,j);
1065 for(k=0; k<gpas; k+=step) ret += pe[k]*pe[k] ;
1066 }
1067 }
1068 return ret;
1069}
1070
1071//! Return the minimum and the maximum values of the array elements
1072/*!
1073 This method generates an exception (\c MathExc) if called for complex arrays
1074*/
1075
1076template <class T>
1077void TArray<T>::MinMax(T& min, T& max) const
1078{
1079 const T * pe;
1080 sa_size_t j,k;
1081 int_4 ka = MaxSizeKA();
1082 sa_size_t step = Step(ka);
1083 sa_size_t gpas = Size(ka)*step;
1084 sa_size_t naxa = Size()/Size(ka);
1085 min = (*this)[0];
1086 max = (*this)[0];
1087 for(j=0; j<naxa; j++) {
1088 pe = mNDBlock.Begin()+Offset(ka,j);
1089 for(k=0; k<gpas; k+=step) {
1090 if (pe[k]<min) min = pe[k];
1091 else if (pe[k]>max) max = pe[k];
1092 }
1093 }
1094 return;
1095}
1096
1097DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
1098void TArray< complex<r_4> >::MinMax(complex<r_4>& min, complex<r_4>& max) const
1099{
1100 throw MathExc("TArray< complex<r_4> >::MinMax(...) - No order in complex");
1101}
1102DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
1103void TArray< complex<r_8> >::MinMax(complex<r_8>& min, complex<r_8>& max) const
1104{
1105 throw MathExc("TArray< complex<r_4> >::MinMax(...) - No order in complex");
1106}
1107
1108
1109// ----------------------------------------------------
1110// Impression, etc ...
1111// ----------------------------------------------------
1112
1113//! Return a string that contain the type \b T of the array
1114template <class T>
1115string TArray<T>::InfoString() const
1116{
1117 string rs = "TArray<" ;
1118 rs += typeid(T).name();
1119 rs += "> ";
1120 return(rs);
1121}
1122
1123//! Print array
1124/*!
1125 \param os : output stream
1126 \param maxprt : maximum numer of print
1127 \param si : if true, display attached DvList
1128 \param ascd : if true, suppresses the display of line numbers,
1129 suitable for ascii dump format.
1130 \sa SetMaxPrint
1131 \sa WriteASCII
1132 */
1133template <class T>
1134void TArray<T>::Print(ostream& os, sa_size_t maxprt, bool si, bool ascd) const
1135{
1136 if (maxprt < 0) maxprt = max_nprt_;
1137 sa_size_t npr = 0;
1138 Show(os, si);
1139 if (ndim_ < 1) return;
1140 sa_size_t k0,k1,k2,k3,k4;
1141 for(k4=0; k4<size_[4]; k4++) {
1142 if ((size_[4] > 1) && ascd)
1143 cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
1144 for(k3=0; k3<size_[3]; k3++) {
1145 if ((size_[3] > 1) && ascd)
1146 cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
1147 for(k2=0; k2<size_[2]; k2++) {
1148 if ((size_[2] > 1) & ascd)
1149 cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
1150 for(k1=0; k1<size_[1]; k1++) {
1151 if ( (size_[1] > 1) && (size_[0] > 10) && ascd)
1152 cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
1153 for(k0=0; k0<size_[0]; k0++) {
1154 if(k0 > 0) os << " ";
1155 os << Elem(k0, k1, k2, k3, k4); npr++;
1156 if (npr >= (sa_size_t) maxprt) {
1157 if (npr < totsize_) os << "\n .... " << endl; return;
1158 }
1159 }
1160 os << endl;
1161 }
1162 }
1163 }
1164 }
1165 os << endl;
1166}
1167
1168//! Fill the array, decoding the ASCII input stream
1169/*!
1170 \param is : input stream (ASCII)
1171 \param nr : Number of non empty (or comment) lines in stream (return value)
1172 \param nc : Number of columns (= ntot/nlines) (return value)
1173 \param clm : Lines starting with clm character are treated as comment lines
1174 \param sep : word separator in lines
1175 \return Number of decoded elements
1176*/
1177template <class T>
1178sa_size_t TArray<T>::ReadASCII(istream& is, sa_size_t & nr, sa_size_t & nc,
1179 char clm, const char* sep)
1180{
1181 EnumeratedSequence es;
1182 sa_size_t n = es.FillFromFile(is, nr, nc, clm, sep);
1183 if ( (n < 1) || (nr < 1) || (nc < 1) ) return(n);
1184 if (!IsAllocated()) {
1185 sa_size_t sz[2];
1186 if (arrtype_ == 2) { // C'est un vecteur
1187 sz[0] = sz[1] = 1;
1188 sz[veceli_] = n;
1189 }
1190 else {
1191 sz[RowsKA()] = nr;
1192 sz[ColsKA()] = nc;
1193 }
1194 ReSize(2, sz);
1195 }
1196 SetSeq(es);
1197 cout << "TArray<T>::ReadASCII()/Info: " << n << " elements read from stream "
1198 << " (Row,Col= " << nr << "," << nc << ")" << endl;
1199 return(n);
1200}
1201
1202//! Writes the array content to the output stream, (in ASCII)
1203/*!
1204 \param os : output stream (ASCII)
1205 \sa Print
1206 */
1207template <class T>
1208void TArray<T>::WriteASCII(ostream& os) const
1209{
1210 Print(os, Size(), false, true);
1211}
1212
1213
1214
1215///////////////////////////////////////////////////////////////
1216///////////////////////////////////////////////////////////////
1217#ifdef __CXX_PRAGMA_TEMPLATES__
1218/*
1219#pragma define_template TArray<uint_1>
1220#pragma define_template TArray<int_2>
1221#pragma define_template TArray<uint_4>
1222*/
1223#pragma define_template TArray<uint_2>
1224#pragma define_template TArray<uint_8>
1225#pragma define_template TArray<int_4>
1226#pragma define_template TArray<int_8>
1227#pragma define_template TArray<r_4>
1228#pragma define_template TArray<r_8>
1229#pragma define_template TArray< complex<r_4> >
1230#pragma define_template TArray< complex<r_8> >
1231#endif
1232
1233#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1234/*
1235template class TArray<uint_1>;
1236template class TArray<int_2>;
1237template class TArray<uint_4>;
1238*/
1239template class TArray<uint_2>;
1240template class TArray<uint_8>;
1241template class TArray<int_4>;
1242template class TArray<int_8>;
1243template class TArray<r_4>;
1244template class TArray<r_8>;
1245template class TArray< complex<r_4> >;
1246template class TArray< complex<r_8> >;
1247#endif
1248
1249
Note: See TracBrowser for help on using the repository browser.