13 template <
typename Tcoeff = double,
14 typename base = Eigen::Matrix<Tcoeff, Eigen::Dynamic, Eigen::Dynamic>>
18 using Tvec = std::vector<double>;
20 using index_t =
typename base::Index;
21 static_assert(std::is_integral_v<index_t> && std::is_signed_v<index_t>,
22 "signed integral value expected");
27 explicit Table(
const Tvec& bw = {1, 1},
const Tvec& lo = {0, 0},
const Tvec& hi = {2, 2})
29 reInitializer(bw, lo, hi);
33 template <
typename OtherDerived>
34 explicit Table(
const Eigen::MatrixBase<OtherDerived>& other)
39 template <
typename OtherDerived>
Table& operator=(
const Eigen::MatrixBase<OtherDerived>& other)
41 this->base::operator=(other);
45 template <
typename OtherDerived>
46 explicit Table(
const Eigen::ArrayBase<OtherDerived>& other)
51 template <
typename OtherDerived>
Table& operator=(
const Eigen::ArrayBase<OtherDerived>& other)
53 this->base::operator=(other);
57 void reInitializer(
const Tvec& bw,
const Tvec& lo,
const Tvec& hi)
59 assert(bw.size() == 1 || bw.size() == 2);
60 assert(bw.size() == lo.size() && lo.size() == hi.size());
64 _rows = (_hi[0] - _lo[0]) / _bw[0] + 1.;
66 _cols = (_hi[1] - _lo[1]) / _bw[1] + 1;
71 base::resize(_rows, _cols);
75 void round(Tvec& v)
const 77 for (Tvec::size_type i = 0; i != v.size(); ++i) {
79 (v[i] >= 0) ?
int(v[i] / _bw[i] + 0.5) * _bw[i] : int(v[i] / _bw[i] - 0.5) * _bw[i];
83 void to_index(Tvec& v)
const 85 for (Tvec::size_type i = 0; i != v.size(); ++i) {
86 v[i] = (v[i] >= 0) ?
int(v[i] / _bw[i] + 0.5) : int(v[i] / _bw[i] - 0.5);
87 v[i] = v[i] - _lo[i] / _bw[i];
92 Tcoeff& operator[](
const Tvec& v)
94 return base::operator()(static_cast<index_t>(v[0]), static_cast<index_t>(v[1]));
97 bool isInRange(
const Tvec& v)
const 100 for (Tvec::size_type i = 0; i != v.size(); ++i) {
101 in_range = in_range && v[i] >= _lo[i] && v[i] <= _hi[i];
106 Tvec hist2buf(
int)
const 109 for (index_t i = 0; i < _cols; ++i) {
110 for (index_t j = 0; j < _rows; ++j) {
111 sendBuf.push_back(base::operator()(j, i));
117 void buf2hist(
const Tvec& v)
121 auto p =
static_cast<int>(v.size()) / this->size();
122 Tvec::size_type n = 0;
125 for (index_t i = 0; i < _cols; ++i) {
126 for (index_t j = 0; j < _rows; ++j) {
127 base::operator()(j, i) += v.at(n++) / nproc;
133 base getBlock(
const Tvec& slice)
136 switch (slice.size()) {
138 w[0] = w[1] = (slice[0] - _lo[0]) / _bw[0];
142 w[0] = (slice[0] - _lo[0]) / _bw[0];
143 w[1] = (slice[1] - _lo[0]) / _bw[0];
146 w[0] = w[1] = _rows - 1;
147 w[2] = w[3] = _cols - 1;
150 w[0] = (slice[0] - _lo[0]) / _bw[0];
151 w[1] = (slice[1] - _lo[0]) / _bw[0];
152 w[2] = (slice[2] - _lo[1]) / _bw[1];
153 w[3] = (slice[3] - _lo[1]) / _bw[1];
155 return this->block(w[0], w[2], w[1] - w[0] + 1, w[3] - w[2] + 1);
158 Tcoeff avg(
const Tvec& v)
const {
return this->getBlock(v).mean(); }
160 void save(
const std::string& filename, Tcoeff scale = 1, Tcoeff translate = 0)
const 162 Eigen::VectorXd v1(_cols + 1);
163 Eigen::VectorXd v2(_rows + 1);
164 v1(0) = v2(0) = base::size();
165 for (index_t i = 1; i != _cols + 1; ++i) {
166 v1(i) = (i - 1) * _bw[1] + _lo[1];
168 for (index_t i = 1; i != _rows + 1; ++i) {
169 v2(i) = (i - 1) * _bw[0] + _lo[0];
171 base m(_rows + 1, _cols + 1);
173 m.topRows(1) = v1.transpose();
174 m.bottomRightCorner(_rows, _cols) = *
this;
176 m.bottomRightCorner(_rows, _cols) *= scale;
178 if (translate != 0) {
179 m.bottomRightCorner(_rows, _cols) += base::Constant(_rows, _cols, translate);
181 std::ofstream stream(filename.c_str());
183 stream.precision(10);
191 void saveRow(
const std::string& filename,
const Tvec& v, Tcoeff scale = 1, Tcoeff translate = 0)
193 if (!this->isInRange(v)) {
196 auto b = this->getBlock(v);
197 auto size = b.size();
198 Eigen::VectorXd w(size);
199 for (index_t i = 0; i != size; ++i) {
200 w(i) = i * _bw[1] + _lo[1];
204 m.bottomRightCorner(size, 1) = b.transpose();
206 m.bottomRightCorner(size, 1) *= scale;
208 if (translate != 0) {
209 m.bottomRightCorner(size, 1) += base::Constant(size, 1, translate);
211 std::ofstream stream(filename.c_str());
213 stream.precision(10);
218 void load(
const std::string& filename)
220 if (std::ifstream f(filename.c_str()); f) {
225 while (getline(f, line)) {
226 if (i > _rows - 1 || j > _cols - 1) {
227 throw std::runtime_error(
"file larger than expected:"s + filename);
230 const std::istringstream iss(line);
235 base::operator()(i, ++j) = b;
239 if (i != _rows || j != _cols - 1) {
240 throw std::runtime_error(
"file larger than expected:"s + filename);
Dynamic table for 1d data.
Definition: table_1d.h:15
Cell list class templates.
Definition: actions.cpp:11