All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
uniform_grid.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2011-2014, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 #ifndef O2SCL_UNIFORM_GRID_H
24 #define O2SCL_UNIFORM_GRID_H
25 
26 /** \file uniform_grid.h
27  \brief File defining \ref o2scl::uniform_grid and its children
28 */
29 #include <iostream>
30 
31 #include <boost/numeric/ublas/vector.hpp>
32 
33 #include <o2scl/err_hnd.h>
34 #include <o2scl/string_conv.h>
35 
36 // Forward definition of the uniform_grid class for HDF I/O
37 namespace o2scl {
38  template<class data_t> class uniform_grid;
39 }
40 
41 // Forward definition of HDF I/O to extend friendship
42 namespace o2scl_hdf {
43  class hdf_file;
44  void hdf_input(hdf_file &hf, o2scl::uniform_grid<double> &t,
45  std::string name);
46  void hdf_output(hdf_file &hf, o2scl::uniform_grid<double> &t,
47  std::string name);
48 }
49 
50 #ifndef DOXYGEN_NO_O2NS
51 namespace o2scl {
52 #endif
53 
54 #ifdef O2SCL_NEVER_DEFINED
55  // Forward definition of the uniform_grid class for HDF I/O
56  namespace o2scl {
57  template<class data_t> class uniform_grid;
58  }
59 
60  // Forward definition of HDF I/O to extend friendship
61  namespace o2scl_hdf {
62  class hdf_file;
63  void hdf_input(hdf_file &hf, o2scl::uniform_grid<double> &t,
64  std::string name);
65  void hdf_output(hdf_file &hf, o2scl::uniform_grid<double> &t,
66  std::string name);
67  }
68 #endif
69 
70  /** \brief A class representing a uniform linear or logarithmic grid
71 
72  \note This class has no public constructors and is to be
73  instantiated through its children.
74 
75  This class should work for any floating-point type
76  compatible with std::pow() .
77 
78  Empty grids are those for which g_n_bins is zero.
79 
80  The first and last bin are always exactly equal to the
81  originally specified values of "start" and "end", but
82  finite-precision errors may affect the inner grid points.
83 
84  \future Implement operator==, etc?
85 
86  \comment
87  \future Add type() classes?
88 
89  Actually type() classes may not be so useful cons
90  \comment
91  */
92  template<class data_t=double> class uniform_grid {
93 
94  public:
95 
96  friend void o2scl_hdf::hdf_output
97  (o2scl_hdf::hdf_file &hf, uniform_grid<double> &ug, std::string name);
98 
99  friend void o2scl_hdf::hdf_input
100  (o2scl_hdf::hdf_file &hf, uniform_grid<double> &ug, std::string name);
101 
102  protected:
103 
104  /// The low-side of the first bin
105  data_t g_start;
106  /// The high-side of the last bin
107  data_t g_end;
108  /** \brief The width of each bin
109 
110  This should be always positive and non-zero for linear grids
111  and always greater than 1 for logarithmic grids.
112  */
113  data_t g_width;
114  /// The number of bins
115  size_t g_n_bins;
116  /// If true, use a logarithmic scale
117  bool g_log;
118 
119  /** \brief Construct a grid with specified values
120 
121  \note This function is not public because it might create
122  grids that are non-sensical. We require users to create grid
123  objects using one of the children which don't allow
124  non-sensical grids.
125  */
126  uniform_grid(data_t start, data_t end, data_t width, size_t n_bins,
127  bool log=false) {
128  if (n_bins==0) {
129  O2SCL_ERR2("Requested zero bins in ",
130  "uniform_grid::uniform_grid().",exc_einval);
131  }
132  if (start==end) {
133  // This helps ensure (but no guarantee) so that one can
134  // use vector_bsearch() for a uniform_grid object.
135  O2SCL_ERR2("Requested grid with start==end in ",
136  "uniform_grid::uniform_grid().",exc_einval);
137  }
138  if (log) {
139  if (width<=1.0) {
140  O2SCL_ERR2("Requested width <=1 for logrithmic grid in ",
141  "uniform_grid::uniform_grid().",exc_einval);
142  }
143  } else {
144  if (width<=0.0) {
145  O2SCL_ERR2("Requested negative or zero width for linear grid in ",
146  "uniform_grid::uniform_grid().",exc_einval);
147  }
148  }
149  g_start=start;
150  g_end=end;
151  g_width=width;
152  g_n_bins=n_bins;
153  g_log=log;
154  }
155 
156  public:
157 
158  /// Default constructor
160  g_n_bins=0;
161  g_start=0.0;
162  g_end=0.0;
163  g_width=0.0;
164  g_log=false;
165  }
166 
167  /** \brief Get the number of bins (regions in between grid points)
168 
169  This function returns zero if the grid is "empty".
170  */
171  size_t get_nbins() const {
172  return g_n_bins;
173  }
174 
175  /** \brief Get the number of points in the grid (always get_nbins()+1)
176 
177  This function will throw an exception if the grid is empty.
178  */
179  size_t get_npoints() const {
180  if (g_n_bins==0) {
181  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
182  exc_einval);
183  }
184  return g_n_bins+1;
185  }
186 
187  /** \brief Return true if the grid is logarithmic
188 
189  This function will throw an exception if the grid is empty.
190  */
191  bool is_log() const {
192  if (g_n_bins==0) {
193  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
194  exc_einval);
195  }
196  return g_log;
197  }
198 
199  /** \brief Fill a vector with the specified grid
200 
201  If the vector is not big enough to hold the grid, it is
202  automatically resized.
203 
204  This function will throw an exception if the grid is empty.
205  */
206  template<class resize_vec_t> void vector(resize_vec_t &v) const {
207 
208  if (g_n_bins==0) {
209  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
210  exc_einval);
211  }
212 
213  if (v.size()<g_n_bins+1) {
214  v.resize(g_n_bins+1);
215  }
216 
217  for(size_t i=0;i<g_n_bins+1;i++) {
218  v[i]=(*this)[i];
219  }
220 
221  return;
222  }
223 
224  /** \brief Get the grid point with index \c i
225  (\f$ i \in [0,\mathrm{n_{bins}}] \f$)
226  */
227  const data_t operator[](size_t i) const {
228 
229  if (g_n_bins==0) {
230  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
231  exc_einval);
232  }
233 
234 #if !O2SCL_NO_RANGE_CHECK
235  if (i>g_n_bins) {
236  std::string str=((std::string)"Index ")+o2scl::szttos(i)+
237  " out of range "+o2scl::szttos(g_n_bins)+
238  " in uniform_grid::operator[].";
239  O2SCL_ERR(str.c_str(),exc_eindex);
240  }
241 #endif
242 
243  // Linear case
244  if (!g_log) {
245  if (g_start<g_end) {
246  // Increasing
247  if (i==0) return g_start;
248  else if (i==g_n_bins) return g_end;
249  return g_start+i*g_width;
250  } else {
251  // Decreasing
252  if (i==0) return g_start;
253  else if (i==g_n_bins) return g_end;
254  return g_start-i*g_width;
255  }
256  }
257 
258  // Logarithmic case
259  if (g_start<g_end) {
260  // Increasing
261  if (i==0) return g_start;
262  else if (i==g_n_bins) return g_end;
263  return g_start*std::pow(g_width,((data_t)i));
264  }
265  // Decreasing
266  if (i==0) return g_start;
267  else if (i==g_n_bins) return g_end;
268  return g_start/std::pow(g_width,((data_t)i));
269  }
270 
271  /// Copy constructor
273  g_n_bins=ug.g_n_bins;
274  if (ug.g_n_bins>0) {
275  g_start=ug.g_start;
276  g_end=ug.g_end;
277  g_width=ug.g_width;
278  g_log=ug.g_log;
279  } else {
280  g_start=0.0;
281  g_end=0.0;
282  g_width=0.0;
283  g_log=false;
284  }
285  }
286 
287  /// Copy from = operator
289  g_n_bins=ug.g_n_bins;
290  if (ug.g_n_bins>0) {
291  g_start=ug.g_start;
292  g_end=ug.g_end;
293  g_width=ug.g_width;
294  g_log=ug.g_log;
295  } else {
296  g_start=0.0;
297  g_end=0.0;
298  g_width=0.0;
299  g_log=false;
300  }
301  return *this;
302  }
303 
304  };
305 
306  /** \brief Linear grid with fixed number of bins and fixed endpoint
307  */
308  template<class data_t=double> class uniform_grid_end :
309  public uniform_grid<data_t> {
310  public:
311 
312  /** \brief Create a grid with \c n_bins bins starting at
313  \c start and \c end
314 
315  The value of \c n_bins must be larger than zero and
316  \c start must not be the same as \c end.
317  */
318  uniform_grid_end(data_t start, data_t end, size_t n_bins) :
319  uniform_grid<data_t>(start,end,(end-start)/((data_t)n_bins),
320  n_bins,false) {
321  }
322  };
323 
324  /** \brief Linear grid with fixed number of bins and fixed bin size
325  */
326  template<class data_t=double> class uniform_grid_width :
327  public uniform_grid<data_t> {
328  public:
329 
330  /** \brief Create a grid with \c n_bins bins starting at
331  \c start with size \c width
332 
333  The value of \c n_bins must be larger than zero and
334  \c width must not be zero.
335  */
336  uniform_grid_width(data_t start, data_t width, size_t n_bins) :
337  uniform_grid<data_t>(start,start+n_bins*width,width,n_bins,false) {
338  }
339  };
340 
341  /** \brief Linear grid with fixed endpoint and fixed bin size
342  */
343  template<class data_t=double> class uniform_grid_end_width :
344  public uniform_grid<data_t> {
345  public:
346 
347  /** \brief Create a grid with bins of size \c width starting
348  at \c start and ending at \c end
349 
350  The value of \c n_bins must be larger than zero and
351  \c start must not be the same as \c end.
352  */
353  uniform_grid_end_width(data_t start, data_t end, data_t width) :
354  uniform_grid<data_t>(start,end,width,
355  ((size_t)((end-start)/width)),false) {
356  }
357  };
358 
359  /** \brief Logarithmic grid with fixed number of bins and fixed endpoint
360  */
361  template<class data_t=double> class uniform_grid_log_end :
362  public uniform_grid<data_t> {
363  public:
364 
365  /** \brief Create a logarithmic grid with \c n_bins bins starting at
366  \c start and \c end
367 
368  The value of \c n_bins must be larger than zero and
369  \c start must not be the same as \c end.
370  */
371  uniform_grid_log_end(data_t start, data_t end, size_t n_bins) :
372  uniform_grid<data_t>(start,end,std::pow(end/start,1.0/((data_t)n_bins)),
373  n_bins,true) {
374  }
375  };
376 
377  /** \brief Logarithmic grid with fixed number of bins and fixed bin size
378  */
379  template<class data_t=double> class uniform_grid_log_width :
380  public uniform_grid<data_t> {
381  public:
382 
383  /** \brief Create a logarithmic grid with \c n_bins bins starting at
384  \c start with size \c width
385 
386  The value of \c n_bins must be larger than zero and
387  \c width must be greater than 1.
388  */
389  uniform_grid_log_width(data_t start, data_t width, size_t n_bins) :
390  uniform_grid<data_t>(start,start*std::pow(width,n_bins),
391  width,n_bins,true) {
392  }
393  };
394 
395  /** \brief Logarithmic grid with fixed endpoint and fixed bin size
396  */
397  template<class data_t=double> class uniform_grid_log_end_width :
398  public uniform_grid<data_t> {
399  public:
400 
401  /** \brief Create a logarithmic grid with bins of size \c width starting
402  at \c start and ending at \c end
403 
404  The value of \c n_bins must be larger than zero and
405  \c start must not be the same as \c end.
406  */
407  uniform_grid_log_end_width(data_t start, data_t end, data_t width) :
408  uniform_grid<data_t>(start,end,width,
409  ((size_t)(log(end/start)/log(width))),true) {
410  }
411  };
412 
413 #ifndef DOXYGEN_NO_O2NS
414 }
415 #endif
416 
417 #endif
uniform_grid_log_width(data_t start, data_t width, size_t n_bins)
Create a logarithmic grid with n_bins bins starting at start with size width.
Definition: uniform_grid.h:389
uniform_grid & operator=(const uniform_grid &ug)
Copy from = operator.
Definition: uniform_grid.h:288
void hdf_output(hdf_file &hf, std::vector< o2scl::edge_crossings > &ec, std::string name)
Output a vector of o2scl::edge_crossings objects to a hdf_file.
uniform_grid_width(data_t start, data_t width, size_t n_bins)
Create a grid with n_bins bins starting at start with size width.
Definition: uniform_grid.h:336
Linear grid with fixed endpoint and fixed bin size.
Definition: uniform_grid.h:343
data_t g_width
The width of each bin.
Definition: uniform_grid.h:113
uniform_grid_log_end(data_t start, data_t end, size_t n_bins)
Create a logarithmic grid with n_bins bins starting at start and end.
Definition: uniform_grid.h:371
bool g_log
If true, use a logarithmic scale.
Definition: uniform_grid.h:117
uniform_grid(const uniform_grid &ug)
Copy constructor.
Definition: uniform_grid.h:272
Linear grid with fixed number of bins and fixed bin size.
Definition: uniform_grid.h:326
bool is_log() const
Return true if the grid is logarithmic.
Definition: uniform_grid.h:191
invalid argument supplied by user
Definition: err_hnd.h:59
Logarithmic grid with fixed endpoint and fixed bin size.
Definition: uniform_grid.h:397
size_t get_nbins() const
Get the number of bins (regions in between grid points)
Definition: uniform_grid.h:171
uniform_grid_end(data_t start, data_t end, size_t n_bins)
Create a grid with n_bins bins starting at start and end.
Definition: uniform_grid.h:318
uniform_grid()
Default constructor.
Definition: uniform_grid.h:159
uniform_grid(data_t start, data_t end, data_t width, size_t n_bins, bool log=false)
Construct a grid with specified values.
Definition: uniform_grid.h:126
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
size_t g_n_bins
The number of bins.
Definition: uniform_grid.h:115
Logarithmic grid with fixed number of bins and fixed bin size.
Definition: uniform_grid.h:379
data_t g_end
The high-side of the last bin.
Definition: uniform_grid.h:107
void vector(resize_vec_t &v) const
Fill a vector with the specified grid.
Definition: uniform_grid.h:206
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
data_t g_start
The low-side of the first bin.
Definition: uniform_grid.h:105
void hdf_output(hdf_file &hf, o2scl::uniform_grid< double > &t, std::string name)
Output a o2scl::uniform_grid object to a hdf_file.
uniform_grid_end_width(data_t start, data_t end, data_t width)
Create a grid with bins of size width starting at start and ending at end.
Definition: uniform_grid.h:353
A class representing a uniform linear or logarithmic grid.
Definition: uniform_grid.h:38
uniform_grid_log_end_width(data_t start, data_t end, data_t width)
Create a logarithmic grid with bins of size width starting at start and ending at end...
Definition: uniform_grid.h:407
Store data in an O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl...
Definition: hdf_file.h:93
Logarithmic grid with fixed number of bins and fixed endpoint.
Definition: uniform_grid.h:361
Invalid index for array or matrix.
Definition: err_hnd.h:123
std::string szttos(size_t x)
Convert a size_t to a string.
void hdf_input(hdf_file &hf, o2scl::uniform_grid< double > &t, std::string name)
Input a o2scl::uniform_grid object from a hdf_file.
void hdf_input(hdf_file &hf, o2scl::table< vec_t > &t, std::string name)
Input a o2scl::table object from a hdf_file.
Definition: hdf_io.h:55
const data_t operator[](size_t i) const
Get the grid point with index i ( )
Definition: uniform_grid.h:227
Linear grid with fixed number of bins and fixed endpoint.
Definition: uniform_grid.h:308
size_t get_npoints() const
Get the number of points in the grid (always get_nbins()+1)
Definition: uniform_grid.h:179

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..