From 320bf2f0155edd67557a3042403eeb843b90a41d Mon Sep 17 00:00:00 2001 From: justanothercatgirl Date: Sun, 9 Mar 2025 23:15:32 +0300 Subject: added 219 --- 204/main.cpp | 2 +- 219/Makefile | 18 ++++++++++++ 219/README.md | 5 ++++ 219/compile_flags.txt | 4 +++ 219/data | 13 +++++++++ 219/data2 | 12 ++++++++ 219/include | 1 + 219/main.cpp | 61 ++++++++++++++++++++++++++++++++++++++++ 219/plots.gp | 29 +++++++++++++++++++ libprakpp/include/prakcommon.hpp | 14 ++++++++- libprakpp/include/praktable.hpp | 59 +++++++++++++++++++++++++++++++++++++- tempalte/plots.gp | 3 +- 12 files changed, 217 insertions(+), 4 deletions(-) create mode 100644 219/Makefile create mode 100644 219/README.md create mode 100644 219/compile_flags.txt create mode 100644 219/data create mode 100644 219/data2 create mode 120000 219/include create mode 100644 219/main.cpp create mode 100644 219/plots.gp diff --git a/204/main.cpp b/204/main.cpp index 64a11e2..37b4466 100644 --- a/204/main.cpp +++ b/204/main.cpp @@ -15,7 +15,7 @@ void ex1(std::string file) { f64 F_err = std::sqrt(2.0) * F1.err; t .apply([&F1](vecarg a){ return a[0] - F1.val;}, {"F2"}, "F") .apply([&](vecarg a){ return a[0] / (2 * k.val * prak::PI * D.val);}, {"F"}, "s") - .apply([&](vecarg a){ return a[0] * std::sqrt(F_err * F_err / (a[1] * a[1]) + sgm);}, {"s", "F"}, "ss") + .apply([&](vecarg a){ return a[0] * std::sqrt(F_err * F_err / (a[1] * a[1]) + sgm);}, {"F", "s"}, "ss") .write_plot("s(T).plot", "T", "s", "ss") .add_columns({"q", "sq", "U", "sU"}); auto [A, B] = t.least_squares_linear("T", "s", std::make_optional("ss"), std::nullopt); diff --git a/219/Makefile b/219/Makefile new file mode 100644 index 0000000..224506f --- /dev/null +++ b/219/Makefile @@ -0,0 +1,18 @@ + +CFLAGS = -std=c++2c -mavx -Iinclude -ggdb + +.PHONY: all run_main clean gnuplot + +run: gnuplot + +gnuplot: plots.gp run_main + gnuplot $< &>/dev/null + +run_main: main + ./main + +main: main.cpp include/* + $(CXX) -o $@ $< $(CFLAGS) + +clean: + rm -fr main *.png *.plot diff --git a/219/README.md b/219/README.md new file mode 100644 index 0000000..96fd716 --- /dev/null +++ b/219/README.md @@ -0,0 +1,5 @@ + + +# Обработка <> прака + + diff --git a/219/compile_flags.txt b/219/compile_flags.txt new file mode 100644 index 0000000..34ae930 --- /dev/null +++ b/219/compile_flags.txt @@ -0,0 +1,4 @@ +-Iinclude +-std=c++2c +-mavx2 + diff --git a/219/data b/219/data new file mode 100644 index 0000000..2cb863c --- /dev/null +++ b/219/data @@ -0,0 +1,13 @@ +I U R W +25 0.13 ? ? +100 0.54 ? ? +155 0.87 ? ? +200 1.14 ? ? +275 1.66 ? ? +350 2.25 ? ? +300 1.83 ? ? +250 1.48 ? ? +200 1.14 ? ? +150 0.85 ? ? +100 0.56 ? ? +50 0.26 ? ? diff --git a/219/data2 b/219/data2 new file mode 100644 index 0000000..9c44794 --- /dev/null +++ b/219/data2 @@ -0,0 +1,12 @@ +n I_V DP DP' A +? 2 1 ? ? +? 2.85 1.9 ? ? +? 5.8 2.7 ? ? +? 8.7 5 ? ? +? 13 7.9 ? ? +? 11.5 6.7 ? ? +? 7.7 4.5 ? ? +? 4.2 2.8 ? ? +? 3 2 ? ? +? 2.4 1.3 ? ? +? 2 1.1 ? ? diff --git a/219/include b/219/include new file mode 120000 index 0000000..2225752 --- /dev/null +++ b/219/include @@ -0,0 +1 @@ +../libprakpp/include/ \ No newline at end of file diff --git a/219/main.cpp b/219/main.cpp new file mode 100644 index 0000000..f6fc4e2 --- /dev/null +++ b/219/main.cpp @@ -0,0 +1,61 @@ +#include + +#include "include/praktable.hpp" + +using table = prak::table; +using f64p = prak::pvalue; +using f64v = std::vector; +using vecarg = const std::vector &; +using argvec = const std::vector &; + +f64p (ex1) (std::string file) { + table t(file); + t .add_columns({"sI", "sU", "sR", "sW"}) + .multiply_column("I", 1e-3) + .apply(prak::mul, "U", "sU") + .apply(prak::add, "sU", "sU") + .apply(prak::mul, "I", "sI") + .apply_function([](argvec a){ return a[0]/a[1]; }, {"U", "I"}, {"sU", "sI"}, "R", "sR") + .apply_function(prak::prod, {"U", "I"}, {"sU", "sI"}, "W", "sW") + .write_plot_4("R(W).plot", "W", "R", "sW", "sR") + .print(); + auto [A, B] = t.least_squares_linear("W", "R", "sR", std::nullopt); + std::cout << "МНК R(W): A = " << A << "; B = " << B << '\n'; + f64p alpha = {3.5e-3, 5e-5}, + L = {0.25, 0.005}, + r_2 = {0.006, 5e-6}, r_1 = {0.075e-3, 5e-6}, + k = prak::function([](vecarg a){ return a[0] * a[1] / (2 * prak::PI * a[2] * a[3]) * std::log(a[4]/a[5]);}, {alpha, B, L, A, r_2, r_1}); + std::cout << "k = " << k << '\n'; + f64p eps = {0.35, 0.005}, sgm = {5.67e-8, 0.01e-8}, + S = prak::function([](vecarg a){ return 2 * prak::PI * a[0] * a[1]; }, {r_1, L}), + R = {t.col_avg("R"), 0}, dT = prak::function([](vecarg a){return std::abs((a[0] - a[1])/(a[1]*a[2]));}, {R, B, alpha}), + T_0 = {295, 5}, T_1 = T_0 + dT, W_rad = eps * sgm * (T_1*T_1*T_1*T_1 - T_0*T_0*T_0*T_0)*S, + g = {9.8, 0.05}, beta = 1.0 / T_0, nu = {1.6e-5, 0.1e-5}, Gr = g * beta * L * L * L * dT / nu / nu, + alpha2 = 0.75 * k / L * ((0.7 * Gr) ^ 0.25), W_con = alpha2 * dT * S; + std::cout var(eps) var(sgm) var(R) var(dT) var(T_0) var(T_1) var(W_rad) var(beta) var(nu) var(Gr) var(alpha2) var(W_con); + return k; +} + +f64p (ex2) (const std::string& s) { + table t(s); + t .multiply_column("I_V", 1e-6) + .apply(prak::mul, "DP", "DP'") + .write_plot("I_V(DP).plot", "DP'", "I_V", std::nullopt) + .print(); + // gnuplot дал оценку лучше + f64p A = {1.24834e-09, 5.18e-11}, + B = {1.57878e-07, 2.787e-07}; + + f64p R = {1e-3, 5e-5}, l = {0.23, 0.005}, eta = prak::PI * (R^4.0) / (8.0 * l * A), + Re = 2.0 * f64p{1.2041, 0.02} * t.col_max("I_V") / (eta * prak::PI * R); + std::cout var(A) var(B) var(eta) var(Re) << std::endl; + return eta; +} + +int (main) (void) { + std::cout << ex1("data") / ex2("data2") / 2.0 + << " = C_P\nпо табличным значениям: C_P = " << 0.0259 / 0.001004 / 2 + << "\nПо здравому смыслу:7/2R = " << 7.0/2 * 8.31 << std::endl; + + return 0; +} diff --git a/219/plots.gp b/219/plots.gp new file mode 100644 index 0000000..9e1a17e --- /dev/null +++ b/219/plots.gp @@ -0,0 +1,29 @@ +set term pngcairo size 1000, 800 +set grid + +f1(x) = a1*x+b1 +fit f1(x) 'R(W).plot' using 1:2:3:4 xyerr via a1, b1 + +set output 'R(W).png' +set title "График зависимости сопротивления R от тепловой мощности W" +set xlabel "W, Дж" +set ylabel "R, Ом" +set label sprintf("A = %.5g\n B = %.5g", a1, b1) at graph 0.1, 0.9 front boxed +plot 'R(W).plot' using 1:2:3:4 with xyerrorbars notitle lc 0 pt 1 lw 2, \ + f1(x) title "R(W)" lc rgb "red" + +reset + +f2(x) = a2*x+b2 +fit f2(x) 'I_V(DP).plot' via a2, b2 + + set output 'I_V(DP).png' + set title "График зависимости плотности потока от разницы давлений" + set xlabel "P-P_0, Па" + set ylabel "I_V, м^3/с" +set label sprintf("A = %.5g\n B = %.5g", a2, b2) at graph 0.1, 0.9 front boxed + +plot 'I_V(DP).plot' notitle lc 0 pt 1 lw 2, \ + f2(x) title "I_V(dP)" lc rgb "red" + + 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{}; diff --git a/tempalte/plots.gp b/tempalte/plots.gp index a6e5cbb..9c2994f 100644 --- a/tempalte/plots.gp +++ b/tempalte/plots.gp @@ -9,6 +9,7 @@ set title "" set xlabel "" set ylabel "" +#set label sprintf("A = %.4g\n B = %.4g", a1, b1) at graph 0.1, 0.9 front boxed #plot '.plot' using 1:2:3 with yerrorbars notitle lc 0 pt 1 lw 2, \ -# f1(x) title "" lc rgb "red", \ +# f1(x) title "" lc rgb "red" -- cgit v1.2.3-70-g09d2