Version: SMASH-3.1
tabulation.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2019
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
8 #include "smash/tabulation.h"
9 
10 namespace smash {
11 
12 Tabulation::Tabulation(double x_min, double range, size_t num,
13  std::function<double(double)> f)
14  : x_min_(x_min), x_max_(x_min + range), inv_dx_(num / range) {
15  if (num < 2) {
16  throw std::runtime_error("Tabulation needs at least two values");
17  }
18  values_.resize(num + 1);
19  const double dx = range / num;
20  for (size_t i = 0; i <= num; i++) {
21  values_[i] = f(x_min_ + i * dx);
22  }
23 }
24 
25 double Tabulation::get_value_step(double x) const {
26  if (x < x_min_) {
27  return 0.;
28  }
29  // this rounds correctly because double -> int conversion truncates
30  const unsigned int n = (x - x_min_) * inv_dx_ + 0.5;
31  if (n >= values_.size()) {
32  return values_.back();
33  } else {
34  return values_[n];
35  }
36 }
37 
38 double Tabulation::get_value_linear(double x, Extrapolation extrapol) const {
39  if (x < x_min_) {
40  return 0.;
41  }
42  if (extrapol == Extrapolation::Zero && x > x_max_) {
43  return 0.0;
44  }
45  if (extrapol == Extrapolation::Const && x > x_max_) {
46  return values_.back();
47  }
48  const double index_double = (x - x_min_) * inv_dx_;
49  // here n is the lower index
50  const size_t n =
51  std::min(static_cast<size_t>(index_double), values_.size() - 2);
52  const double r = index_double - n;
53  return values_[n] + (values_[n + 1] - values_[n]) * r;
54 }
55 
62 static void swrite(std::ofstream& stream, double x) {
63  stream.write(reinterpret_cast<const char*>(&x), sizeof(x));
64 }
65 
72 static double sread_double(std::ifstream& stream) {
73  double x;
74  stream.read(reinterpret_cast<char*>(&x), sizeof(x));
75  return x;
76 }
77 
84 static void swrite(std::ofstream& stream, size_t x) {
85  // We want to support 32-bit and 64-bit platforms, so we store a 64-bit
86  // integer on all platforms.
87  const auto const_size_x = static_cast<uint64_t>(x);
88  stream.write(reinterpret_cast<const char*>(&const_size_x),
89  sizeof(const_size_x));
90 }
91 
98 static size_t sread_size(std::ifstream& stream) {
99  uint64_t x;
100  stream.read(reinterpret_cast<char*>(&x), sizeof(x));
101  if (x > std::numeric_limits<size_t>::max()) {
102  throw std::runtime_error("trying to read vector larger than supported");
103  }
104  return x;
105 }
106 
113 static void swrite(std::ofstream& stream, const std::vector<double> x) {
114  swrite(stream, x.size());
115  if (x.size() > 0) {
116  stream.write(reinterpret_cast<const char*>(x.data()),
117  sizeof(x[0]) * x.size());
118  }
119 }
120 
127 static std::vector<double> sread_vector(std::ifstream& stream) {
128  const size_t n = sread_size(stream);
129  std::vector<double> x;
130  x.resize(n);
131  stream.read(reinterpret_cast<char*>(x.data()), sizeof(double) * n);
132  return x;
133 }
134 
141 static void swrite(std::ofstream& stream, sha256::Hash x) {
142  // The size is always the same, so there is no need to write it.
143  stream.write(reinterpret_cast<const char*>(x.data()),
144  sizeof(x[0]) * x.size());
145 }
146 
153 static sha256::Hash sread_hash(std::ifstream& stream) {
154  sha256::Hash x;
155  stream.read(reinterpret_cast<char*>(x.data()), x.size());
156  return x;
157 }
158 
159 void Tabulation::write(std::ofstream& stream, sha256::Hash hash) const {
160  swrite(stream, hash);
161  swrite(stream, x_min_);
162  swrite(stream, x_max_);
163  swrite(stream, inv_dx_);
164  swrite(stream, values_);
165 }
166 
167 Tabulation Tabulation::from_file(std::ifstream& stream, sha256::Hash hash) {
168  sha256::Hash hash_from_stream = sread_hash(stream);
169  Tabulation t;
170  if (hash != hash_from_stream) {
171  return t;
172  }
173  t.x_min_ = sread_double(stream);
174  t.x_max_ = sread_double(stream);
175  t.inv_dx_ = sread_double(stream);
176  t.values_ = sread_vector(stream);
177  return t;
178 }
179 
180 } // namespace smash
A class for storing a one-dimensional lookup table of floating-point values.
Definition: tabulation.h:35
double x_min_
lower bound for tabulation
Definition: tabulation.h:113
double inv_dx_
inverse step size 1/dx
Definition: tabulation.h:119
double x_max_
upper bound for tabulation
Definition: tabulation.h:116
std::vector< double > values_
vector for storing tabulated values
Definition: tabulation.h:110
static Tabulation from_file(std::ifstream &stream, sha256::Hash hash)
Construct a tabulation object by reading binary data from a stream.
Definition: tabulation.cc:167
Tabulation()
Construct an empty tabulation object.
Definition: tabulation.h:40
void write(std::ofstream &stream, sha256::Hash hash) const
Write a binary representation of the tabulation to a stream.
Definition: tabulation.cc:159
double get_value_step(double x) const
Look up a value from the tabulation (without any interpolation, simply using the closest tabulated va...
Definition: tabulation.cc:25
double get_value_linear(double x, Extrapolation extrapolation=Extrapolation::Linear) const
Look up a value from the tabulation using linear interpolation.
Definition: tabulation.cc:38
constexpr int n
Neutron.
std::array< uint8_t, HASH_SIZE > Hash
A SHA256 hash.
Definition: sha256.h:25
Definition: action.h:24
static std::vector< double > sread_vector(std::ifstream &stream)
Read binary representation of a vector of doubles.
Definition: tabulation.cc:127
static double sread_double(std::ifstream &stream)
Read binary representation of a double.
Definition: tabulation.cc:72
static sha256::Hash sread_hash(std::ifstream &stream)
Read binary representation of a SHA256 hash.
Definition: tabulation.cc:153
Extrapolation
The kind of extrapolation used by the tabulation.
Definition: tabulation.h:26
static void swrite(std::ofstream &stream, double x)
Write binary representation to stream.
Definition: tabulation.cc:62
static size_t sread_size(std::ifstream &stream)
Read binary representation of a size_t.
Definition: tabulation.cc:98