18#ifndef OPAL_GSL_HISTOGRAM_HH
19#define OPAL_GSL_HISTOGRAM_HH
40 throw std::invalid_argument(
"gsl_histogram: xmin must be < xmax");
43 double bin_width = (xmax - xmin) /
n_;
44 for (
size_t i = 0; i <=
n_; ++i) {
45 range_[i] = xmin + i * bin_width;
54 throw std::invalid_argument(
"gsl_histogram: range size mismatch");
71 double get(
size_t i)
const {
72 if (i >=
bin_.size()) {
73 throw std::out_of_range(
"gsl_histogram: bin index out of range");
80 size_t n()
const {
return n_; }
86 const std::vector<double>&
bin()
const {
return bin_; }
102 auto it = std::upper_bound(
range_.begin(),
range_.end(), x);
103 return std::distance(
range_.begin(), it) - 1;
114 h->
bin_.resize(n, 0.0);
156 if (h->
range().empty() || i >= h->
range().size() - 1) {
159 *lower = h->
range()[i];
160 *upper = h->
range()[i + 1];
187 if (xmin >= xmax || ymin >= ymax) {
188 throw std::invalid_argument(
"gsl_histogram2d: invalid range");
192 double xbin_width = (xmax - xmin) /
nx_;
193 double ybin_width = (ymax - ymin) /
ny_;
194 for (
size_t i = 0; i <=
nx_; ++i) {
195 xrange_[i] = xmin + i * xbin_width;
197 for (
size_t i = 0; i <=
ny_; ++i) {
198 yrange_[i] = ymin + i * ybin_width;
226 throw std::invalid_argument(
"gsl_histogram2d: range size mismatch");
236 double get(
size_t i,
size_t j)
const {
237 if (i >=
nx_ || j >=
ny_) {
238 throw std::out_of_range(
"gsl_histogram2d: bin index out of range");
257 const std::vector<double>&
bin()
const {
return bin_; }
271 return std::distance(
xrange_.begin(), it) - 1;
279 return std::distance(
yrange_.begin(), it) - 1;
297 const auto& bin = h->
bin();
299 for (
double val : bin) {
303 pdf_.resize(bin.size());
305 for (
size_t i = 0; i < bin.size(); ++i) {
306 pdf_[i] = bin[i] / total;
313 for (
size_t i = 0; i <
pdf_.size(); ++i) {
324 void sample(
double u,
double v,
double* x,
double* y) {
327 double target = u *
cumsum_.back();
328 for (
size_t i = 0; i <
cumsum_.size(); ++i) {
335 size_t i = bin_idx /
ny_;
336 size_t j = bin_idx %
ny_;
343 *x = xmin + (xmax - xmin) * v;
344 *y = ymin + (ymax - ymin) * u;
368 h->
bin_.resize(nx * ny, 0.0);
379 gsl_histogram2d* h,
double xmin,
double xmax,
double ymin,
double ymax) {
391 gsl_histogram2d* h,
const double* xrange,
size_t nx,
const double* yrange,
size_t ny) {
438 FILE* fh,
const gsl_histogram2d* h,
const char* xformat,
const char* yformat) {
439 fprintf(fh,
"# xrange: %zu bins from %g to %g\n", h->
nx(), h->
xrange()[0], h->
xrange().back());
440 fprintf(fh,
"# yrange: %zu bins from %g to %g\n", h->
ny(), h->
yrange()[0], h->
yrange().back());
441 const auto& bin = h->
bin();
442 for (
size_t i = 0; i < h->
nx(); ++i) {
443 for (
size_t j = 0; j < h->
ny(); ++j) {
444 fprintf(fh, xformat, h->
xrange()[i]);
446 fprintf(fh, yformat, h->
yrange()[j]);
447 fprintf(fh,
" %g\n", bin[i * h->
ny() + j]);
gsl_histogram2d * gsl_histogram2d_alloc(size_t nx, size_t ny)
Allocate a 2D histogram with nx by ny bins.
void gsl_histogram2d_pdf_free(gsl_histogram2d_pdf *p)
Free a 2D histogram PDF.
void gsl_histogram2d_fprintf(FILE *fh, const gsl_histogram2d *h, const char *xformat, const char *yformat)
Print the 2D histogram in a simple text table.
void gsl_histogram2d_increment(gsl_histogram2d *h, double x, double y)
Increment the bin containing x,y by 1.
void gsl_histogram_free(gsl_histogram *h)
Free a histogram allocated by gsl_histogram_alloc.
int gsl_histogram2d_set_ranges(gsl_histogram2d *h, const double *xrange, size_t nx, const double *yrange, size_t ny)
Set explicit x/y bin edges.
int gsl_histogram_get_range(const gsl_histogram *h, size_t i, double *lower, double *upper)
Get the range for a bin.
void gsl_histogram_increment(gsl_histogram *h, double x)
Increment the bin containing x by 1.
void gsl_histogram2d_accumulate(gsl_histogram2d *h, double x, double y, double weight)
Accumulate a weighted sample into the 2D histogram.
double gsl_histogram2d_get(const gsl_histogram2d *h, size_t i, size_t j)
Get the bin count for index .
void gsl_histogram2d_pdf_init(gsl_histogram2d_pdf *p, const gsl_histogram2d *h)
Initialize a PDF from a histogram.
size_t gsl_histogram2d_nx(const gsl_histogram2d *h)
Number of x bins.
void gsl_histogram_set_ranges_uniform(gsl_histogram *h, double xmin, double xmax)
Set uniform bin edges over .
void gsl_histogram2d_pdf_sample(const gsl_histogram2d_pdf *p, double u, double v, double *x, double *y)
Sample from the PDF using two uniform variates.
size_t gsl_histogram2d_ny(const gsl_histogram2d *h)
Number of y bins.
gsl_histogram * gsl_histogram_alloc(size_t n)
Allocate a 1D histogram with n bins.
int gsl_histogram_set_ranges(gsl_histogram *h, const double *range, size_t n)
Set explicit bin edges for a histogram.
void gsl_histogram2d_set_ranges_uniform(gsl_histogram2d *h, double xmin, double xmax, double ymin, double ymax)
Set uniform x/y bin edges.
double gsl_histogram_get(const gsl_histogram *h, size_t i)
Get the bin count for index i.
gsl_histogram2d_pdf * gsl_histogram2d_pdf_alloc(size_t, size_t)
Allocate a 2D histogram PDF.
void gsl_histogram2d_free(gsl_histogram2d *h)
Free a 2D histogram.
size_t gsl_histogram_bins(const gsl_histogram *h)
Number of bins in the histogram.
2D PDF derived from histogram for sampling.
std::vector< double > xrange_
void sample(double u, double v, double *x, double *y)
Sample given two uniform variates.
std::vector< double > pdf_
std::vector< double > yrange_
void init(const gsl_histogram2d *h)
Initialize a PDF from a 2D histogram.
std::vector< double > cumsum_
2D histogram with explicit x/y bin edges.
double get(size_t i, size_t j) const
Get the bin count for index .
const std::vector< double > & bin() const
Bin count array.
std::vector< double > xrange_
void set_ranges(const double *xrange, size_t nx, const double *yrange, size_t ny)
Set explicit x/y bin edges.
void set_ranges_uniform(double xmin, double xmax, double ymin, double ymax)
Set uniform x/y bin edges over and .
size_t find_x_bin(double x) const
const std::vector< double > & yrange() const
Y-axis bin edges.
std::vector< double > yrange_
size_t nx() const
Number of x bins.
size_t find_y_bin(double y) const
void increment(double x, double y)
Increment the bin containing x,y by 1.
std::vector< double > bin_
size_t ny() const
Number of y bins.
const std::vector< double > & xrange() const
X-axis bin edges.
void accumulate(double x, double y, double weight)
Accumulate a weighted sample into the 2D histogram.
1D histogram with explicit bin edges.
void set_ranges_uniform(double xmin, double xmax)
Set uniform bin edges over .
void set_ranges(const double *range, size_t n)
Set bin edges from an explicit array.
std::vector< double > bin_
const std::vector< double > & range() const
Bin edge array.
void increment(double x)
Increment the bin containing x by 1.
std::vector< double > range_
const std::vector< double > & bin() const
Bin count array.
double get(size_t i) const
Get the bin count for index i.
size_t n() const
Number of bins.
size_t find_bin(double x) const