// template array class for numerical types // R. Ansari, C.Magneville 03/2000 #include "sopnamsp.h" #include "machdefs.h" #include #include #include #include #include "pexceptions.h" #include "tarray.h" /*! \class SOPHYA::TArray \ingroup TArray Class for template arrays with numerical data types (int, float, complex). This class implements arrays with number of dimensions up to \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS" Standard arithmetic operations on numerical arrays are implemented, as well as sub-array manipulation services. \b Array is a typedef for double precision floating point arrays ( TArray ) \sa SOPHYA::Range \sa SOPHYA::Sequence \sa SOPHYA::MathArray \code #include "array.h" // ... // Creating and initialising a 1-D array of integers TArray ia(5); EnumeratedSequence es; es = 24, 35, 46, 57, 68; ia = es; cout << "Array ia = " << ia; // 2-D array of floats TArray b(6,4), c(6,4); // Initializing b with a constant b = 2.71828; // Filling c with random numbers c = RandomSequence(); // Arithmetic operations TArray d = b+0.3f*c; cout << "Array d = " << d; \endcode */ /*! \ingroup TArray \typedef sa_size_t \brief Array index range and size, defined to be a 4-byte or 8-byte integer */ // ------------------------------------------------------- // Methodes de la classe // ------------------------------------------------------- ////////////////////////// Les constructeurs / destructeurs //! Default constructor template TArray::TArray() : BaseArray() , mNDBlock() { } //! Constructor /*! \param ndim : number of dimensions (less or equal to \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS") \param siz[ndim] : size along each dimension \param step : step (same for all dimensions) \param fzero : if \b true , set array elements to zero */ template TArray::TArray(int_4 ndim, const sa_size_t * siz, sa_size_t step, bool fzero) : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), fzero) { string exmsg = "TArray::TArray(int_4, sa_size_t *, sa_size_t)"; if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) ); } //! Constructor /*! \param nx,ny,nz,nt,nu : sizes along first, second, third, fourth and fifth dimension \param fzero : if \b true , set array elements to zero */ template TArray::TArray(sa_size_t nx, sa_size_t ny, sa_size_t nz, sa_size_t nt, sa_size_t nu, bool fzero) : BaseArray() , mNDBlock(nx*((ny>0)?ny:1)*((nz>0)?nz:1)*((nt>0)?nt:1)*((nu>0)?nu:1)) { sa_size_t size[BASEARRAY_MAXNDIMS]; size[0] = nx; size[1] = ny; size[2] = nz; size[3] = nt; size[4] = nu; int_4 ndim = 1; if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) && (size[4] > 0) ) ndim = 5; else if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) ) ndim = 4; else if ((size[1] > 0) && (size[2] > 0)) ndim = 3; else if (size[1] > 0) ndim = 2; else ndim = 1; string exmsg = "TArray::TArray(sa_size_t, sa_size_t, sa_size_t, sa_size_t, sa_size_t)"; if (!UpdateSizes(ndim, size, 1, 0, exmsg)) throw( ParmError(exmsg) ); } //! Constructor /*! \param ndim : number of dimensions \param siz[ndim] : size along each dimension \param db : datas are given by this NDataBlock \param share : if true, data are shared, if false they are copied \param step : step (same for all dimensions) in data block \param offset : offset for first element in data block */ template TArray::TArray(int_4 ndim, const sa_size_t * siz, NDataBlock & db, bool share, sa_size_t step, sa_size_t offset) : BaseArray() , mNDBlock(db, share) { string exmsg = "TArray::TArray(int_4, sa_size_t *, NDataBlock & ... )"; if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) ); if (mNDBlock.Size() < ComputeTotalSize(ndim, siz, step, offset)) { exmsg += " DataBlock.Size() < ComputeTotalSize(...) " ; throw( ParmError(exmsg) ); } } //! Constructor /*! \param ndim : number of dimensions \param siz[ndim] : size along each dimension \param values : datas are given by this pointer \param share : if true, data are shared, if false they are copied \param step : step (same for all dimensions) in data block \param offset : offset for first element in data block \param br : if not NULL, dats are bridge with other datas \sa NDataBlock */ template TArray::TArray(int_4 ndim, const sa_size_t * siz, T* values, sa_size_t step, sa_size_t offset, Bridge* br) : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), values, br) { string exmsg = "TArray::TArray(int_4, sa_size_t *, T* ... )"; if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) ); } //! Constructor by copy /*! \warning datas are \b SHARED with \b a. \sa NDataBlock::NDataBlock(const NDataBlock&) */ template TArray::TArray(const TArray& a) : BaseArray() , mNDBlock(a.mNDBlock) { string exmsg = "TArray::TArray(const TArray&)"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Constructor by copy /*! \param share : if true, data are shared, if false they are copied */ template TArray::TArray(const TArray& a, bool share) : BaseArray() , mNDBlock(a.mNDBlock, share) { if (a.NbDimensions() == 0) return; string exmsg = "TArray::TArray(const TArray&, bool)"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Constructor with size and contents copied (after conversion) from a different type TArray template TArray::TArray(const BaseArray& a) : BaseArray() , mNDBlock() { if (a.NbDimensions() == 0) return; string exmsg = "TArray::TArray(const BaseArray&)"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); mNDBlock.ReSize(totsize_); // if (a.mInfo) mInfo = new DVList(*(a.mInfo)); - pb protected ! ConvertAndCopyElt(a); } //! Destructor template TArray::~TArray() { } ////////////////////////// Les methodes de copie/share //! Set array equal to \b a and return *this /*! If the array is already allocated, CopyElt() is called for checking that the two arrays have the same size and for copying the array element values. For non allocated arrays, CloneOrShare() is called. The array memory organization is also copied from \b a. \warning Datas are copied (cloned) from \b a. \sa CopyElt \sa CloneOrShare \sa NDataBlock::operator=(const NDataBlock&) */ template TArray& TArray::Set(const TArray& a) { if (this == &a) return(*this); if (a.NbDimensions() < 1) throw RangeCheckError("TArray::Set(a ) - Array a not allocated ! "); if (NbDimensions() < 1) CloneOrShare(a); else CopyElt(a); return(*this); } //! Set array elements equal to the \b a array elements, after conversion template TArray& TArray::SetBA(const BaseArray& a) { if (this == &a) return(*this); if (a.NbDimensions() < 1) throw RangeCheckError("TArray::SetBA(a ) - Array a not allocated ! "); if (NbDimensions() < 1) { string exmsg = "TArray::SetBA(const BaseArray& a)"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); mNDBlock.ReSize(totsize_); } ConvertAndCopyElt(a); return(*this); } //! Clone array \b a template void TArray::Clone(const TArray& a) { string exmsg = "TArray::Clone()"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); mNDBlock.Clone(a.mNDBlock); if (mInfo) {delete mInfo; mInfo = NULL;} if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Clone if \b a is not temporary, share if temporary /*! \sa NDataBlock::CloneOrShare(const NDataBlock&) */ template void TArray::CloneOrShare(const TArray& a) { string exmsg = "TArray::CloneOrShare()"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); mNDBlock.CloneOrShare(a.mNDBlock); if (mInfo) {delete mInfo; mInfo = NULL;} if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Share data with a template void TArray::Share(const TArray& a) { string exmsg = "TArray::Share()"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); mNDBlock.Share(a.mNDBlock); if (mInfo) {delete mInfo; mInfo = NULL;} if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Sets or changes the array size /*! \param ndim : number of dimensions \param siz[ndim] : size along each dimension \param step : step (same for all dimensions) \param fzero : if \b true , set array elements to zero */ template void TArray::ReSize(int_4 ndim, sa_size_t * siz, sa_size_t step, bool fzero) { if (arrtype_ != 0) { if (ndim != 2) throw( ParmError("TArray::ReSize(ndim!=2,...) for Matrix" ) ); if ((arrtype_ == 2) && (siz[0] > 1) && (siz[1] > 1)) throw( ParmError("TArray::ReSize(,siz[0]>1 && size[1]>1) for Vector" ) ); } string exmsg = "TArray::ReSize(int_4 ...)"; if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) ); mNDBlock.ReSize(totsize_, fzero); } //! Sets or changes the array size. /*! The array size and memory layout are copied from the array \b a. \param a : Array used as template for setting the size and memory layout. \param pack : if \b true , create a packed array, else same memory layout as \b a. \param fzero : if \b true , set array elements to zero */ template void TArray::ReSize(const BaseArray& a, bool pack, bool fzero) { if (arrtype_ != 0) { if (a.NbDimensions() != 2) throw( ParmError("TArray::ReSize(a.NbDimensions()!=2,...) for Matrix" ) ); if ((arrtype_ == 2) && (a.Size(0) > 1) && (a.Size(1) > 1)) throw( ParmError("TArray::ReSize(a.Size(0)>1 && a.Size(1)>1) for Vector" ) ); } string exmsg = "TArray::ReSize(const TArray&)"; if (pack) { sa_size_t siz[BASEARRAY_MAXNDIMS]; int ksz; for(ksz=0; ksz void TArray::Realloc(int_4 ndim, sa_size_t * siz, sa_size_t step, bool force) { if (arrtype_ != 0) { if (ndim != 2) throw( ParmError("TArray::Realloc(ndim!=2,...) for Matrix" ) ); if ((arrtype_ == 2) && (siz[0] > 1) && (siz[1] > 1)) throw( ParmError("TArray::Realloc(,siz[0]>1 && size[1]>1) for Vector" ) ); } string exmsg = "TArray::Realloc()"; if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) ); mNDBlock.Realloc(totsize_, force); } //! Compact dimensions in one or more is equal to 1. template TArray& TArray::CompactAllDimensions() { CompactAllDim(); return(*this); } //! Compact dimensions if the last one is equal to 1. template TArray& TArray::CompactTrailingDimensions() { CompactTrailingDim(); return(*this); } //! Give value (in \b double) for element at position \b ip.. template MuTyV & TArray::ValueAtPosition(sa_size_t ip) const { #ifdef SO_BOUNDCHECKING if (ip >= totsize_) throw( ParmError("TArray::ValueAtPosition(sa_size_t ip) Out-of-bound Error") ); #endif my_mtv = *(mNDBlock.Begin()+Offset(ip)); return( my_mtv ); } //! Return array with elements packed /*! \param force : if true, pack elements in a new array. If false and array is already packed, return an array that share data with the current one. \return packed array */ template TArray TArray::PackElements(bool force) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::PackElements() - Not Allocated Array ! "); if ( !force && (AvgStep() == 1) ) { TArray ra; ra.Share(*this); ra.SetTemp(true); return(ra); } else { TArray ra(ndim_, size_, 1); ra.CopyElt(*this); ra.SetTemp(true); return(ra); } } // SubArrays // $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ? //! Extract a sub-array /*! \param rx,ry,rz,rt,ru : range of extraction along dimensions \sa Range */ template TArray TArray::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::operator () (Range, ...) - Not Allocated Array ! "); int_4 ndim = 0; sa_size_t size[BASEARRAY_MAXNDIMS]; sa_size_t step[BASEARRAY_MAXNDIMS]; sa_size_t pos[BASEARRAY_MAXNDIMS]; size[0] = rx.Size(); size[1] = ry.Size(); size[2] = rz.Size(); size[3] = rt.Size(); size[4] = ru.Size(); step[0] = rx.Step(); step[1] = ry.Step(); step[2] = rz.Step(); step[3] = rt.Step(); step[4] = ru.Step(); pos[0] = rx.Start(); pos[1] = ry.Start(); pos[2] = rz.Start(); pos[3] = rt.Start(); pos[4] = ru.Start(); ndim = ndim_; TArray ra; UpdateSubArraySizes(ra, ndim, size, pos, step); ra.DataBlock().Share(this->DataBlock()); ra.SetTemp(true); return(ra); } // ...... Operation de calcul sur les tableaux ...... // ------- Attention -------- // Boucles normales prenant en compte les steps .... // Possibilite de // , vectorisation //! Fill TArray with Sequence \b seq /*! \param seq : sequence to fill the array \sa Sequence */ template TArray& TArray::SetSeq(Sequence const & seq) { if (NbDimensions() < 1) throw RangeCheckError("TArray::SetSeq(Sequence ) - Not Allocated Array ! "); T * pe; sa_size_t j,k; int_4 ka; if (arrtype_ == 0) ka = 0; else ka = macoli_; sa_size_t step = Step(ka); sa_size_t gpas = Size(ka); sa_size_t naxa = Size()/Size(ka); for(j=0; j>>> Operations avec 2nd membre de type scalaire //! Fill an array with a constant value \b x template TArray& TArray::SetCst(T x) { if (NbDimensions() < 1) throw RangeCheckError("TArray::SetCst(T ) - Not Allocated Array ! "); T * pe; sa_size_t j,k; if (AvgStep() > 0) { // regularly spaced elements sa_size_t step = AvgStep(); sa_size_t maxx = totsize_*step; pe = Data(); for(k=0; k TArray& TArray::AddCst(T x, TArray& res) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::AddCst(T,res) - Not allocated source array "); if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smo; if (!CompareSizes(res, smo)) throw(SzMismatchError("TArray::AddCst(T, res) SizeMismatch(this,res) ")) ; const T * pe; T * per; sa_size_t j,k; if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements sa_size_t maxx = totsize_; pe = Data(); per = res.Data(); for(k=0; k TArray& TArray::SubCst(T x, TArray& res, bool fginv) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::SubCst(T,res) - Not allocated source array "); if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smo; if (!CompareSizes(res, smo)) throw(SzMismatchError("TArray::SubCst(T, res) SizeMismatch(this,res) ")) ; const T * pe; T * per; sa_size_t j,k; if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements sa_size_t maxx = totsize_; pe = Data(); per = res.Data(); if (!fginv) for(k=0; k TArray& TArray::MulCst(T x, TArray& res) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::MulCst(T,res) - Not allocated source array "); if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smo; if (!CompareSizes(res, smo)) throw(SzMismatchError("TArray::MulCst(T, res) SizeMismatch(this,res) ")) ; const T * pe; T * per; sa_size_t j,k; if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements sa_size_t maxx = totsize_; pe = Data(); per = res.Data(); for(k=0; k TArray& TArray::DivCst(T x, TArray& res, bool fginv) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::DivCst(T,res) - Not allocated source array ! "); if (!fginv && (x == (T) 0) ) throw MathExc("TArray::DivCst(T,res) - Divide by zero ! "); if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smo; if (!CompareSizes(res, smo)) throw(SzMismatchError("TArray::DivCst(T, res) SizeMismatch(this,res) ")) ; const T * pe; T * per; sa_size_t j,k; if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements sa_size_t maxx = totsize_; pe = Data(); per = res.Data(); if (!fginv) for(k=0; k TArray& TArray::NegateElt(TArray& res) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::NegateElt(res) - Not allocated source array "); if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smo; if (!CompareSizes(res, smo)) throw(SzMismatchError("TArray::NegateElt(res) SizeMismatch(this,res) ")) ; const T * pe; T * per; sa_size_t j,k; if (smo && (IsPacked() > 0) && (res.IsPacked() > 0)) { // regularly spaced elements sa_size_t maxx = totsize_; pe = Data(); per = res.Data(); for(k=0; k>>> Operations avec 2nd membre de type tableau //! Two TArrays element by element addition /*! Perform element by element addition of the source array (this) and the \b a array and store the result in \b res (res = *this+a). The source and argument arrays (this, a) should have the same sizes. If not initially allocated, the output array \b res is automatically resized as a packed array with the same sizes as the source (this) array. Returns a reference to the output array \b res. \param a : Array to be added to the source array. \param res : Output array containing the result (res=this+a). */ template TArray& TArray::AddElt(const TArray& a, TArray& res) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::AddElt(...) - Not allocated source array ! "); bool smoa; if (!CompareSizes(a, smoa)) throw(SzMismatchError("TArray::AddElt(...) SizeMismatch(this,a)")) ; if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smor; if (!CompareSizes(res, smor)) throw(SzMismatchError("TArray::AddElt(...) SizeMismatch(this,res) ")) ; bool smora; a.CompareSizes(res, smora); bool smo = smoa && smor; // The three arrays have same memory organisation const T * pe; const T * pea; T * per; sa_size_t j,k; if (smo && IsPacked() && a.IsPacked() && res.IsPacked() ) { // All packed arrays sa_size_t maxx = totsize_; pe = Data(); pea = a.Data(); per = res.Data(); // for(k=0; k TArray& TArray::SubElt(const TArray& a, TArray& res, bool fginv) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::SubElt(...) - Not allocated source array ! "); bool smoa; if (!CompareSizes(a, smoa)) throw(SzMismatchError("TArray::SubElt(...) SizeMismatch(this,a)")) ; if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smor; if (!CompareSizes(res, smor)) throw(SzMismatchError("TArray::SubElt(...) SizeMismatch(this,res) ")) ; bool smora; a.CompareSizes(res, smora); bool smo = smoa && smor; // The three arrays have same memory organisation const T * pe; const T * pea; T * per; sa_size_t j,k; if (smo && IsPacked() && a.IsPacked() && res.IsPacked() ) { // All packed arrays sa_size_t maxx = totsize_; pe = Data(); pea = a.Data(); per = res.Data(); if (!fginv) for(k=0; k TArray& TArray::MulElt(const TArray& a, TArray& res) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::MulElt(...) - Not allocated source array ! "); bool smoa; if (!CompareSizes(a, smoa)) throw(SzMismatchError("TArray::MulElt(...) SizeMismatch(this,a)")) ; if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smor; if (!CompareSizes(res, smor)) throw(SzMismatchError("TArray::MulElt(...) SizeMismatch(this,res) ")) ; bool smora; a.CompareSizes(res, smora); bool smo = smoa && smor; // The three arrays have same memory organisation const T * pe; const T * pea; T * per; sa_size_t j,k; if (smo && IsPacked() && a.IsPacked() && res.IsPacked() ) { // All packed arrays sa_size_t maxx = totsize_; pe = Data(); pea = a.Data(); per = res.Data(); for(k=0; k TArray& TArray::DivElt(const TArray& a, TArray& res, bool fginv, bool divzero) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::DivElt(...) - Not allocated source array ! "); bool smoa; if (!CompareSizes(a, smoa)) throw(SzMismatchError("TArray::DivElt(...) SizeMismatch(this,a)")) ; if (res.NbDimensions() < 1) res.SetSize(*this, true, false); bool smor; if (!CompareSizes(res, smor)) throw(SzMismatchError("TArray::DivElt(...) SizeMismatch(this,res) ")) ; bool smora; a.CompareSizes(res, smora); bool smo = smoa && smor; // The three arrays have same memory organisation const T * pe; const T * pea; T * per; sa_size_t j,k; if (smo && IsPacked() && a.IsPacked() && res.IsPacked() ) { // All packed arrays sa_size_t maxx = totsize_; pe = Data(); pea = a.Data(); per = res.Data(); if(divzero) { if (!fginv) for(k=0; k::CopyElt(const TArray& ) - Not Allocated Array ! "); bool smo; if (!CompareSizes(a, smo)) throw(SzMismatchError("TArray::CopyElt(const TArray&) SizeMismatch")) ; T * pe; const T * pea; sa_size_t j,k; if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements if (IsPacked() && a.IsPacked()) memcpy(Data(), a.Data(), totsize_*sizeof(T)); // Packed arrays else { sa_size_t step = AvgStep(); sa_size_t stepa = a.AvgStep(); sa_size_t maxx = totsize_*step; pe = Data(); pea = a.Data(); for(k=0; k TArray& TArray::ConvertAndCopyElt(const BaseArray& a) { if (NbDimensions() < 1) throw RangeCheckError("TArray::ConvertAndCopyElt(const TArray& ) - Not Allocated Array ! "); bool smo; if (!CompareSizes(a, smo)) throw(SzMismatchError("TArray::ConvertAndCopyElt(const TArray&) SizeMismatch")) ; T * pe; sa_size_t j,k,ka; sa_size_t offa; // Non regular data spacing ... int_4 ax,axa; sa_size_t step, stepa; sa_size_t gpas, naxa; GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa); for(j=0; j T TArray::ScalarProduct(const TArray& a) const { if (NbDimensions() < 1) throw RangeCheckError("TArray::ScalarProduct(...) - Not allocated source array "); bool smo; if (!CompareSizes(a, smo)) throw(SzMismatchError("TArray::ScalarProduct(...) SizeMismatch(this,a) ")) ; T res = (T)(0); const T * pe; const T * pea; sa_size_t j,k; if (smo && (IsPacked() > 0) && (a.IsPacked() > 0)) { // regularly spaced elements sa_size_t maxx = totsize_; pe = Data(); pea = a.Data(); for(k=0; k T TArray::Sum() const { if (NbDimensions() < 1) throw RangeCheckError("TArray::Sum() - Not Allocated Array ! "); T ret=0; const T * pe; sa_size_t j,k; if (AvgStep() > 0) { // regularly spaced elements sa_size_t step = AvgStep(); sa_size_t maxx = totsize_*step; pe = Data(); for(k=0; k T TArray::Product() const { if (NbDimensions() < 1) throw RangeCheckError("TArray::Product() - Not Allocated Array ! "); T ret=(T)1; const T * pe; sa_size_t j,k; if (AvgStep() > 0) { // regularly spaced elements sa_size_t step = AvgStep(); sa_size_t maxx = totsize_*step; pe = Data(); for(k=0; k T TArray::SumX2() const { if (NbDimensions() < 1) throw RangeCheckError("TArray::SumX2() - Not Allocated Array ! "); T ret=0; const T * pe; sa_size_t j,k; if (AvgStep() > 0) { // regularly spaced elements sa_size_t step = AvgStep(); sa_size_t maxx = totsize_*step; pe = Data(); for(k=0; k void TArray::MinMax(T& min, T& max) const { const T * pe; sa_size_t j,k; int_4 ka = MaxSizeKA(); sa_size_t step = Step(ka); sa_size_t gpas = Size(ka)*step; sa_size_t naxa = Size()/Size(ka); min = (*this)[0]; max = (*this)[0]; for(j=0; jmax) max = pe[k]; } } return; } DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void TArray< complex >::MinMax(complex& min, complex& max) const { throw MathExc("TArray< complex >::MinMax(...) - No order in complex"); } DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void TArray< complex >::MinMax(complex& min, complex& max) const { throw MathExc("TArray< complex >::MinMax(...) - No order in complex"); } // ---------------------------------------------------- // Impression, etc ... // ---------------------------------------------------- //! Return a string that contain the type \b T of the array template string TArray::InfoString() const { string rs = "TArray<" ; rs += typeid(T).name(); rs += "> "; return(rs); } //! Print array /*! \param os : output stream \param maxprt : maximum numer of print \param si : if true, display attached DvList \param ascd : if true, suppresses the display of line numbers, suitable for ascii dump format. \sa SetMaxPrint \sa WriteASCII */ template void TArray::Print(ostream& os, sa_size_t maxprt, bool si, bool ascd) const { if (maxprt < 0) maxprt = max_nprt_; sa_size_t npr = 0; // keep stream's io flags // ios_base::fmtflags ioflg = os.flags(); compile pas sur OSF-cxx // os << right ; compile pas sur OSF-cxx Show(os, si); if (ndim_ < 1) return; // Calcul de la largeur d'impression pour chaque element int fprtw = os.precision()+7; int prtw = 5; if ( (typeid(T) == typeid( int_4 )) || (typeid(T) == typeid( uint_4 )) ) prtw = 8; else if ( (typeid(T) == typeid( int_8 )) || (typeid(T) == typeid( uint_8 )) ) prtw = 11; else if ( typeid(T) == typeid( r_4 ) ) prtw = fprtw; else if ( typeid(T) == typeid( r_8 ) ) prtw = fprtw; else if ( typeid(T) == typeid(complex) ) prtw = fprtw; else if ( typeid(T) == typeid(complex) ) prtw = fprtw; sa_size_t k0,k1,k2,k3,k4; for(k4=0; k4 1) && !ascd) os << "\n ----- Dimension 5 (U) K4= " << k4 << endl; for(k3=0; k3 1) && !ascd) os << "\n ----- Dimension 4 (T) K3= " << k3 << endl; for(k2=0; k2 1) && !ascd) os << "\n ----- Dimension 3 (Z) K2= " << k2 << endl; for(k1=0; k1 1) && (size_[0] > 10) && !ascd) os << "----- Dimension 2 (Y) K1= " << k1 << endl; for(k0=0; k0 0) os << " "; os << setw(prtw) << Elem(k0, k1, k2, k3, k4); npr++; if (npr >= (sa_size_t) maxprt) { if (npr < totsize_) os << "\n .... " << endl; return; } } os << endl; } } } } os << endl; //compile pas sur OSF-cxx os.flags(ioflg); // reset stream io flags } //! Fill the array, decoding the ASCII input stream /*! \param is : input stream (ASCII) \param nr : Number of non empty (or comment) lines in stream (return value) \param nc : Number of columns (= ntot/nlines) (return value) \param clm : Lines starting with clm character are treated as comment lines \param sep : word separator in lines \return Number of decoded elements */ template sa_size_t TArray::ReadASCII(istream& is, sa_size_t & nr, sa_size_t & nc, char clm, const char* sep) { EnumeratedSequence es; sa_size_t n = es.FillFromFile(is, nr, nc, clm, sep); if ( (n < 1) || (nr < 1) || (nc < 1) ) return(n); if (!IsAllocated()) { sa_size_t sz[2]; if (arrtype_ == 2) { // C'est un vecteur sz[0] = sz[1] = 1; sz[veceli_] = n; } else { sz[RowsKA()] = nr; sz[ColsKA()] = nc; } ReSize(2, sz); } SetSeq(es); cout << "TArray::ReadASCII()/Info: " << n << " elements read from stream " << " (Row,Col= " << nr << "," << nc << ")" << endl; return(n); } //! Writes the array content to the output stream, (in ASCII) /*! \param os : output stream (ASCII) \sa Print */ template void TArray::WriteASCII(ostream& os) const { Print(os, Size(), false, true); } /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// #ifdef __CXX_PRAGMA_TEMPLATES__ /* #pragma define_template TArray #pragma define_template TArray #pragma define_template TArray */ #pragma define_template TArray #pragma define_template TArray #pragma define_template TArray #pragma define_template TArray #pragma define_template TArray #pragma define_template TArray #pragma define_template TArray< complex > #pragma define_template TArray< complex > #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) namespace SOPHYA { /* template class TArray; template class TArray; template class TArray; */ template class TArray; template class TArray; template class TArray; template class TArray; template class TArray; template class TArray; template class TArray< complex >; template class TArray< complex >; } #endif