// Base class for numerical arrays // R. Ansari, C.Magneville 03/2000 #include "machdefs.h" #include #include #include "pexceptions.h" #include "basarr.h" /*! \class SOPHYA::BaseArray \ingroup TArray Base class for template arrays No data are connected to this class. Define base methods, enum and defaults for TArray , TMatrix and TVector. */ // Variables statiques globales char * BaseArray::ck_op_msg_[6] = {"???", "Size(int )", "IsPacked(int )" ,"Stride(int )", "ElemCheckBound()", "operator()" }; int_4 BaseArray::max_nprt_ = 50; int_4 BaseArray::prt_lev_ = 0; short BaseArray::default_memory_mapping = CMemoryMapping; short BaseArray::default_vector_type = ColumnVector; sa_size_t BaseArray::openmp_size_threshold = 200000; // ------ Methodes statiques globales -------- //! Set maximum number of printed elements and print level /*! \param nprt : maximum number of print \param lev : print level */ void BaseArray::SetMaxPrint(int_4 nprt, int_4 lev) { max_nprt_ = nprt; prt_lev_ = (lev < 3) ? lev : 3; } //! Set Size threshold for parallel routine call /*! \param thr : thresold value */ void BaseArray::SetOpenMPSizeThreshold(sa_size_t thr) { openmp_size_threshold = thr; } //! Compute totale size /*! \param ndim : number of dimensions \param siz : array of size along the \b ndim dimensions \param step[ndim] : step value \param offset : offset value \return Total size of the array */ sa_size_t BaseArray::ComputeTotalSize(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset) { sa_size_t rs = step; for(sa_size_t k=0; k row-major array \endverbatim \return default memory mapping value */ short BaseArray::SetDefaultMemoryMapping(short mm) { default_memory_mapping = (mm != CMemoryMapping) ? FortranMemoryMapping : CMemoryMapping; return default_memory_mapping; } //! Set Default Vector Type /*! \param vt : vector type (ColumnVector,RowVector) \return default vector type value */ short BaseArray::SetDefaultVectorType(short vt) { default_vector_type = (vt != ColumnVector) ? RowVector : ColumnVector ; return default_vector_type; } //! Select Memory Mapping /*! Do essentially nothing. \param mm : type of Memory Mapping (CMemoryMapping,FortranMemoryMapping) \return return \b mm if it makes sense or default memory mapping value \sa SetDefaultMemoryMapping */ short BaseArray::SelectMemoryMapping(short mm) { if ( (mm == CMemoryMapping) || (mm == FortranMemoryMapping) ) return (mm) ; else return (default_memory_mapping); } //! Select Vector type /*! Do essentially nothing. \param vt : vector type (ColumnVector,RowVector) \return return \b vt if it makes sense or default vector type \sa SetDefaultVectorType */ short BaseArray::SelectVectorType(short vt) { if ((vt == ColumnVector) || (vt == RowVector)) return(vt); else return(default_vector_type); } //! Update Memory Mapping /*! Update variables marowi_ macoli_ veceli_ \param mm : type of Memory Mapping (CMemoryMapping,FortranMemoryMapping) \sa SetDefaultMemoryMapping */ void BaseArray::UpdateMemoryMapping(short mm) { short vt = default_vector_type; if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) mm = default_memory_mapping; if (mm == CMemoryMapping) { marowi_ = 1; macoli_ = 0; } else { marowi_ = 0; macoli_ = 1; } if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) { // Choix automatique Vecteur ligne ou colonne if ( size_[macoli_] == 1) veceli_ = marowi_; else veceli_ = macoli_; } else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_; } //! Update Memory Mapping /*! \param a : Array to be compared with \param mm : type of Memory Mapping or memory mapping transfert (SameMemoryMapping,AutoMemoryMapping,CMemoryMapping,FortranMemoryMapping) \sa SetDefaultMemoryMapping */ void BaseArray::UpdateMemoryMapping(BaseArray const & a, short mm) { short vt = default_vector_type; if (mm == SameMemoryMapping) { mm = ((a.marowi_ == 1) ? CMemoryMapping : FortranMemoryMapping); vt = (a.marowi_ == a.veceli_) ? ColumnVector : RowVector; } else if (mm == AutoMemoryMapping) mm = default_memory_mapping; if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) mm = default_memory_mapping; if (mm == CMemoryMapping) { marowi_ = 1; macoli_ = 0; } else { marowi_ = 0; macoli_ = 1; } if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) { // Choix automatique Vecteur ligne ou colonne if ( size_[macoli_] == 1) veceli_ = marowi_; else veceli_ = marowi_; } else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_; } //! Set Memory Mapping type /*! Compute values for variables marowi_ macoli_ veceli_ \param mm : Memory Mapping type (SameMemoryMapping,AutoMemoryMapping ,CMemoryMapping,FortranMemoryMapping) \sa SetDefaultMemoryMapping */ void BaseArray::SetMemoryMapping(short mm) { if (mm == SameMemoryMapping) return; if (mm == AutoMemoryMapping) mm = default_memory_mapping; if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) return; short vt = (marowi_ == veceli_) ? ColumnVector : RowVector; if (mm == CMemoryMapping) { marowi_ = 1; macoli_ = 0; } else { marowi_ = 0; macoli_ = 1; } if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) { // Choix automatique Vecteur ligne ou colonne if ( size_[macoli_] == 1) veceli_ = marowi_; else veceli_ = macoli_; } else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_; } //! Set Vector Type /*! Compute values for variable veceli_ \param vt : vector type () \sa SetDefaultVectorType */ void BaseArray::SetVectorType(short vt) { if (vt == SameVectorType) return; if (vt == AutoVectorType) vt = default_vector_type; if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) { // Choix automatique Vecteur ligne ou colonne if ( size_[macoli_] == 1) veceli_ = marowi_; else veceli_ = macoli_; } else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_; } // ------------------------------------------------------- // Methodes de la classe // ------------------------------------------------------- //! Default constructor BaseArray::BaseArray() : mInfo(NULL) { ndim_ = 0; for(int_4 k=0; k (Size(k) == a.Size(k), k=0,...NbDimensions()), disregard of the memory organisation and the row and column index. The flag \c smo is returned true in this case. */ bool BaseArray::CompareSizes(const BaseArray& a, bool& smo) { if (ndim_ != a.ndim_) return(false); if (arrtype_ == 0) { // Simple TArray, not a matrix smo = true; for(int_4 k=0; k 2) for(int_4 k=2; k 1) ndim=k; } if (ndim == 0) ndim = 1; string exmsg = "BaseArray::CompactTrailingDim() "; if (!UpdateSizes(ndim, size, step, offset_, exmsg)) throw( ParmError(exmsg) ); return; } //! return minimum value for step[ndim] int_4 BaseArray::MinStepKA() const { for(int_4 ka=0; ka mx) { ka = k; mx = size_[k]; } return(ka); } // Acces lineaire aux elements .... Calcul d'offset // -------------------------------------------------- // Position de l'element 0 du vecteur i selon l'axe ka // -------------------------------------------------- //! return position of first element for vector \b i alond \b ka th axe. sa_size_t BaseArray::Offset(int_4 ka, sa_size_t i) const { if ( (ndim_ < 1) || (i == 0) ) return(offset_); //#ifdef SO_BOUNDCHECKING if (ka >= ndim_) throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Axe KA Error"); if ( i*size_[ka] >= totsize_ ) throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Index Error"); //#endif sa_size_t idx[BASEARRAY_MAXNDIMS]; int_4 k; sa_size_t rest = i; idx[ka] = 0; for(k=0; k= totsize_) throw RangeCheckError("BaseArray::Offset(sa_size_t ip) Out of range index ip"); //#endif sa_size_t idx[BASEARRAY_MAXNDIMS]; int_4 k; sa_size_t rest = ip; for(k=0; k= Size(ColsKA()) ) { ax = RowsKA(); axa = a.RowsKA(); } else { ax = ColsKA(); axa = a.ColsKA(); } } step = Step(ax); stepa = a.Step(axa); gpas = Size(ax)*step; naxa = Size()/Size(ax); return; } // ---------------------------------------------------- // Impression, etc ... // ---------------------------------------------------- //! Show infos on stream \b os (\b si to display DvList) void BaseArray::Show(ostream& os, bool si) const { if (ndim_ < 1) { os << "\n--- " << BaseArray::InfoString() << " Unallocated Array ! " << endl; return; } os << "\n--- " << InfoString() ; os << " ND=" << ndim_ << " SizeX*Y*...= " ; for(int_4 k=0; k 0) { os << " TotSize= " << totsize_ << " Step(X Y ...)=" ; for(int_4 k=0; k= BASEARRAY_MAXNDIMS) { exmsg += " NDim Error"; return false; } // Flagging bad updates ... ndim_ = 0; totsize_ = 1; int_4 k; for(k=0; k= BASEARRAY_MAXNDIMS) { exmsg += " NDim Error"; return false; } // Flagging bad updates ... ndim_ = 0; totsize_ = 1; int_4 k; for(k=0; k ndim_) || (ndim < 1) ) throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) NDim Error") ); int_4 k; for(k=0; k size_[k] ) throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) Size/Pos Error") ); sa_size_t offset = offset_; for(k=0; k