aboutsummaryrefslogtreecommitdiffstats
path: root/libprakpp/include
diff options
context:
space:
mode:
Diffstat (limited to 'libprakpp/include')
-rw-r--r--libprakpp/include/prakcommon.hpp19
-rw-r--r--libprakpp/include/prakmath.hpp24
-rw-r--r--libprakpp/include/prakmatrix.hpp2
-rw-r--r--libprakpp/include/praktable.hpp80
4 files changed, 109 insertions, 16 deletions
diff --git a/libprakpp/include/prakcommon.hpp b/libprakpp/include/prakcommon.hpp
index 749d5ef..45030d0 100644
--- a/libprakpp/include/prakcommon.hpp
+++ b/libprakpp/include/prakcommon.hpp
@@ -5,6 +5,25 @@
#include <vector>
#include <iostream>
+typedef void i0;
+typedef int8_t i8;
+typedef uint8_t u8;
+typedef int16_t i16;
+typedef uint16_t u16;
+typedef int32_t i32;
+typedef uint32_t u32;
+typedef int64_t i64;
+typedef uint64_t u64;
+typedef ssize_t isz;
+typedef size_t usz;
+typedef float f32;
+typedef double f64;
+#if __SIZEOF_LONG_DOUBLE__ == 16
+typedef long double f128;
+#else
+typedef long double _f64;
+#endif
+
#if defined(_MSC_VER) || !defined(__cpp_multidimensional_subscript) || __cplusplus < 202110L
#warning "can not use multidimentional subscript operator: falling back to `operator()`"
#undef MDSUBSCRIPT
diff --git a/libprakpp/include/prakmath.hpp b/libprakpp/include/prakmath.hpp
index 3a4e4db..a5eb0b8 100644
--- a/libprakpp/include/prakmath.hpp
+++ b/libprakpp/include/prakmath.hpp
@@ -2,6 +2,7 @@
#include <cmath>
#include <concepts>
+#include <numeric>
#ifdef __x86_64__
#include <immintrin.h>
@@ -184,6 +185,25 @@ scalar:
return linear + finalize(buf);
}
+template <arithmetic T>
+T avg(const std::vector<T> &args) {
+ T init{};
+ for (const T &x : args) {
+ init += x;
+ }
+ return init / args.size();
+}
+
+template <arithmetic T>
+T stddev(const std::vector<T> &args) {
+ T sum = {};
+ const T a = avg<T>(args);
+ for (T el : args) {
+ sum += (a-el)*(a-el);
+ }
+ return std::sqrt(sum/args.size()/(args.size()-1));
+}
+
// take a derivative of function `f` with arguments `at` and with differentiable variable being at index `varidx`
template <std::floating_point T>
T deriv4(function_t<T> f, std::vector<T> /*I actually do want a copy here*/ at, size_t varidx) {
@@ -204,7 +224,7 @@ T deriv4(function_t<T> f, std::vector<T> /*I actually do want a copy here*/ at,
/// get error of the calculated value
template <std::floating_point T>
-T sigma(function_t<T> f, const std::vector<T> &args, const std::vector<T> sigmas) noexcept(false) {
+T sigma(function_t<T> f, const std::vector<T> &args, const std::vector<T> &sigmas) noexcept(false) {
if (args.size() != sigmas.size()) throw dimension_error("function prak::sigma : Args.size() does not match sigmas.size()");
T sum = 0;
for (size_t i = 0; i < args.size(); ++i) {
@@ -277,7 +297,7 @@ void least_squares_linear(
/// May throw std::bad_optional_access
template <typename T>
std::enable_if<std::is_arithmetic_v<T>, std::vector<pvalue<T>>>
-polynomial_regression(
+polynominal_regression(
size_t degree,
std::vector<T> data_x,
std::vector<T> data_y,
diff --git a/libprakpp/include/prakmatrix.hpp b/libprakpp/include/prakmatrix.hpp
index 87b38b4..53d3b4b 100644
--- a/libprakpp/include/prakmatrix.hpp
+++ b/libprakpp/include/prakmatrix.hpp
@@ -3,8 +3,8 @@
#include "prakcommon.hpp"
#include <cstring>
-#include <iomanip>
#include <ostream>
+#include <optional>
#include <vector>
namespace prak {
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 <cassert>
#include <cstddef>
#include <functional>
#include <algorithm>
@@ -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<std::string> opt_rownames;
@@ -108,16 +109,23 @@ public:
/// default constructor
table() = default;
+ explicit table(const std::vector<std::string> &columns, size_t rows, const dtype &deflt)
+ : rows{rows}, columns{columns.size()}
+ {
+ names = columns;
+ data = std::vector<dtype>(rows * columns.size(), deflt);
+ }
+
/// Data: array of ararys, not freed automatically.
- explicit table(const std::vector<std::string> &strings, dtype **data, size_t rows /*size_t columns = strings.size()*/)
- : rows{rows}, columns{strings.size()}
+ explicit table(const std::vector<std::string> &columns, dtype **data, size_t rows /*size_t columns = strings.size()*/)
+ : rows{rows}, columns{columns.size()}
{
- names = strings;
+ names = columns;
- data = std::vector<dtype>(rows * strings.size());
+ data = std::vector<dtype>(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<dtype> column_data) {
+ if (column_data.size() == 0) column_data = std::vector<dtype>(rows, dtype{});
std::vector<dtype> 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<dtype> values, std::optional<std::string> name = std::nullopt) {
+ if (values.size() == 0) values = std::vector<dtype>(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<dtype> 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>& _) -> dtype { return v; }, {}, column);
+ }
/// returns an std::pair with coefficients A and B in that order
- std::pair<prak::pvalue<dtype>, prak::pvalue<dtype>> least_squares_linear(std::string x, std::string y, std::optional<std::string> sigma = std::nullopt) {
+ std::pair<prak::pvalue<dtype>, prak::pvalue<dtype>>
+ least_squares_linear(std::string x, std::string y, std::optional<std::string> sigma, std::optional<dtype> 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<dtype> _x(rows);
prak::vector<dtype> _y(rows);
prak::vector<dtype> _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<dtype>(rows, static_cast<dtype>(1));
+ else _s = prak::vector<dtype>(rows, static_cast<dtype>(*sigma_fixed));
std::pair<prak::pvalue<dtype>, prak::pvalue<dtype>> ret;
prak::least_squares_linear<dtype>(_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<size_t> 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<std::string> yss = std::nullopt) const {
+ std::ofstream out(file);
+ write_plot(xs, ys, yss, out);
+ }
void plot_png(
const std::string output_filename,