uniform_grid.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2011-2018, 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 (start>0.0) {
140  if ((width<1.0 && start<end) ||
141  (width>1.0 && start>end)) {
142  O2SCL_ERR2("Incommensurate logarithmic grid in ",
143  "uniform_grid::uniform_grid().",exc_einval);
144  }
145  } else if (start<0.0) {
146  if ((width<1.0 && start>end) ||
147  (width>1.0 && start<end)) {
148  O2SCL_ERR2("Incommensurate logarithmic grid in ",
149  "uniform_grid::uniform_grid().",exc_einval);
150  }
151  } else if (start==0.0 || end==0.0) {
152  O2SCL_ERR2("Requested logarithmic grid with either ",
153  "start or end=0 in uniform_grid::uniform_grid().",
154  exc_einval);
155  }
156  if (width==1.0) {
157  O2SCL_ERR2("Requested width 1 for logrithmic grid in ",
158  "uniform_grid::uniform_grid().",exc_einval);
159  }
160  } else {
161  if ((width<0.0 && start<end) ||
162  (width>0.0 && start>end)) {
163  O2SCL_ERR2("Incommensurate linear grid in ",
164  "uniform_grid::uniform_grid().",exc_einval);
165  }
166  if (width==0.0) {
167  O2SCL_ERR2("Requested zero width for linear grid in ",
168  "uniform_grid::uniform_grid().",exc_einval);
169  }
170  }
171  g_start=start;
172  g_end=end;
173  g_width=width;
174  g_n_bins=n_bins;
175  g_log=log;
176  }
177 
178  public:
179 
180  /// Default constructor
182  g_n_bins=0;
183  g_start=0.0;
184  g_end=0.0;
185  g_width=0.0;
186  g_log=false;
187  }
188 
189  /** \brief Get the number of bins (regions in between grid points)
190 
191  This function returns zero if the grid is "empty".
192  */
193  size_t get_nbins() const {
194  return g_n_bins;
195  }
196 
197  /** \brief Get the number of points in the grid (always get_nbins()+1)
198 
199  This function will throw an exception if the grid is empty.
200  */
201  size_t get_npoints() const {
202  if (g_n_bins==0) {
203  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
204  exc_einval);
205  }
206  return g_n_bins+1;
207  }
208 
209  /** \brief Return true if the grid is logarithmic
210 
211  This function will throw an exception if the grid is empty.
212  */
213  bool is_log() const {
214  if (g_n_bins==0) {
215  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
216  exc_einval);
217  }
218  return g_log;
219  }
220 
221  /** \brief Desc
222  */
223  double get_start() {
224  return g_start;
225  }
226 
227  /** \brief Desc
228  */
229  double get_end() {
230  return g_end;
231  }
232 
233  /** \brief Desc
234  */
235  double get_width() {
236  return g_width;
237  }
238 
239  /** \brief Fill a vector with the specified grid
240 
241  If the vector is not big enough to hold the grid, it is
242  automatically resized.
243 
244  This function will throw an exception if the grid is empty.
245  */
246  template<class resize_vec_t> void vector(resize_vec_t &v) const {
247 
248  if (g_n_bins==0) {
249  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
250  exc_einval);
251  }
252 
253  if (v.size()<g_n_bins+1) {
254  v.resize(g_n_bins+1);
255  }
256 
257  for(size_t i=0;i<g_n_bins+1;i++) {
258  v[i]=(*this)[i];
259  }
260 
261  return;
262  }
263 
264  /** \brief Get the grid point with index \c i
265  (\f$ i \in [0,\mathrm{n_{bins}}] \f$)
266  */
267  const data_t operator[](size_t i) const {
268 
269  if (g_n_bins==0) {
270  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
271  exc_einval);
272  }
273 
274 #if !O2SCL_NO_RANGE_CHECK
275  if (i>g_n_bins) {
276  std::string str=((std::string)"Index ")+o2scl::szttos(i)+
277  " out of range "+o2scl::szttos(g_n_bins)+
278  " in uniform_grid::operator[].";
279  O2SCL_ERR(str.c_str(),exc_eindex);
280  }
281 #endif
282 
283  // Linear case
284  if (!g_log) {
285  if (i==0) return g_start;
286  else if (i==g_n_bins) return g_end;
287  return g_start+i*g_width;
288  } else {
289  // Logarithmic case
290  if (i==0) return g_start;
291  else if (i==g_n_bins) return g_end;
292  return g_start*std::pow(g_width,((data_t)i));
293  }
294  }
295 
296  /// Copy constructor
298  g_n_bins=ug.g_n_bins;
299  if (ug.g_n_bins>0) {
300  g_start=ug.g_start;
301  g_end=ug.g_end;
302  g_width=ug.g_width;
303  g_log=ug.g_log;
304  } else {
305  g_start=0.0;
306  g_end=0.0;
307  g_width=0.0;
308  g_log=false;
309  }
310  }
311 
312  /// Copy from = operator
314  g_n_bins=ug.g_n_bins;
315  if (ug.g_n_bins>0) {
316  g_start=ug.g_start;
317  g_end=ug.g_end;
318  g_width=ug.g_width;
319  g_log=ug.g_log;
320  } else {
321  g_start=0.0;
322  g_end=0.0;
323  g_width=0.0;
324  g_log=false;
325  }
326  return *this;
327  }
328 
329  };
330 
331  /** \brief Linear grid with fixed number of bins and fixed endpoint
332  */
333  template<class data_t=double> class uniform_grid_end :
334  public uniform_grid<data_t> {
335  public:
336 
337  /** \brief Create a grid with \c n_bins bins starting at
338  \c start and \c end
339 
340  The value of \c n_bins must be larger than zero and
341  \c start must not be the same as \c end.
342  */
343  uniform_grid_end(data_t start, data_t end, size_t n_bins) :
344  uniform_grid<data_t>(start,end,(end-start)/((data_t)n_bins),
345  n_bins,false) {
346  }
347  };
348 
349  /** \brief Linear grid with fixed number of bins and fixed bin size
350  */
351  template<class data_t=double> class uniform_grid_width :
352  public uniform_grid<data_t> {
353  public:
354 
355  /** \brief Create a grid with \c n_bins bins starting at
356  \c start with size \c width
357 
358  The value of \c n_bins must be larger than zero and
359  \c width must not be zero.
360  */
361  uniform_grid_width(data_t start, data_t width, size_t n_bins) :
362  uniform_grid<data_t>(start,start+n_bins*width,width,n_bins,false) {
363  }
364  };
365 
366  /** \brief Linear grid with fixed endpoint and fixed bin size
367  */
368  template<class data_t=double> class uniform_grid_end_width :
369  public uniform_grid<data_t> {
370  public:
371 
372  /** \brief Create a grid with bins of size \c width starting
373  at \c start and ending at \c end
374 
375  The value of \c n_bins must be larger than zero and
376  \c start must not be the same as \c end.
377  */
378  uniform_grid_end_width(data_t start, data_t end, data_t width) :
379  uniform_grid<data_t>(start,end,width,
380  ((size_t)((end-start)/width)),false) {
381  }
382  };
383 
384  /** \brief Logarithmic grid with fixed number of bins and fixed endpoint
385  */
386  template<class data_t=double> class uniform_grid_log_end :
387  public uniform_grid<data_t> {
388  public:
389 
390  /** \brief Create a logarithmic grid with \c n_bins bins starting at
391  \c start and \c end
392 
393  The value of \c n_bins must be larger than zero and
394  \c start must not be the same as \c end.
395  */
396  uniform_grid_log_end(data_t start, data_t end, size_t n_bins) :
397  uniform_grid<data_t>(start,end,std::pow(end/start,1.0/((data_t)n_bins)),
398  n_bins,true) {
399  }
400  };
401 
402  /** \brief Logarithmic grid with fixed number of bins and fixed bin size
403  */
404  template<class data_t=double> class uniform_grid_log_width :
405  public uniform_grid<data_t> {
406  public:
407 
408  /** \brief Create a logarithmic grid with \c n_bins bins starting at
409  \c start with size \c width
410 
411  The value of \c n_bins must be larger than zero and
412  \c width must be greater than 1.
413  */
414  uniform_grid_log_width(data_t start, data_t width, size_t n_bins) :
415  uniform_grid<data_t>(start,start*std::pow(width,n_bins),
416  width,n_bins,true) {
417  }
418  };
419 
420  /** \brief Logarithmic grid with fixed endpoint and fixed bin size
421  */
422  template<class data_t=double> class uniform_grid_log_end_width :
423  public uniform_grid<data_t> {
424  public:
425 
426  /** \brief Create a logarithmic grid with bins of size \c width starting
427  at \c start and ending at \c end
428 
429  The value of \c n_bins must be larger than zero and
430  \c start must not be the same as \c end.
431  */
432  uniform_grid_log_end_width(data_t start, data_t end, data_t width) :
433  uniform_grid<data_t>(start,end,width,
434  ((size_t)(log(end/start)/log(width))),true) {
435  }
436  };
437 
438 #ifndef DOXYGEN_NO_O2NS
439 }
440 #endif
441 
442 #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:414
uniform_grid & operator=(const uniform_grid &ug)
Copy from = operator.
Definition: uniform_grid.h:313
The main O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$scl names...
Definition: anneal.h:42
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:361
Linear grid with fixed endpoint and fixed bin size.
Definition: uniform_grid.h:368
double get_end()
Desc.
Definition: uniform_grid.h:229
const data_t operator[](size_t i) const
Get the grid point with index i ( )
Definition: uniform_grid.h:267
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:396
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:297
Linear grid with fixed number of bins and fixed bin size.
Definition: uniform_grid.h:351
invalid argument supplied by user
Definition: err_hnd.h:59
Logarithmic grid with fixed endpoint and fixed bin size.
Definition: uniform_grid.h:422
size_t get_npoints() const
Get the number of points in the grid (always get_nbins()+1)
Definition: uniform_grid.h:201
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:343
uniform_grid()
Default constructor.
Definition: uniform_grid.h:181
double get_width()
Desc.
Definition: uniform_grid.h:235
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
The O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$scl namespace ...
Definition: table.h:53
Logarithmic grid with fixed number of bins and fixed bin size.
Definition: uniform_grid.h:404
data_t g_end
The high-side of the last bin.
Definition: uniform_grid.h:107
#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:378
double get_start()
Desc.
Definition: uniform_grid.h:223
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:432
void vector(resize_vec_t &v) const
Fill a vector with the specified grid.
Definition: uniform_grid.h:246
Store data in an O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$sc...
Definition: hdf_file.h:100
bool is_log() const
Return true if the grid is logarithmic.
Definition: uniform_grid.h:213
Logarithmic grid with fixed number of bins and fixed endpoint.
Definition: uniform_grid.h:386
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:59
Linear grid with fixed number of bins and fixed endpoint.
Definition: uniform_grid.h:333
size_t get_nbins() const
Get the number of bins (regions in between grid points)
Definition: uniform_grid.h:193

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).