From fcf77faf19dcb9d75b7842ec7138551bd73418cf Mon Sep 17 00:00:00 2001 From: justanothercatgirl Date: Sun, 24 Nov 2024 19:42:42 +0300 Subject: Added 101 prak --- libprakpp/include/praktable.hpp | 80 ++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 13 deletions(-) (limited to 'libprakpp/include/praktable.hpp') diff --git a/libprakpp/include/praktable.hpp b/libprakpp/include/praktable.hpp index f32d00d..70f6d49 100644 --- a/libprakpp/include/praktable.hpp +++ b/libprakpp/include/praktable.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -96,7 +97,7 @@ public: iterator operator++(int) { iterator ret = *this; ++(*this); return ret; } bool operator==(iterator other) { return data_index == other.data_index && parent == other.parent && col_index == other.col_index; } bool operator!=(iterator other) { return data_index != other.data_index || parent != other.parent || col_index != other.col_index; } - value_type operator*() { return parent->data[data_index]; }; + value_type &operator*() { return parent->data[data_index]; }; }; /// Optional rownames: names of rows std::vector opt_rownames; @@ -108,16 +109,23 @@ public: /// default constructor table() = default; + explicit table(const std::vector &columns, size_t rows, const dtype &deflt) + : rows{rows}, columns{columns.size()} + { + names = columns; + data = std::vector(rows * columns.size(), deflt); + } + /// Data: array of ararys, not freed automatically. - explicit table(const std::vector &strings, dtype **data, size_t rows /*size_t columns = strings.size()*/) - : rows{rows}, columns{strings.size()} + explicit table(const std::vector &columns, dtype **data, size_t rows /*size_t columns = strings.size()*/) + : rows{rows}, columns{columns.size()} { - names = strings; + names = columns; - data = std::vector(rows * strings.size()); + data = std::vector(rows * columns.size()); for (size_t i = 0; i < rows; ++i) - for (size_t j = 0; j < strings.size(); ++j) - data[i * strings.size() + j] = data[i][j]; + for (size_t j = 0; j < columns.size(); ++j) + data[i * columns.size() + j] = data[i][j]; } /// Strings: names for columns @@ -137,10 +145,16 @@ public: } } + explicit table(const std::string &file) { + read(file); + } + iterator begin(std::string column) { return iterator(this, column); } iterator end(std::string column) { return iterator(this, column, rows); } - dtype & SUBSCR_OPRTR (const std::string &column, size_t row) { + dtype & SUBSCR_OPRTR (const std::string &column, size_t row) noexcept(false) { + size_t i = index(column); + if (i == columns) throw std::out_of_range("Column " + column + " does not exist"); return data.at(names.size() * row + index(column)); } @@ -196,12 +210,14 @@ public: v[j] = SUBSCR_OPRTR(args[j], i); if (result.has_value()) data[columns * i + result_index] = function(v); else (void)function(v); - } + } + /* print(std::cerr); */ return *this; } /// adds a column with name `name` and data `column_data` void add_column(std::string name, std::vector column_data) { + if (column_data.size() == 0) column_data = std::vector(rows, dtype{}); std::vector data_new(rows * (++columns)); for (size_t row = 0; row < rows; ++row) { @@ -215,6 +231,7 @@ public: /// Appends a column to the table. if name is set, appends it to `opt_rownames` void add_row(std::vector values, std::optional name = std::nullopt) { + if (values.size() == 0) values = std::vector(columns, dtype{}); data.resize(columns * (++rows)); std::copy_n(values.cbegin(), columns, data.end() - columns); if (name.has_value()) opt_rownames.push_back(*name); @@ -224,7 +241,7 @@ public: t.print(os); return os; } - + /// Reads a table from a file in a format: /// ``` /// col1 col2 col3 ... @@ -251,7 +268,9 @@ public: names.push_back(buffer); std::vector tmp_row(names.size()); + int __i = 0; while (!(f >> std::ws).eof()) { + ++__i; if (read_names) { f >> buffer; opt_rownames.push_back(buffer); @@ -269,9 +288,25 @@ public: } columns = names.size(); } + + /// Reads a table from a file specified by `path`. + /// For details, refer to documentation of `void read(std::ifstream&)` overload + void read(const std::string &path) { + std::ifstream f(path); + read(f); + } + + /// Fills a specified column with the same value `v` + void fill_column(const std::string &column, dtype v) { + apply([&v](const std::vector& _) -> dtype { return v; }, {}, column); + } /// returns an std::pair with coefficients A and B in that order - std::pair, prak::pvalue> least_squares_linear(std::string x, std::string y, std::optional sigma = std::nullopt) { + std::pair, prak::pvalue> + least_squares_linear(std::string x, std::string y, std::optional sigma, std::optional sigma_fixed) + noexcept(false) { + if (sigma.has_value() == sigma_fixed.has_value()) + throw std::invalid_argument("sigma and sigma_fixed can't both have (no) value"); prak::vector _x(rows); prak::vector _y(rows); prak::vector _s(rows); @@ -279,13 +314,26 @@ public: std::copy(begin(x), end(x), _x.begin()); std::copy(begin(y), end(y), _y.begin()); if (sigma.has_value()) std::copy(begin(*sigma), end(*sigma), _s.begin()); - else _s = prak::vector(rows, static_cast(1)); + else _s = prak::vector(rows, static_cast(*sigma_fixed)); std::pair, prak::pvalue> ret; prak::least_squares_linear(_x, _y, _s, ret.first, ret.second); return ret; } + /// calculate an average of the column + dtype col_avg(const std::string &column) { + dtype accum = dtype{}; + for (auto it = begin(column); it != end(column); ++it) + accum += *it; + return accum / rows; + } + + /// calculate standard deviation of the column + dtype col_stddev(const std::string &column) { + assert(0); + } + /// Serialize data in format `data[args[0]][i] data[args[1]][i] data[args[2]][i]...` void print_plot(const stringvec &args, std::ostream &out = std::cout) const { std::vector offsets(args.size()); @@ -307,11 +355,17 @@ public: if (yss.has_value()) ssi = index(*yss); for (size_t row = 0; row < rows; ++row) { size_t offset = columns * row; - out << data[offset + xsi] << ' ' << data[offset + ysi]; + out << data.at(offset + xsi) << ' ' << data.at(offset + ysi); if (ssi != nosigma) out << ' ' << data[offset+ssi]; out << std::endl; } } + + /// Serialize data into a file `file`. For details, refer to documentation for overload with std::ifstream as an argument + void write_plot(const std::string &file, const std::string &xs, const std::string &ys, std::optional yss = std::nullopt) const { + std::ofstream out(file); + write_plot(xs, ys, yss, out); + } void plot_png( const std::string output_filename, -- cgit v1.2.3-70-g09d2