// template array class for numerical types // R. Ansari, C.Magneville 03/2000 #include "machdefs.h" #include #include #include "pexceptions.h" #include "tarray.h" // Variables statiques globales template char * TArray::ck_op_msg_[6] = {"???", "Size(int )", "IsPacked(int )", "Stride(int )", "ElemCheckBound()", "operator()" }; template uint_4 TArray::max_nprt_ = 50; // Methodes statiques globales template void TArray::SetMaxPrint(uint_4 nprt) { max_nprt_ = nprt; } template uint_8 TArray::ComputeTotalSize(uint_4 ndim, uint_4 * siz, uint_4 step, uint_8 offset) { uint_8 rs = step; for(int k=0; k TArray::TArray() : mNDBlock() , mInfo(NULL) // Default constructor { ndim_ = 0; for(int k=0; k TArray::TArray(uint_4 ndim, uint_4 * siz, uint_4 step) : mNDBlock(ComputeTotalSize(ndim, siz, step, 1)) , mInfo(NULL) { string exmsg = "TArray::TArray(uint_4, uint_4 *, uint_4)"; if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) ); } template TArray::TArray(uint_4 nx, uint_4 ny=1, uint_4 nz=1) : mNDBlock(nx*((ny>0)?ny:1)*((nz>0)?nz:1)) , mInfo(NULL) { uint_4 size[TARRAY_MAXNDIMS]; size[0] = nx; size[1] = ny; size[2] = nz; int ndim = 1; if ((size[1] > 0) && (size[2] > 0)) ndim = 3; else if (size[1] > 0) ndim = 2; else ndim = 1; string exmsg = "TArray::TArray(uint_4, uint_4, uint_4)"; if (!UpdateSizes(ndim, size, 1, 0, exmsg)) throw( ParmError(exmsg) ); } template TArray::TArray(uint_4 ndim, uint_4 * siz, NDataBlock & db, bool share, uint_4 step, uint_8 offset) : mNDBlock(db, share) , mInfo(NULL) { string exmsg = "TArray::TArray(uint_4, uint_4 *, NDataBlock & ... )"; if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) ); } template TArray::TArray(uint_4 ndim, uint_4 * siz, T* values, uint_4 step, uint_8 offset, Bridge* br) : mNDBlock(ComputeTotalSize(ndim, siz, step, 1), values, br) , mInfo(NULL) { string exmsg = "TArray::TArray(uint_4, uint_4 *, T* ... )"; if (!UpdateSizes(ndim, siz, step, offset, exmsg)) throw( ParmError(exmsg) ); } template TArray::TArray(const TArray& a) : mNDBlock(a.mNDBlock) , mInfo(NULL) { string exmsg = "TArray::TArray(const TArray&)"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } template TArray::TArray(const TArray& a, bool share) : mNDBlock(a.mNDBlock, share) , mInfo(NULL) { string exmsg = "TArray::TArray(const TArray&, bool)"; if (!UpdateSizes(a, exmsg)) throw( ParmError(exmsg) ); if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } // Destructeur template TArray::~TArray() { } template TArray& TArray::operator = (const TArray& a) { if (this != &a) { CloneOrShare(a); if (mInfo) delete mInfo; if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } return(*this); } 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; if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } template void TArray::ReSize(uint_4 ndim, uint_4 * siz, uint_4 step) { string exmsg = "TArray::ReSize()"; if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) ); mNDBlock.ReSize(totsize_); } template void TArray::Realloc(uint_4 ndim, uint_4 * siz, uint_4 step, bool force) { string exmsg = "TArray::Realloc()"; if (!UpdateSizes(ndim, siz, step, 0, exmsg)) throw( ParmError(exmsg) ); mNDBlock.ReSize(totsize_); } template bool TArray::CompareSizes(const TArray& a) { if (ndim_ != a.ndim_) return(false); for(int k=0; k TArray& TArray::CompactDim() { if (ndim_ < 2) return(*this); uint_4 ndim = 0; uint_4 size[TARRAY_MAXNDIMS]; uint_4 step[TARRAY_MAXNDIMS]; for(int k=0; k uint_4 TArray::MinStepKA() const { for(int ka=0; ka uint_4 TArray::MaxSizeKA() const { uint_4 ka = 0; uint_4 mx = size_[0]; for(int k=0; k mx) { ka = k; mx = size_[k]; } return(ka); } // Acces lineaire aux elements .... Calcul d'offset template uint_8 TArray::Offset(uint_8 ip) const { if (ip == 0) return(offset_); uint_4 idx[TARRAY_MAXNDIMS]; int k; uint_8 rest = ip; for(k=0; k TArray TArray::operator () (Range rx, Range ry, Range rz, Range rt, Range ru) { uint_4 ndim = 0; uint_4 size[TARRAY_MAXNDIMS]; uint_4 step[TARRAY_MAXNDIMS]; uint_4 pos[TARRAY_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; SubArray(ra, ndim, size, pos, step); ra.SetTemp(true); return(ra); } // ...... Operation de calcul sur les tableaux ...... // ------- Attention -------- // Boucles normales prenant en compte les steps .... // Possibilite de // , vectorisation template TArray& TArray::operator = (Sequence seq) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); pe = Data(); for(k=0; k>>> Operations avec 2nd membre de type scalaire template TArray& TArray::operator = (T x) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); for(k=0; k TArray& TArray::operator += (T x) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); for(k=0; k TArray& TArray::operator -= (T x) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); for(k=0; k TArray& TArray::operator *= (T x) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); for(k=0; k TArray& TArray::operator /= (T x) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); for(k=0; k>>> Operations avec 2nd membre de type tableau template TArray& TArray::operator += (const TArray& a) { if (!CompareSizes(a)) throw(SzMismatchError("TArray::operator += (const TArray&)")) ; T * pe; const T * pea; uint_8 j,k,ka; if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 stepa = a.AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); pea = a.Data(); for(k=0, ka=0; k TArray& TArray::operator -= (const TArray& a) { if (!CompareSizes(a)) throw(SzMismatchError("TArray::operator -= (const TArray&)")) ; T * pe; const T * pea; uint_8 j,k,ka; if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 stepa = a.AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); pea = a.Data(); for(k=0, ka=0; k TArray& TArray::MultElt(const TArray& a) { if (!CompareSizes(a)) throw(SzMismatchError("TArray::MultElt(const TArray&)")) ; T * pe; const T * pea; uint_8 j,k,ka; if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 stepa = a.AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); pea = a.Data(); for(k=0, ka=0; k TArray& TArray::DivElt(const TArray& a) { if (!CompareSizes(a)) throw(SzMismatchError("TArray::DivElt(const TArray&)")) ; T * pe; const T * pea; uint_8 j,k,ka; if ((AvgStep() > 0) && (a.AvgStep() > 0) ) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 stepa = a.AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); pea = a.Data(); for(k=0, ka=0; k TArray& TArray::ApplyFunction(Arr_DoubleFunctionOfX f) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); for(k=0; k TArray& TArray::ApplyFunction(Arr_FloatFunctionOfX f) { T * pe; uint_8 j,k; if (AvgStep() > 0) { // regularly spaced elements uint_8 step = AvgStep(); uint_8 maxx = totsize_*step; pe = Data(); for(k=0; k >& TArray< complex >::ApplyFunction(Arr_DoubleFunctionOfX f) { throw( NotAvailableOperation("TArray< complex >::ApplyFunction() - Unsupported operation ") ); } TArray< complex >& TArray< complex >::ApplyFunction(Arr_FloatFunctionOfX f) { throw(NotAvailableOperation( "TArray< complex >::ApplyFunction() - Unsupported operation ") ); } TArray< complex >& TArray< complex >::ApplyFunction(Arr_DoubleFunctionOfX f) { throw(NotAvailableOperation("TArray< complex >::ApplyFunction() - Unsupported operation ") ); } TArray< complex >& TArray< complex >::ApplyFunction(Arr_FloatFunctionOfX f) { throw(NotAvailableOperation("TArray< complex >::ApplyFunction() - Unsupported operation ") ); } // ---------------------------------------------------- // Impression, etc ... // ---------------------------------------------------- template void TArray::Show(ostream& os, bool si) const { os << " TArray< " << typeid(T).name() << " NDim= " << ndim_ << "(" << typeid(*this).name() << " )" << endl; os << "TotSize=" << totsize_ << " Size(X*Y*...)= " ; for(int k=0; k void TArray::Print(ostream& os, int_4 maxprt, bool si) const { if (maxprt < 0) maxprt = max_nprt_; uint_4 npr = 0; Show(os, si); int k0,k1,k2,k3,k4; for(k4=0; k4 1) cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl; for(k3=0; k3 1) cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl; for(k2=0; k2 1) cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl; for(k1=0; k1 1) && (size_[0] > 10) ) cout << "----- Dimension 2 (Y) K1= " << k1 << endl; for(k0=0; k0 0) os << ", "; os << Elem(k0, k1, k2, k3, k4); npr++; if (npr >= maxprt) { if (npr < totsize_) os << "\n .... " << endl; return; } } os << endl; } } } } os << "\n" << endl; } template DVList& TArray::Info() { if (mInfo == NULL) mInfo = new DVList; return(*mInfo); } template bool TArray::UpdateSizes(uint_4 ndim, const uint_4 * siz, uint_4 step, uint_8 offset, string & exmsg) { if (ndim >= TARRAY_MAXNDIMS) { exmsg += " NDim Error"; return false; } if (step < 1) { exmsg += " Step(=0) Error"; return false; } minstep_ = moystep_ = step; // Flagging bad updates ... ndim_ = 0; totsize_ = 1; int k; for(k=0; k bool TArray::UpdateSizes(uint_4 ndim, const uint_4 * siz, const uint_4 * step, uint_8 offset, string & exmsg) { if (ndim >= TARRAY_MAXNDIMS) { exmsg += " NDim Error"; return false; } // Flagging bad updates ... ndim_ = 0; totsize_ = 1; int k; for(k=0; k bool TArray::UpdateSizes(const TArray& a, string & exmsg) { if (a.ndim_ >= TARRAY_MAXNDIMS) { exmsg += " NDim Error"; return false; } // Flagging bad updates ... ndim_ = 0; totsize_ = 1; int k; for(k=0; k void TArray::CloneOrShare(const TArray& a) { string exmsg = "TArray::CloneOrShare()"; if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) ); mNDBlock.CloneOrShare(a.mNDBlock); } template void TArray::Share(const TArray& a) { string exmsg = "TArray::Share()"; if (!UpdateSizes(a.ndim_, a.size_, a.step_, a.offset_, exmsg)) throw( ParmError(exmsg) ); mNDBlock.Share(a.mNDBlock); } template void TArray::SubArray(TArray & ra, uint_4 ndim, uint_4 * siz, uint_4 * pos, uint_4 * step) { if ( (ndim > ndim_) || (ndim < 1) ) throw(SzMismatchError("TArray::SubArray( ... ) NDim Error") ); int k; for(k=0; k size_[k] ) throw(SzMismatchError("TArray::SubArray( ... ) Size/Pos Error") ); (ra.mNDBlock).Share(mNDBlock); uint_8 offset = offset_; for(k=0; k #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) 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