From 320bf2f0155edd67557a3042403eeb843b90a41d Mon Sep 17 00:00:00 2001 From: justanothercatgirl Date: Sun, 9 Mar 2025 23:15:32 +0300 Subject: added 219 --- libprakpp/include/prakcommon.hpp | 14 +++++++++- libprakpp/include/praktable.hpp | 59 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) (limited to 'libprakpp') diff --git a/libprakpp/include/prakcommon.hpp b/libprakpp/include/prakcommon.hpp index 47c793c..074e290 100644 --- a/libprakpp/include/prakcommon.hpp +++ b/libprakpp/include/prakcommon.hpp @@ -44,6 +44,16 @@ typedef long double _f64; #define SUBSCR_OPRTR operator() #endif +#ifndef ENDCHAR +# define ENDCHAR '\n' +#endif +#define var(v) << #v " = " << v << ENDCHAR + +#define FOR_EACH(fn, first, ...) fn(first) __VA_OPT__(FOR_EACH_AGAIN(fn, __VA_ARGS__)) +#define FOR_EACH_AGAIN(fn, ...) FOR_EACH(fn, __VA_ARGS__) +#define APPLY_VARS(...) FOR_EACH(var, __VA_ARGS__) +#define vars(...) APPLY_VARS(__VA_ARGS__) + template using function_t = std::function &)>; @@ -97,7 +107,7 @@ struct align_alloc : public std::allocator { constexpr void deallocate( T* p, std::size_t n ) { ::operator delete(p, std::align_val_t{64}); } -};; +}; /// alias prak::vector that is the same as std::vector, but uses aligned allocator template @@ -106,9 +116,11 @@ using vector = std::vector>; /// prak value / pair value: a value with an error template struct pvalue { T val, err; }; +template struct pvalue operator^(const struct pvalue &v, const T &a) { return {std::pow(v.val, a), a * std::pow(v.val, a-1) * v.err}; } template struct pvalue operator*(const struct pvalue &v, const T &a) { return {v.val * a, v.err * a}; } template struct pvalue operator*(const T &a, const struct pvalue &v) { return {v.val * a, v.err * a}; } template struct pvalue operator*(const struct pvalue &a, const struct pvalue &b) { return {a.val * b.val, a.val * b.val * std::hypot(a.err/a.val, b.err/b.val)}; } +template struct pvalue operator/(const T &a, const struct pvalue &v) { return {a / v.val, a * v.err / (v.val * v.val)}; } template struct pvalue operator/(const struct pvalue &v, const T &a) { return {v.val / a, v.err / a}; } template struct pvalue operator/(const struct pvalue &a, const struct pvalue &b) { return {a.val / b.val, a.val / b.val * std::hypot(a.err/a.val, b.err/b.val)}; } template struct pvalue operator+(const struct pvalue &a, const struct pvalue &b) { return {a.val + b.val, std::hypot(a.err, b.err)}; } diff --git a/libprakpp/include/praktable.hpp b/libprakpp/include/praktable.hpp index daccedc..2cfa500 100644 --- a/libprakpp/include/praktable.hpp +++ b/libprakpp/include/praktable.hpp @@ -111,7 +111,39 @@ public: bool operator==(const iterator& other) { return parent == other.parent && col_index == other.col_index && data_index == other.data_index; } - value_type &operator*() { return parent->data[data_index]; }; + reference operator*() { return parent->data[data_index]; }; + }; + struct const_iterator { + const table *parent; + size_t columns; + size_t col_index = 0, data_index = 0; + using iterator_category = std::bidirectional_iterator_tag; + using value_type = dtype; + using difference_type = ptrdiff_t; + using pointer = const dtype *; + using reference = const dtype &; + const_iterator() = default; + const_iterator(const const_iterator& other) = default; + const_iterator& operator=(const const_iterator& other) = default; + const_iterator(const table *new_parent, const std::string &column, size_t row_idx = 0) + : parent{new_parent}, columns(new_parent->columns) + { + col_index = parent->index(column); + data_index = col_index + row_idx * new_parent->columns; + } + const_iterator &operator++() { data_index += columns; return *this; } + const_iterator &operator--() { data_index -= columns; return *this; } + const_iterator operator++(int) { const_iterator ret = *this; ++(*this); return ret; } + const_iterator operator--(int) { const_iterator ret = *this; --(*this); return ret; } + const_iterator &operator+(int x) { data_index += columns * x; return *this; } + const_iterator &operator-(int x) { data_index -= columns * x; return *this; } + std::strong_ordering operator<=>(const const_iterator& other) const { + return parent == other.parent && col_index == other.col_index && data_index <=> other.data_index; + } + bool operator==(const const_iterator& other) const { + return parent == other.parent && col_index == other.col_index && data_index == other.data_index; + } + reference operator*() const { return parent->data[data_index]; }; }; // Optional rownames: names of rows std::vector opt_rownames; @@ -177,7 +209,9 @@ public: } iterator begin(std::string column) { return iterator(this, column); } + const_iterator cbegin(std::string column) const { return const_iterator(this, column); } iterator end(std::string column) { return iterator(this, column, rows); } + const_iterator cend(std::string column) const { return const_iterator(this, column, rows); } dtype & SUBSCR_OPRTR (const std::string &column, size_t row) noexcept(false) { size_t i = index(column); @@ -240,6 +274,16 @@ public: return *this; } + table& apply(function_type function, const std::string& arg, std::optional result) { + size_t result_index = result.has_value() ? index(*result) : 0; + for (size_t i = 0; i < rows; ++i) { + const std::vector v(1, SUBSCR_OPRTR(arg, i)); + if (result.has_value()) data[columns * i + result_index] = function(v); + else (void)function(v); + } + return *this; + } + table &apply_n(function_type function, std::vector cols, size_t n, std::optional result) { size_t result_index = result.has_value() ? index(*result) : 0; for (size_t i = 0; i < n; ++i) { @@ -475,6 +519,19 @@ public: return accum / rows; } + dtype col_max(const std::string &column) { + dtype max = dtype{}; + for (auto it = begin(column); it != end(column); ++it) + max = max < *it ? *it : max; + return max; + } + dtype col_min(const std::string &column) { + dtype min = dtype{}; + for (auto it = begin(column); it != end(column); ++it) + min = min > *it ? *it : min; + return min; + } + // calculate standard deviation of the column dtype col_stddev(const std::string &column) { dtype accum = dtype{}; -- cgit v1.2.3-70-g09d2