aboutsummaryrefslogtreecommitdiffstats
path: root/libprakpp
diff options
context:
space:
mode:
Diffstat (limited to 'libprakpp')
-rw-r--r--libprakpp/include/prakcommon.hpp14
-rw-r--r--libprakpp/include/praktable.hpp59
2 files changed, 71 insertions, 2 deletions
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 <typename T>
using function_t = std::function<T(const std::vector<T> &)>;
@@ -97,7 +107,7 @@ struct align_alloc : public std::allocator<T> {
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 <typename T>
@@ -106,9 +116,11 @@ using vector = std::vector<T, align_alloc<T>>;
/// prak value / pair value: a value with an error
template <typename T>
struct pvalue { T val, err; };
+template <typename T> struct pvalue<T> operator^(const struct pvalue<T> &v, const T &a) { return {std::pow(v.val, a), a * std::pow(v.val, a-1) * v.err}; }
template <typename T> struct pvalue<T> operator*(const struct pvalue<T> &v, const T &a) { return {v.val * a, v.err * a}; }
template <typename T> struct pvalue<T> operator*(const T &a, const struct pvalue<T> &v) { return {v.val * a, v.err * a}; }
template <typename T> struct pvalue<T> operator*(const struct pvalue<T> &a, const struct pvalue<T> &b) { return {a.val * b.val, a.val * b.val * std::hypot(a.err/a.val, b.err/b.val)}; }
+template <typename T> struct pvalue<T> operator/(const T &a, const struct pvalue<T> &v) { return {a / v.val, a * v.err / (v.val * v.val)}; }
template <typename T> struct pvalue<T> operator/(const struct pvalue<T> &v, const T &a) { return {v.val / a, v.err / a}; }
template <typename T> struct pvalue<T> operator/(const struct pvalue<T> &a, const struct pvalue<T> &b) { return {a.val / b.val, a.val / b.val * std::hypot(a.err/a.val, b.err/b.val)}; }
template <typename T> struct pvalue<T> operator+(const struct pvalue<T> &a, const struct pvalue<T> &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<std::string> 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<std::string> result) {
+ size_t result_index = result.has_value() ? index(*result) : 0;
+ for (size_t i = 0; i < rows; ++i) {
+ const std::vector<dtype> 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<iterator> cols, size_t n, std::optional<std::string> 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{};