// Utility classes for template numerical arrays // R. Ansari, C.Magneville 03/2000 #include "machdefs.h" #include "utilarr.h" #include "srandgen.h" // Classe utilitaires Sequence::~Sequence() { } ////////////////////////////////////////////////////////// /*! \class SOPHYA::RandomSequence \ingroup TArray Base class to generate a sequence of random values */ //! Constructor /*! \param typ : generator type \param m : mean parameter of the generator (if needed) \param s : sigma parameter of the generator (if needed) */ RandomSequence::RandomSequence(int typ, double m, double s) { typ_ = (typ == Flat) ? Flat : Gaussian; mean_ = m; sig_ = s; } RandomSequence::~RandomSequence() { } //! Return random sequence values. /*! \return If typ = Flat : return [-1,+1]*sig + mean \return If typ = Gaussian : return gaussian distributed with \b mean mean and sigma \b sig */ double RandomSequence::Rand() { if (typ_ == Flat) return(drandpm1()*sig_ + mean_); else return(GauRnd(mean_, sig_)); } MuTyV & RandomSequence::Value(sa_size_t k) const { if (typ_ == Flat) retv_ = drandpm1()*sig_ + mean_; else retv_ = GauRnd(mean_, sig_); return retv_; } ////////////////////////////////////////////////////////// /*! \class SOPHYA::RegularSequence \ingroup TArray Class to generate a sequence of values */ //! Constructor /*! \param start : start value \param step : step value \param f : pointer to the sequence function (default = NULL, f(x)=x ) See \ref RegularSequenceOperat "operator()" */ RegularSequence::RegularSequence(double start, double step, Arr_DoubleFunctionOfX f) { start_ = start; step_ = step; myf_ = f; } RegularSequence::~RegularSequence() { } //! Get the \b k th value /*! \param k : index of the value \anchor RegularSequenceOperat \return f(start+k*step) */ MuTyV & RegularSequence::Value (sa_size_t k) const { double x = start_+(double)k*step_; if (myf_) x = myf_(x); retv_ = x; return(retv_); } /*! \class SOPHYA::EnumeratedSequence \ingroup TArray Explicitly defined sequence of values. The comma operator has been redefined to let an easy definition of sequences. \code // Initializing a sequence EnumeratedSequence es; es = 11, 22, 33, 44, 55, 66; for(int k=0; k<8; k++) cout << " k= " << k << " es(k)= " << es(k) << endl; // Decoding a sequence from a string EnumeratedSequence ess; int nbad; ess.Append("56.5 (1.,-1.) 4 8 16", nbad); cout << ess; \endcode */ //! Default constructor EnumeratedSequence::EnumeratedSequence() { } //! Copy constructor EnumeratedSequence::EnumeratedSequence(EnumeratedSequence const & es) { Append(es); } EnumeratedSequence::~EnumeratedSequence() { } //! Return the k th value in the sequence (default = 0) MuTyV & EnumeratedSequence::Value (sa_size_t k) const { if (k >= vecv_.size()) retv_ = 0; else retv_ = vecv_[k]; return(retv_); } //! Appends a new value to the sequence EnumeratedSequence & EnumeratedSequence::operator , (MuTyV const & v) { vecv_.push_back(v); return(*this); } //! Initialize the sequence with a single value \b v EnumeratedSequence & EnumeratedSequence::operator = (MuTyV const & v) { vecv_.clear(); vecv_.push_back(v); return(*this); } //! Copy operator EnumeratedSequence & EnumeratedSequence::operator = (EnumeratedSequence const & seq) { Clear(); Append(seq); return(*this); } //! Prints the list to the output stream \b os void EnumeratedSequence::Print(ostream& os) const { os << " EnumeratedSequence::Print() - Size()= " << Size() << endl; for(int k=0; k 0) && (k%10 == 0)) os << endl; else os << " " ; } os << endl; return; } //! Append the \b seq to the end of the sequence. /*! \return the number of added elements. */ sa_size_t EnumeratedSequence::Append(EnumeratedSequence const & seq) { for(int k=0; k= l) break; if (str[p] == '\'') { // Decodage d'un string q = str.find('\'',p+1); if (q < l) { vecv_.push_back(MuTyV(str.substr(p+1,q-p-1))); n++; q++; } else nbad++; } else if (str[p] == '(') { // Decodage d'un complex q = str.find(')',p); if (q < l) { q++; MuTyV mtv(str.substr(p,q-p)); complex z = mtv.operator complex(); vecv_.push_back(MuTyV(z)); n++; } else nbad++; } else { q = str.find_first_of(" \t",p); if (!isdigit(str[p]) && !(str[p] == '+') && !(str[p] == '-') ) { // une chaine continue; } else { // C'est un nombre if (str.find('.',p) < q) { // c'est un flottant r_8 x = atof(str.substr(p,q-p).c_str()); vecv_.push_back(MuTyV(x)); } else { // un entier int_8 l = atol(str.substr(p,q-p).c_str()); vecv_.push_back(MuTyV(l)); } n++; } } } return (n); } //! Decodes the input ASCII stream, creating a sequence of values /*! \param is : Input ASCII stream \param nr : Number of non empty (or comment) lines in stream (return value) \param nc : Number of columns (= ntot/nlines) (return value) \return Number of decoded elements */ sa_size_t EnumeratedSequence::FillFromFile(istream& is, sa_size_t& nr, sa_size_t& nc) { nr = 0; nc = 0; sa_size_t n = 0; char buff[256]; string line; int nbad, nbadtot, nel; nbadtot = nbad = 0; while (!is.eof()) { is.clear(); is.getline(buff, 256); // cout << " DBG : buff=" << buff << " :state=" << is.rdstate() << endl; line += buff; if (is.good()) { nel = Append(line, nbad); // cout << " Decoding line = " << line << " Nel= " << nel << endl; if (nel > 0) { nr++; n += nel; } nbadtot += nbad; line = ""; } } if (line.length() > 0) { nel = Append(line, nbad); // cout << " Decoding Eline = " << line << " Nel= " << nel << endl; if (nel > 0) { nr++; n += nel; } nbadtot += nbad; line = ""; } if (nbadtot > 0) cout << "EnumeratedSequence::FillFromFile()/Warning " << nbadtot << " bad match (quotes or parenthesis) in stream " << endl; nc = n/nr; return (n); } ////////////////////////////////////////////////////////// /*! \class SOPHYA::Range \ingroup TArray Class to define a range of indexes */ //! Constructor /*! Define a range of indexes \param start : start index (inclusive) \param end : end index (inclusive) \param size : size (number of elements, used if end \<= start) \param step : step (or stride) \warning If \b end \> \b start, \b size is computed automatically \warning If not \b size is fixed and \b end recomputed */ Range::Range(sa_size_t start, sa_size_t end, sa_size_t size, sa_size_t step) { start_ = start; step_ = (step > 0) ? step : 1; if (end > start) { // Taille calcule automatiquement end_ = end; if (step_ > ((end_-start_)+1)) size_ = 1; else size_ = ((end-start)+1)/step_; } else { // Taille fixee size_ = size; end_ = start_+size_*step_; } } /* Range & Range::operator = (sa_size_t start) { start_ = start; size_ = 1; step_ = 1; return (*this); } */ ////////////////////////////////////////////////////////// /*! \class SOPHYA::IdentityMatrix \ingroup TArray Class to define an identity matrix */ //! Constructor of a (n,n) diagonal matrix with value diag on the diagonal IdentityMatrix::IdentityMatrix(double diag, sa_size_t n) { size_ = n; diag_ = diag; }