xdata.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "xview.h"
4 #include "xerror.h"
5 #include "xoutput.h"
6 #include <array>
7 #include <cmath>
8 #include <fstream>
9 #include <functional>
10 #include <optional>
11 #include <vector>
12 
13 namespace nmx {
14 
21 template<size_t N>
22 class Data
23 {
24 public:
25  using Row = std::array<double, N>;
26  using Container = std::vector<Row>;
27  using Column = std::vector<double>;
28  using View = View<Data<N>>;
29 
30 private:
31  Container _data;
32 
33 public:
37  inline Data() {}
38 
43  inline const auto &data() const { return _data; }
44 
49  inline auto &data() { return _data; }
50 
55  inline Row &first() { return *_data.begin(); }
56 
61  inline const Row &first() const { return *_data.begin(); }
62 
67  inline Row &last() { return *(_data.end() - 1); }
68 
73  inline const Row &last() const { return *(_data.end() - 1); }
74 
80  inline const auto &row(size_t idx) const {
81  //wenn ungültiger Index: out_of_range Ausnahme
82  return _data.at(idx);
83  }
84 
90  inline auto &row(size_t idx) {
91  //wenn ungültiger Index: out_of_range Ausnahme
92  return _data.at(idx);
93  }
94 
99  inline size_t rows() const { return _data.size(); }
100 
105  inline size_t columns() const { return N; }
106 
111  inline void add(const Row &lst) { _data.push_back(lst); }
112 
118  inline void add(std::initializer_list<double> lst) {
119  Check::error_if<std::out_of_range>(nmx_msgx(__func__), //
120  lst.size() > N);
121  //instanziiere neue Zeile
122  Row crow;
123  //kopiere Elemente
124  std::copy(std::begin(lst), std::end(lst), std::begin(crow));
125  //addiere neue Reihe zur Tabelle
126  add(crow);
127  }
128 
134  inline auto &operator+=(const Row &lst) {
135  add(lst);
136  return *this;
137  }
138 
144  inline auto &operator+=(std::initializer_list<double> lst) {
145  try {
146  add(lst);
147  } catch (...) {
148  // wenn ein Fehler auftritt, enthält die Nachricht
149  // den richtigen Funktionsnamen
150  throw std::out_of_range(nmx_msgx(__func__));
151  }
152  return *this;
153  }
154 
160  inline void save(std::ostream &ofs, Format fmt) const {
161  for (const auto &row : _data) {
162  fmt.write_line(ofs, row);
163  }
164  }
165 
173  template<class FN>
174  void save(std::ostream &ofs, Format fmt, FN fn) const {
175  for (const auto &row : _data) {
176  fmt.write_line(ofs, fn(row));
177  }
178  }
179 
185  auto column(size_t cidx) const {
186  //erzeuge Vektor mit Länge gleich der Anzahl der Reihen
187  Column clmn(rows());
188  for (size_t idx = 0; idx < _data.size(); idx++) {
189  clmn[idx] = _data[idx][cidx];
190  }
191  return clmn;
192  }
193 
201  inline void set_column(const Column clmn, size_t idx) {
202  if (_data.empty()) { // Tabelle ist leer
203  for (size_t jdx = 0; jdx < clmn.size(); jdx++) {
204  Row crow; //erzeuge neue Reihe
205  crow[idx] = clmn[jdx]; // setze Wert
206  _data.push_back(crow); // füge Reihe hinzu
207  }
208  } else { //Tabelle nicht leer
209  if (clmn.size() != rows()) {
210  //Fehler: die neue Spalte hat nicht die gleiche Länge
211  // mit der alten Spalte
212  throw std::range_error(nmx_msgx(__func__));
213  }
214  for (size_t jdx = 0; jdx < rows(); jdx++) {
215  _data[jdx][idx] = clmn[jdx]; //ersetze Wert
216  }
217  }
218  }
219 
225  template<class FN>
226  void apply(FN fn) {
227  for (auto &row : _data) {
228  fn(row);
229  }
230  }
231 
236  inline void read_csv(std::ifstream &ifs) {
237  //teste Status von Eingabestrom
238  Check::error_if(nmx_msg, !ifs.is_open());
239  std::string line;
240  while (getline(ifs, line)) {
241  std::stringstream stream(line);
242  std::string token;
243  size_t idx = 0;
244  char *ptr;
245  std::array<double, N> buffer;
246  while (getline(stream, token, ',')) {
247  buffer[idx] = std::strtod(token.c_str(), &ptr);
248  idx++;
249  }
250  add(buffer);
251  }
252  }
253 
258  inline auto view() const { return View(*this); }
259 
267  template<class PREDICATE>
268  auto view(PREDICATE fn, bool f = true, bool l = true) const {
269  View view(*this);
270  if (f) { //füge erste Zeile der Tabelle hinzu?
271  view.add(static_cast<size_t>(0));
272  }
273  for (size_t idx = 0; idx < rows(); idx++) {
274  if (fn(_data[idx])) {
275  view.add(idx); //addiere Reihenindex zur View
276  }
277  }
278  if (l) { //füge letzte Zeile der Tabelle hinzu?
279  view.add(_data.size() - 1);
280  }
281  return view;
282  }
283 
292  inline auto view(std::initializer_list<typename Container::iterator> lst,
293  bool f = true,
294  bool l = true) {
295  View view(*this);
296 
297  if (f) { //füge erste Zeile der Tabelle hinzu?
298  view.add(static_cast<size_t>(0));
299  }
300  for (const auto &itr : lst) {
301  //berechne Index
302  const auto cidx = std::distance(_data.begin(), itr);
303  //addiere Reihenindex zur View
304  view.add(static_cast<size_t>(cidx));
305  }
306  if (l) { //füge letzte Zeile der Tabelle hinzu?
307  view.add(_data.size() - 1);
308  }
309  return view;
310  }
311 
319  inline auto select_rows(size_t step, size_t startidx = 0, bool last = false) const {
320  View view(*this);
321 
322  for (size_t idx = startidx; idx < _data.size(); idx += step) {
323  //addiere Reihenindex zur View
324  view.add(idx);
325  }
326 
327  if (last) { //füge letzte Zeile der Tabelle hinzu?
328  view.add(_data.size() - 1);
329  }
330  return view;
331  }
332 
338  inline auto select_total_rows(size_t n, size_t start = 0, bool l = true) const {
339  //berechne Abstand zwischen den Zeilen
340  const size_t stepSize = std::ceil((rows()) / (n - 1));
341  return select_rows(stepSize, start, l);
342  }
343 
350  template<class FN>
351  inline Column column(size_t cidx, const FN &fn) {
352  Column clmn;
353  for (const auto &row : _data) {
354  if (fn(row)) {
355  clmn.push_back(row[cidx]);
356  }
357  }
358  return clmn;
359  }
360 }; //Data
361 
362 } // namespace nmx
auto & operator+=(const Row &lst)
operator += Hinzufügen einer Reihe
Definition: xdata.h:134
void apply(FN fn)
apply ändere alle oder bestimmte Elemente
Definition: xdata.h:226
auto select_rows(size_t step, size_t startidx=0, bool last=false) const
view Teile der Tabelle als View
Definition: xdata.h:319
auto & operator+=(std::initializer_list< double > lst)
operator += Hinzufügen einer Reihe
Definition: xdata.h:144
std::vector< double > Column
Definition: xdata.h:27
auto view() const
view die ganze Tabelle als view
Definition: xdata.h:258
const Row & first() const
first erste Zeile (lesender Zugriff)
Definition: xdata.h:61
const auto & row(size_t idx) const
row Zugriff auf Zeile per Index (lesen)
Definition: xdata.h:80
void save(std::ostream &ofs, Format fmt) const
save Schreibe Tabelle in Datei
Definition: xdata.h:160
std::vector< Row > Container
Definition: xdata.h:26
static void error_if(const std::string &s, bool arg)
error_if Fehler wenn Bedingung erfüllt ist
Definition: xerror.h:51
Column column(size_t cidx, const FN &fn)
column erstelle Kopie einer Spalte
Definition: xdata.h:351
The Data class Eine Klasse für Zahlentabellen mit fester Anzahl von Spalten. Die Anzahl der Reihen wä...
Definition: xdata.h:22
auto column(size_t cidx) const
column Kopie einer Spalte
Definition: xdata.h:185
auto & data()
data schreibender Zugriff auf die interne Struktur
Definition: xdata.h:49
#define nmx_msg
Definition: xerror.h:113
const Row & last() const
last letzte Zeile (lesender Zugriff)
Definition: xdata.h:73
void add(const Row &lst)
add füge eine neue Zeile hinzu
Definition: xdata.h:111
auto view(std::initializer_list< typename Container::iterator > lst, bool f=true, bool l=true)
view Teile der Tabelle als View
Definition: xdata.h:292
const auto & data() const
data lesender Zugriff auf die interne Struktur
Definition: xdata.h:43
auto view(PREDICATE fn, bool f=true, bool l=true) const
view Teile der Tabelle als View
Definition: xdata.h:268
void set_column(const Column clmn, size_t idx)
set_column Die Werte einer Spalte werden eingefügt oder ersetzt. Wenn die Tabelle leer ist wird erst ...
Definition: xdata.h:201
View< Data< N > > View
Definition: xdata.h:28
#define nmx_msgx(msg)
Definition: xerror.h:125
auto select_total_rows(size_t n, size_t start=0, bool l=true) const
get_total_rows generiere View mit eine Instanz vom Typ View bestimmter Anzahl von Spalten ...
Definition: xdata.h:338
void read_csv(std::ifstream &ifs)
read_csv lese Daten aus csv-Datei
Definition: xdata.h:236
void write_line(std::ostream &ofs, const T &crow) const
write_line Daten in einem Array werden in einer Zeile ausgegeben
Definition: xfmt.h:66
Row & first()
first erste Zeile (schreibender Zugriff)
Definition: xdata.h:55
Row & last()
last letzte Zeile (schreibender Zugriff)
Definition: xdata.h:67
Data()
Data Standardkonstruktor die Tabelle enthält keine Daten.
Definition: xdata.h:37
void save(std::ostream &ofs, Format fmt, FN fn) const
save Schreibe Tabelle in Datei
Definition: xdata.h:174
void add(std::initializer_list< double > lst)
add füge eine neue Reihe hinzu. Die Anzahl der Elemente darf kleiner als die Anzahl der Spalten sein ...
Definition: xdata.h:118
The Format class Formatierte Ausgabe von Arrays.
Definition: xfmt.h:10
size_t rows() const
rows
Definition: xdata.h:99
auto & row(size_t idx)
row Zugriff auf Zeile per Index (schreiben)
Definition: xdata.h:90
double f(double x, void *params)
f
Definition: x035.h:15
size_t columns() const
columns
Definition: xdata.h:105
std::array< double, N > Row
Definition: xdata.h:25