uniform_grid.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2011-2017, 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 Fill a vector with the specified grid
222 
223  If the vector is not big enough to hold the grid, it is
224  automatically resized.
225 
226  This function will throw an exception if the grid is empty.
227  */
228  template<class resize_vec_t> void vector(resize_vec_t &v) const {
229 
230  if (g_n_bins==0) {
231  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
232  exc_einval);
233  }
234 
235  if (v.size()<g_n_bins+1) {
236  v.resize(g_n_bins+1);
237  }
238 
239  for(size_t i=0;i<g_n_bins+1;i++) {
240  v[i]=(*this)[i];
241  }
242 
243  return;
244  }
245 
246  /** \brief Get the grid point with index \c i
247  (\f$ i \in [0,\mathrm{n_{bins}}] \f$)
248  */
249  const data_t operator[](size_t i) const {
250 
251  if (g_n_bins==0) {
252  O2SCL_ERR("Grid not set in uniform_grid::get_npoints().",
253  exc_einval);
254  }
255 
256 #if !O2SCL_NO_RANGE_CHECK
257  if (i>g_n_bins) {
258  std::string str=((std::string)"Index ")+o2scl::szttos(i)+
259  " out of range "+o2scl::szttos(g_n_bins)+
260  " in uniform_grid::operator[].";
261  O2SCL_ERR(str.c_str(),exc_eindex);
262  }
263 #endif
264 
265  // Linear case
266  if (!g_log) {
267  if (i==0) return g_start;
268  else if (i==g_n_bins) return g_end;
269  return g_start+i*g_width;
270  } else {
271  // Logarithmic case
272  if (i==0) return g_start;
273  else if (i==g_n_bins) return g_end;
274  return g_start*std::pow(g_width,((data_t)i));
275  }
276  }
277 
278  /// Copy constructor
280  g_n_bins=ug.g_n_bins;
281  if (ug.g_n_bins>0) {
282  g_start=ug.g_start;
283  g_end=ug.g_end;
284  g_width=ug.g_width;
285  g_log=ug.g_log;
286  } else {
287  g_start=0.0;
288  g_end=0.0;
289  g_width=0.0;
290  g_log=false;
291  }
292  }
293 
294  /// Copy from = operator
296  g_n_bins=ug.g_n_bins;
297  if (ug.g_n_bins>0) {
298  g_start=ug.g_start;
299  g_end=ug.g_end;
300  g_width=ug.g_width;
301  g_log=ug.g_log;
302  } else {
303  g_start=0.0;
304  g_end=0.0;
305  g_width=0.0;
306  g_log=false;
307  }
308  return *this;
309  }
310 
311  };
312 
313  /** \brief Linear grid with fixed number of bins and fixed endpoint
314  */
315  template<class data_t=double> class uniform_grid_end :
316  public uniform_grid<data_t> {
317  public:
318 
319  /** \brief Create a grid with \c n_bins bins starting at
320  \c start and \c end
321 
322  The value of \c n_bins must be larger than zero and
323  \c start must not be the same as \c end.
324  */
325  uniform_grid_end(data_t start, data_t end, size_t n_bins) :
326  uniform_grid<data_t>(start,end,(end-start)/((data_t)n_bins),
327  n_bins,false) {
328  }
329  };
330 
331  /** \brief Linear grid with fixed number of bins and fixed bin size
332  */
333  template<class data_t=double> class uniform_grid_width :
334  public uniform_grid<data_t> {
335  public:
336 
337  /** \brief Create a grid with \c n_bins bins starting at
338  \c start with size \c width
339 
340  The value of \c n_bins must be larger than zero and
341  \c width must not be zero.
342  */
343  uniform_grid_width(data_t start, data_t width, size_t n_bins) :
344  uniform_grid<data_t>(start,start+n_bins*width,width,n_bins,false) {
345  }
346  };
347 
348  /** \brief Linear grid with fixed endpoint and fixed bin size
349  */
350  template<class data_t=double> class uniform_grid_end_width :
351  public uniform_grid<data_t> {
352  public:
353 
354  /** \brief Create a grid with bins of size \c width starting
355  at \c start and ending at \c end
356 
357  The value of \c n_bins must be larger than zero and
358  \c start must not be the same as \c end.
359  */
360  uniform_grid_end_width(data_t start, data_t end, data_t width) :
361  uniform_grid<data_t>(start,end,width,
362  ((size_t)((end-start)/width)),false) {
363  }
364  };
365 
366  /** \brief Logarithmic grid with fixed number of bins and fixed endpoint
367  */
368  template<class data_t=double> class uniform_grid_log_end :
369  public uniform_grid<data_t> {
370  public:
371 
372  /** \brief Create a logarithmic grid with \c n_bins bins starting at
373  \c start and \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_log_end(data_t start, data_t end, size_t n_bins) :
379  uniform_grid<data_t>(start,end,std::pow(end/start,1.0/((data_t)n_bins)),
380  n_bins,true) {
381  }
382  };
383 
384  /** \brief Logarithmic grid with fixed number of bins and fixed bin size
385  */
386  template<class data_t=double> class uniform_grid_log_width :
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 with size \c width
392 
393  The value of \c n_bins must be larger than zero and
394  \c width must be greater than 1.
395  */
396  uniform_grid_log_width(data_t start, data_t width, size_t n_bins) :
397  uniform_grid<data_t>(start,start*std::pow(width,n_bins),
398  width,n_bins,true) {
399  }
400  };
401 
402  /** \brief Logarithmic grid with fixed endpoint and fixed bin size
403  */
404  template<class data_t=double> class uniform_grid_log_end_width :
405  public uniform_grid<data_t> {
406  public:
407 
408  /** \brief Create a logarithmic grid with bins of size \c width starting
409  at \c start and ending at \c end
410 
411  The value of \c n_bins must be larger than zero and
412  \c start must not be the same as \c end.
413  */
414  uniform_grid_log_end_width(data_t start, data_t end, data_t width) :
415  uniform_grid<data_t>(start,end,width,
416  ((size_t)(log(end/start)/log(width))),true) {
417  }
418  };
419 
420 #ifndef DOXYGEN_NO_O2NS
421 }
422 #endif
423 
424 #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:396
uniform_grid & operator=(const uniform_grid &ug)
Copy from = operator.
Definition: uniform_grid.h:295
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:343
Linear grid with fixed endpoint and fixed bin size.
Definition: uniform_grid.h:350
const data_t operator[](size_t i) const
Get the grid point with index i ( )
Definition: uniform_grid.h:249
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:378
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:279
Linear grid with fixed number of bins and fixed bin size.
Definition: uniform_grid.h:333
invalid argument supplied by user
Definition: err_hnd.h:59
Logarithmic grid with fixed endpoint and fixed bin size.
Definition: uniform_grid.h:404
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:325
uniform_grid()
Default constructor.
Definition: uniform_grid.h:181
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:386
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:360
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:414
void vector(resize_vec_t &v) const
Fill a vector with the specified grid.
Definition: uniform_grid.h:228
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:96
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:368
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:315
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).