utilarr.h 11.2 KB
Newer Older
1 2 3 4 5 6 7
//-----------------------------------------------------------
// Classes Sequence,  RandomSequence, EnumeratedSequence ...
//      Utility classes for template numerical arrays
// SOPHYA class library - (C)  UPS+LAL IN2P3/CNRS  , CEA-Irfu 
// R. Ansari , C.Magneville       03/2000         
//-----------------------------------------------------------

8 9 10 11 12 13 14
//     Utility classes for template numerical arrays 
//                     R. Ansari, C.Magneville   03/2000

#ifndef UtilArray_SEEN
#define UtilArray_SEEN

#include "machdefs.h"
15
#include "mutyv.h"
16
#include "randinterf.h"
17

18
#include <stdlib.h>
19
#include <vector>
20 21 22 23 24

namespace SOPHYA {   

/* Quelques utilitaires pour les tableaux (Array) */             

ansari's avatar
ansari committed
25 26
/*! \ingroup TArray
  \typedef Arr_DoubleFunctionOfX
27
  \brief define a function of double which returns a double
ansari's avatar
ansari committed
28
*/
29
typedef double (* Arr_DoubleFunctionOfX) (double x);
ansari's avatar
ansari committed
30 31
/*! \ingroup TArray
  \typedef Arr_FloatFunctionOfX
32
  \brief define a function of float which returns a float
ansari's avatar
ansari committed
33
*/
34 35
typedef float  (* Arr_FloatFunctionOfX)  (float x);

36 37 38 39
/*! \ingroup TArray
  \typedef Arr_ComplexDoubleFunctionOfX
  \brief define a function of a complex<double> which returns a complex<double>
*/
40
typedef std::complex<double> (* Arr_ComplexDoubleFunctionOfX) (std::complex<double> x);
41 42 43 44
/*! \ingroup TArray
  \typedef Arr_ComplexFloatFunctionOfX
  \brief define a function of complex<float> which returns a complex<float>
*/
45
typedef float  (* Arr_ComplexFloatFunctionOfX)  (std::complex<float> x);
46

ansari's avatar
ansari committed
47
//////////////////////////////////////////////////////////
48
//! Class to generate a sequence of values
49 50 51
class Sequence {
public:
  virtual ~Sequence();
52 53
  virtual MuTyV & Value(sa_size_t k) const = 0;
  inline MuTyV & operator () (sa_size_t k) const { return(Value(k)) ; }
54 55 56
};

class RandomSequence : public Sequence {
57
public:
ansari's avatar
ansari committed
58 59 60 61 62 63
  //! to define the generator type
  enum {
    Gaussian = 0, //!< gaussian generator
    Flat = 1      //!< Flat generator
    };

64
  explicit RandomSequence(int typ = RandomSequence::Gaussian, double m=0., double s=1.);
65
  explicit RandomSequence(RandomGeneratorInterface& rgen, RNDTypes rtyp=C_RND_Gaussian, double mean=0., double sigma=1.);
66
  virtual  ~RandomSequence();
67
  virtual MuTyV & Value(sa_size_t k) const ;
68
  double   Next() const ;
69

70
protected:
71
  RNDTypes typ_;            //!< random generation type
ansari's avatar
ansari committed
72
  double mean_, sig_;  //!< generation parameters mean and sigma (if needed)
73
  mutable MuTyV retv_;
74
  mutable RandomGeneratorInterface* rgp_;
75 76 77
};


ansari's avatar
ansari committed
78 79
//////////////////////////////////////////////////////////
//! Class to generate a sequence of values
80
class RegularSequence : public Sequence {
81
public:
82 83
  explicit RegularSequence (double start=0., double step=1., Arr_DoubleFunctionOfX f=NULL);
  virtual  ~RegularSequence();
ansari's avatar
ansari committed
84 85

  //! return start value of the sequence
86
  inline double & Start() { return start_; }
ansari's avatar
ansari committed
87
  //! return step value of the sequence
88
  inline double & Step() { return step_; }
89

90
  virtual MuTyV & Value(sa_size_t k) const ;
91

92
protected:
ansari's avatar
ansari committed
93 94 95
  double start_;              //!< start value of the sequence
  double step_;               //!< step value of the sequence
  Arr_DoubleFunctionOfX myf_; //!< pointer to the sequence function
96 97 98
  mutable MuTyV retv_;
};

99 100 101
//////////////////////////////////////////////////////////
//! Class for creation and handling of an explicitly defined list of values

102 103
class EnumeratedSequence : public Sequence  {
public:
104
  explicit EnumeratedSequence();
105
           EnumeratedSequence(EnumeratedSequence const & es);
106
  virtual ~EnumeratedSequence();
107
  virtual MuTyV & Value(sa_size_t k) const ;
108 109 110

  inline sa_size_t Size() const { return vecv_.size(); }

111
  EnumeratedSequence & operator , (MuTyV const & v);
112
  EnumeratedSequence & operator = (MuTyV const & v);
113

114 115
  EnumeratedSequence & operator = (EnumeratedSequence const & es);

116
  inline  void         Clear()  { vecv_.clear(); }      
117
  void                 Print(std::ostream& os) const;
118

119
  sa_size_t            Append(EnumeratedSequence const & seq);
120 121
  sa_size_t            Append(std::string const & str, int & nbad, const char* sep=" \t");
  sa_size_t            FillFromFile(std::istream& is, sa_size_t& nr, sa_size_t& nc, 
122
				    char clm='#', const char* sep=" \t");
123

124
private:
125
  std::vector<MuTyV> vecv_;
126
  mutable MuTyV retv_;
127 128
};

129
//! prints/displays the enumerated sequence on the ostream \b os 
130
inline std::ostream& operator << (std::ostream& os, const EnumeratedSequence& a)
131
{ a.Print(os);    return(os);    }
132

133 134
  //inline EnumeratedSequence operator , (MuTyV const & a, MuTyV const & b)
  //{ EnumeratedSequence seq;   return ((seq,a),b) ; }
135

ansari's avatar
ansari committed
136 137
//////////////////////////////////////////////////////////
//! Class to define a range of indexes
138 139
class Range {
public:
140
  //! Index range containing a single index = \b start 
141 142 143 144 145 146 147
  Range(sa_size_t start);
  //! Index range start \<= index \<= end
  Range(sa_size_t start, sa_size_t end); 
  //! Index range start \<= index \<= end with increment step 
  Range(sa_size_t start, sa_size_t end, sa_size_t step);
  //! General Index range specification, using size or start/end and increment
  Range(sa_size_t start, sa_size_t end, sa_size_t size, sa_size_t step);
148 149
  //! Index range specified as a string, in the form start:end:step
  Range(std::string s);
150 151 152 153
  //! copy constructor 
  Range(Range const & a);
  //! copy (equal) operator
  Range& operator = (Range const & a);
154
  //! tests the equality between two Range object - return true if equal
155 156
  bool IsEqual(Range const & a) const;
  //! Return a reference to the start index
157
  inline sa_size_t & Start()  {  return start_; }
158
  //! Return a reference to the last index
159
  inline sa_size_t & End()    {  return end_; }
160
  //! Return a reference to the size
161
  inline sa_size_t & Size()   {  return size_; }
162
  //! Return a reference to the step
163
  inline sa_size_t & Step()   {  return step_; }
164 165 166 167 168 169 170 171
  //! Return the start index (const version) 
  inline sa_size_t Start()  const {  return start_; }
  //! Return the last index (const version) 
  inline sa_size_t End()  const   {  return end_; }
  //! Return the size  (const version) 
  inline sa_size_t Size() const   {  return size_; }
  //! Return the step  (const version) 
  inline sa_size_t Step() const   {  return step_; }
172 173
  //! prints/displays the Range object on the ostream \b os - No new line appended 
  std::ostream& Print(std::ostream& os) const;
174 175 176 177 178 179 180 181 182
  //! return a constant value defining the first element
  inline static sa_size_t firstIndex() { return 0; }
  //! return a constant value as a placeholder for the last valid index 
  inline static sa_size_t lastIndex() { return -1; }
  //! return a Range object specifing all indices, from first to last
  inline static Range all() 
  { return Range(Range::firstIndex() , Range::lastIndex()); }
  //! return a Range object specifing the first index
  inline static Range first()
183
  { return Range(Range::firstIndex() , Range::firstIndex(), 1, 1); }
184 185 186
  //! return a Range object specifing the last valid index
  inline static Range last()
  { return Range(Range::lastIndex() , Range::lastIndex(), 1, 1); }
187 188
  //! return a vector of ranges decoding the provided string as [rs1,rs2,...] with rs=start:end:step
  static std::vector<Range> str2vranges(std::string s);
189 190 191
  //! For internal TArray module use.
  void Update(sa_size_t osz);

192
protected:
193 194 195 196
  sa_size_t start_; //!< start index
  sa_size_t end_;   //!< end index
  sa_size_t size_;  //!< size
  sa_size_t step_;  //!< step
197 198
};

199
//! equality comparison operator between two ranges 
200 201 202
inline bool operator == (Range const& a1, Range const& a2)
{ return a1.IsEqual(a2); }
  
203
//! inequality comparison operator between two ranges 
204 205 206
inline bool operator != (Range const& a1, Range const& a2)
{ return !(a1.IsEqual(a2)); }  

207 208 209 210
//! prints/displays the Range objet  on the ostream \b os 
inline std::ostream& operator << (std::ostream& os, const Range& a)
{ a.Print(os);    return(os);    }
  
ansari's avatar
ansari committed
211 212
//////////////////////////////////////////////////////////
//! Class to define an identity matrix
213 214
class IdentityMatrix {
public:
215
  explicit IdentityMatrix(double diag=1., sa_size_t n=0);
ansari's avatar
ansari committed
216
  //! return the size of the identity matrix
217
  inline sa_size_t Size() { return size_; }
ansari's avatar
ansari committed
218
  //! return the value of the diagonal elements
219 220
  inline double Diag() { return diag_; }
protected:
221
  sa_size_t size_; //!< size of the matrix
ansari's avatar
ansari committed
222
  double diag_; //!< value of the diagonal elements
223 224
};

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
/*! 
  \class SOPHYA::Range_Array_Grp 
  \ingroup TArray
  \brief A utiliy class to gather an array and set of Range  specification 

  This class is a utility object returned by SOPHYA::RangeArrayGroup() functions,
  and specify the portion of a multi-dimensional data set.
*/
template <class T> class TArray;

template <class T>
class Range_Array_Grp  {
  public:
  explicit Range_Array_Grp() : arrp_(nullptr) { } 
  explicit Range_Array_Grp(TArray<T> & arr) : arrp_(&arr) { }
  TArray<T> * arrp_;
  std::vector<Range> vr_;
};


/*! 
  \fn SOPHYA::RangeArrayGroup
  \ingroup TArray
  \brief A utiliy function to ease creation of Range_Array_Grp from Ranges and an array 

  Note that the optional flag \b fgrevdim, reverses the order of Ranges put in the corresponding 
251
  vector in Range_Array_Grp<T> if set to true. 
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
  The default order (fgrevdim=false) correspond to the SOPHYA::TArray<T> convention. The first element 
  in the vector correspond to SizeX/OffsetX. 
*/

//! Creates a Range_Array_Grp<T> corresponding to a one-dimensional array 
template <class T>
inline Range_Array_Grp<T> RangeArrayGroup(Range const & r1, TArray<T> & arr) 
{
  Range_Array_Grp<T> sa(arr); sa.vr_.push_back(r1);  return sa;
}
//! Creates a Range_Array_Grp<T> corresponding to a two-dimensional array 
template <class T>
inline Range_Array_Grp<T> RangeArrayGroup(Range const & r1, Range const & r2, TArray<T> & arr, bool fgrevdim=false)
{
  Range_Array_Grp<T> sa(arr);
  if (fgrevdim)  {  sa.vr_.push_back(r1);  sa.vr_.push_back(r2); }
  else { sa.vr_.push_back(r2);  sa.vr_.push_back(r1); }
  return sa; 
}
//! Creates a Range_Array_Grp<T> corresponding to a three-dimensional array 
template <class T>
inline Range_Array_Grp<T> RangeArrayGroup(Range const & r1, Range const & r2, Range const & r3, 
					  TArray<T> & arr, bool fgrevdim=false)
{
  Range_Array_Grp<T> sa(arr);
  if (fgrevdim) { sa.vr_.push_back(r1); sa.vr_.push_back(r2); sa.vr_.push_back(r3);  }
  else { sa.vr_.push_back(r3); sa.vr_.push_back(r2);  sa.vr_.push_back(r1); }
  return sa; 
}
//! Creates a Range_Array_Grp<T> corresponding to a four-dimensional array 
template <class T>
inline Range_Array_Grp<T> RangeArrayGroup(Range const & r1, Range const & r2, Range const & r3, Range const & r4,
					  TArray<T> & arr, bool fgrevdim=false)
{
  Range_Array_Grp<T> sa(arr);
  if (fgrevdim) { sa.vr_.push_back(r1); sa.vr_.push_back(r2); sa.vr_.push_back(r3); sa.vr_.push_back(r4); }
  else { sa.vr_.push_back(r4); sa.vr_.push_back(r3); sa.vr_.push_back(r2);  sa.vr_.push_back(r1); }
  return sa; 
}
//! Creates a Range_Array_Grp<T> corresponding to a five-dimensional array 
template <class T>
inline Range_Array_Grp<T> RangeArrayGroup(Range const & r1, Range const & r2, Range const & r3, Range const & r4,
					  Range const & r5, TArray<T> & arr, bool fgrevdim=false)
{
  Range_Array_Grp<T> sa(arr);
  if (fgrevdim) { sa.vr_.push_back(r1); sa.vr_.push_back(r2); sa.vr_.push_back(r3); sa.vr_.push_back(r4); sa.vr_.push_back(r5); }
  else { sa.vr_.push_back(r5); sa.vr_.push_back(r4); sa.vr_.push_back(r3); sa.vr_.push_back(r2);  sa.vr_.push_back(r1); }
  return sa; 
}

302 303 304
} // Fin du namespace

#endif