aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjustanothercatgirl <sotov2070@gmail.com>2025-03-05 20:12:26 +0300
committerjustanothercatgirl <sotov2070@gmail.com>2025-03-05 20:12:26 +0300
commit620b996f2ffe5e9e426b88f57e4f46bc9af7f237 (patch)
treeabb62586d4d569807ecefc007eef2316d521084c
parente10c7380486e07b277001ab3aa653b74aa990f79 (diff)
added 204
-rw-r--r--204/Makefile18
-rw-r--r--204/README.md5
-rw-r--r--204/compile_flags.txt4
-rw-r--r--204/data10
-rw-r--r--204/data215
-rw-r--r--204/data2__2
l---------204/include1
-rw-r--r--204/main.cpp52
-rw-r--r--204/plots.gp62
-rw-r--r--libprakpp/include/praktable.hpp144
10 files changed, 263 insertions, 50 deletions
diff --git a/204/Makefile b/204/Makefile
new file mode 100644
index 0000000..224506f
--- /dev/null
+++ b/204/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/204/README.md b/204/README.md
new file mode 100644
index 0000000..96fd716
--- /dev/null
+++ b/204/README.md
@@ -0,0 +1,5 @@
+<!-- Шаблон для прака -->
+<!-- файлы, заканчивающиеся на .plot считаются генерируемыми и удаляются через make clean -->
+# Обработка <> прака
+
+
diff --git a/204/compile_flags.txt b/204/compile_flags.txt
new file mode 100644
index 0000000..34ae930
--- /dev/null
+++ b/204/compile_flags.txt
@@ -0,0 +1,4 @@
+-Iinclude
+-std=c++2c
+-mavx2
+
diff --git a/204/data b/204/data
new file mode 100644
index 0000000..94abed5
--- /dev/null
+++ b/204/data
@@ -0,0 +1,10 @@
+T F2 F s ss
+290.65 0.050 ? ? ?
+291.15 0.050 ? ? ?
+291.65 0.050 ? ? ?
+333 0.042 ? ? ?
+332 0.0425 ? ? ?
+352 0.041 ? ? ?
+349 0.041 ? ? ?
+322 0.043 ? ? ?
+315 0.045 ? ? ?
diff --git a/204/data2 b/204/data2
new file mode 100644
index 0000000..696eb10
--- /dev/null
+++ b/204/data2
@@ -0,0 +1,15 @@
+x1 f1 x2 f2 x3 f3 x4 f4
+111.5 0.021 114 0.029 108 0.026 110 0.027
+118 0.025 120 0.024 120 0.019 120 0.019
+120 0.024 130 0.015 125 0.0145 130 0.010
+123 0.020 135 0.010 130 0.010 120 0.019
+130 0.015 125 0.019 130 0.010 110 0.028
+135 0.010 115 0.028 122 0.017 100 0.036
+120 0.024 105 0.037 110 0.028 93 0.040
+115 0.0285 95 0.041 85 0.042 84 0.042
+110 0.033 85 0.049 0 0 0 0
+105 0.037 83 0.05 0 0 0 0
+100 0.041 0 0 0 0 0 0
+90 0.045 0 0 0 0 0 0
+82 0.05 0 0 0 0 0 0
+0 0 0 0 0 0 0 0
diff --git a/204/data2__ b/204/data2__
new file mode 100644
index 0000000..6b6c8ee
--- /dev/null
+++ b/204/data2__
@@ -0,0 +1,2 @@
+T1 T2 T3 T4
+293.15 293.15 348 343
diff --git a/204/include b/204/include
new file mode 120000
index 0000000..2225752
--- /dev/null
+++ b/204/include
@@ -0,0 +1 @@
+../libprakpp/include/ \ No newline at end of file
diff --git a/204/main.cpp b/204/main.cpp
new file mode 100644
index 0000000..64a11e2
--- /dev/null
+++ b/204/main.cpp
@@ -0,0 +1,52 @@
+#include <iostream>
+
+#include "include/praktable.hpp"
+
+using table = prak::table<f64>;
+using f64p = prak::pvalue<f64>;
+using f64v = std::vector<f64>;
+using vecarg = const std::vector<f64> &;
+using argvec = const std::vector<f64> &;
+
+void ex1(std::string file) {
+ table t(file);
+ f64p F1 = {0.0215, 0.0005}, D = {0.0061, 0.0001}, k = {0.91, 0.01};
+ f64 sgm = (D.err / D.val) * (D.err / D.val) + (k.err / k.val) * (k.err / k.val);
+ 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")
+ .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);
+ t .apply([&A](vecarg a){ return -a[0] * A.val;}, {"T"}, "q")
+ .apply([&A](vecarg a){ return a[0] * A.err;}, {"T"}, "sq")
+ .apply_function(prak::sum<f64>, {"s", "q"}, {"ss", "sq"}, "U", "sU")
+ .write_plot("q(T).plot", "T", "q", "sq")
+ .write_plot("U(T).plot", "T", "U", "sU")
+ .print();
+ auto [qA, qB] = t.least_squares_linear("T", "q", "sq", std::nullopt);
+ auto [UA, UB] = t.least_squares_linear("T", "U", "sU", std::nullopt);
+ std::cout
+ << "s(T)" << A << "x+" << B << std::endl
+ << "q(T)" << qA << "x+" << qB << std::endl
+ << "U(T)" << UA << "x+" << UB << std::endl;
+}
+
+void ex2(std::string file) {
+ table t(file);
+ const char* strs = "1234";
+ std::string x = "x";
+ std::string f = "f";
+ std::string l = "f(x)";
+ for (int i = 0; i < 4; ++i) {
+ table _t({x, f}, {t.begin(x + strs[i]), t.begin(f + strs[i])}, t.find_index(x + strs[i], 0));
+ _t.write_plot(l + strs[i] + ".plot", "x", "f", std::nullopt).print();
+ }
+}
+
+int main() {
+ ex1("data");
+ ex2("data2");
+ return 0;
+}
diff --git a/204/plots.gp b/204/plots.gp
new file mode 100644
index 0000000..cbf7a1c
--- /dev/null
+++ b/204/plots.gp
@@ -0,0 +1,62 @@
+set term pngcairo size 1000, 800
+set grid
+
+f1(x) = a1*x+b1
+fit f1(x) 's(T).plot' using 1:2:3 yerr via a1, b1
+f2(x) = a2*x+b2
+fit f2(x) 'q(T).plot' using 1:2:3 yerr via a2, b2
+f3(x) = a3*x+b3
+fit f3(x) 'U(T).plot' using 1:2:3 yerr via a3, b3
+
+
+set output 's(T).png'
+set title "Зависимость коэффицента поверхностного натяжения от температуры"
+set xlabel "T, К"
+set ylabel "sigma, Н/м"
+
+plot 's(T).plot' using 1:2:3 with yerrorbars notitle lc 0 pt 1 lw 2, \
+ f1(x) title "" lc rgb "red"
+
+
+set output 'q(T),U(T).png'
+set title "Зависимости теплоты изотермического образования и поверхностной плотности внутренней энергии от температуры"
+set ytics nomirror
+set y2tics
+set xlabel "Т, К"
+set ylabel "q, дж/м^2"
+set y2label "U, дж/м^2"
+set yrange[1.1:1.8]
+set y2range[1:10]
+plot 'q(T).plot' using 1:2:3 with yerrorbars axes x1y1 notitle lc 0 pt 1 lw 2, \
+ 'U(T).plot' using 1:2:3 with yerrorbars axes x1y2 notitle lc 0 pt 1 lw 2, \
+ f2(x) lc rgb "red" axes x1y1 notitle, \
+ f3(x) lc rgb "red" axes x1y2 notitle, \
+ 'q(T).plot' with lines lc rgb "green" axes x1y1 title "q(T)", \
+ 'U(T).plot' with lines lc rgb "blue" axes x1y2 title "U(T)"
+unset y2tics
+unset y2label
+unset xrange
+unset yrange
+
+set xlabel "x, мм"
+set ylabel "f, мН"
+
+set output 'f1(x).png'
+set title "Зависимость силы натяжения от координаты (T = 293К)"
+plot 'f(x)1.plot' notitle lc 0 pt 1 lw 2 ,\
+ 'f(x)1.plot' notitle with lines lc rgb "blue"
+
+set output 'f2(x).png'
+set title "Зависимость силы натяжения от координаты (T = 293К)"
+plot 'f(x)2.plot' notitle lc 0 pt 1 lw 2 ,\
+ 'f(x)2.plot' notitle with lines lc rgb "blue"
+
+set output 'f3(x).png'
+set title "Зависимость силы натяжения от координаты (T = 343-333К)"
+plot 'f(x)3.plot' notitle lc 0 pt 1 lw 2 ,\
+ 'f(x)3.plot' notitle with lines lc rgb "red"
+
+set output 'f4(x).png'
+set title "Зависимость силы натяжения от координаты (T = 336-330К)"
+plot 'f(x)4.plot' notitle lc 0 pt 1 lw 2 ,\
+ 'f(x)4.plot' notitle with lines lc rgb "green"
diff --git a/libprakpp/include/praktable.hpp b/libprakpp/include/praktable.hpp
index 06519ee..daccedc 100644
--- a/libprakpp/include/praktable.hpp
+++ b/libprakpp/include/praktable.hpp
@@ -20,15 +20,15 @@
namespace prak {
-/// truncate a string to n characters, or return in unmodified
+// truncate a string to n characters, or return in unmodified
inline std::string truncate_or(const std::string &str, size_t n) {
if (str.size() >= n) return str.substr(0, n);
return str;
}
-/// Unused for now.
-/// TODO: Remove
+// Unused for now.
+// TODO: Remove
template <typename T>
struct opt_value {
enum struct t: unsigned char {
@@ -55,7 +55,7 @@ struct opt_value {
};
-/// Class that can store, print, and apply operations to a table used by lab works
+// Class that can store, print, and apply operations to a table used by lab works
template <typename dtype>
class table {
std::vector<dtype> data;
@@ -85,11 +85,14 @@ public:
table *parent;
size_t columns;
size_t col_index = 0, data_index = 0;
- using iterator_category = std::forward_iterator_tag;
+ using iterator_category = std::bidirectional_iterator_tag;
using value_type = dtype;
using difference_type = ptrdiff_t;
using pointer = dtype *;
using reference = dtype &;
+ iterator() = default;
+ iterator(const iterator& other) = default;
+ iterator& operator=(const iterator& other) = default;
iterator(table *new_parent, const std::string &column, size_t row_idx = 0)
: parent{new_parent}, columns(new_parent->columns)
{
@@ -97,21 +100,41 @@ public:
data_index = col_index + row_idx * new_parent->columns;
}
iterator &operator++() { data_index += columns; return *this; }
+ iterator &operator--() { data_index -= columns; return *this; }
iterator operator++(int) { iterator ret = *this; ++(*this); return ret; }
+ iterator operator--(int) { iterator ret = *this; --(*this); return ret; }
iterator &operator+(int x) { data_index += columns * x; return *this; }
- 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; }
+ iterator &operator-(int x) { data_index -= columns * x; return *this; }
+ std::strong_ordering operator<=>(const iterator& other) {
+ return parent == other.parent && col_index == other.col_index && data_index <=> other.data_index;
+ }
+ 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]; };
};
- /// Optional rownames: names of rows
+ // Optional rownames: names of rows
std::vector<std::string> opt_rownames;
- /// Mandatory columnnames: names of columns
+ // Mandatory columnnames: names of columns
std::vector<std::string> names;
- /// width used for printing, defaults to 8
+ // width used for printing, defaults to 8
size_t column_width = 12;
- /// default constructor
+ // default constructor
table() = default;
+
+ table(const std::vector<std::string> &cols, std::vector<iterator> iters, size_t rows)
+ : rows{rows}, columns{cols.size()}
+ {
+ names = cols;
+ data = std::vector<dtype>(rows * cols.size());
+ for (size_t row = 0; row < rows; ++row) {
+ for (size_t col = 0; col < columns; ++col) {
+ data[row * columns + col] = *iters[col];
+ ++iters[col];
+ }
+ }
+ }
explicit table(const std::vector<std::string> &columns, size_t rows, const dtype &deflt)
: rows{rows}, columns{columns.size()}
@@ -120,7 +143,7 @@ public:
data = std::vector<dtype>(rows * columns.size(), deflt);
}
- /// Data: array of ararys, not freed automatically.
+ // Data: array of ararys, not freed automatically.
explicit table(const std::vector<std::string> &columns, dtype **data, size_t rows /*size_t columns = strings.size()*/)
: rows{rows}, columns{columns.size()}
{
@@ -132,9 +155,9 @@ public:
data[i * columns.size() + j] = data[i][j];
}
- /// Strings: names for columns
- /// `new_data` format: { { entry1_a, entry2_a, ...} { entry1_b, entry2_b, ... }, ... }
- /// where `a`, `b`, ... are columns
+ // Strings: names for columns
+ // `new_data` format: { { entry1_a, entry2_a, ...} { entry1_b, entry2_b, ... }, ... }
+ // where `a`, `b`, ... are columns
explicit table(std::vector<std::string> &&strings, std::vector<std::vector<dtype>> &&new_data)
: rows{new_data.size() ? new_data[0].size() : 0}, columns{strings.size()}
{
@@ -165,7 +188,7 @@ public:
return data.at(names.size() * row + column);
}
- /// prints a table. defaults to using std::cout, but any std::ostream can be passed in it.
+ // prints a table. defaults to using std::cout, but any std::ostream can be passed in it.
void print(std::ostream &stream = std::cout) const {
stream << "columns: " << columns << ", rows: " << rows << std::endl;
bool print_names = opt_rownames.size() == data.size() / columns;
@@ -196,15 +219,15 @@ public:
stream << '|' << std::endl << '|' << rowsep << '|' << std::endl;
}
- /// Returns whether the amount of names is correct
- /// If it is incorrect, names won't be displayed during printing
+ // Returns whether the amount of names is correct
+ // If it is incorrect, names won't be displayed during printing
bool set_rownames(std::vector<std::string> &&names) {
opt_rownames = names;
return opt_rownames.size() == data.size() / names.size();
}
- /// apply a function to several columns and store result in another column
- /// function must accept std::vector or arguments
+ // apply a function to several columns and store result in another column
+ // function must accept std::vector or arguments
table &apply(function_type function, stringvec args, std::optional<std::string> result) {
size_t result_index = result.has_value() ? index(*result) : 0;
for (size_t i = 0; i < rows; ++i) {
@@ -228,6 +251,22 @@ public:
}
return *this;
}
+
+ table &apply_function(
+ function_type function,
+ const std::vector<std::string> cols,
+ const std::vector<std::string> sgms,
+ const std::string& res,
+ const std::string& ress) {
+ std::vector<iterator> __cols(cols.size()),
+ __sgms(sgms.size());
+ for (size_t i = 0; i < __cols.size() && i < __sgms.size(); ++i) {
+ __cols[i] = begin(cols[i]);
+ __sgms[i] = begin(sgms[i]);
+ }
+
+ return apply_function_n(function, __cols, __sgms, rows, res, ress);
+ }
table &apply_function_n(
function_type function,
@@ -253,7 +292,7 @@ public:
}
return *this;
}
- /// adds a column with name `name` and data `column_data`
+ // adds a column with name `name` and data `column_data`
table &add_column(const 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));
@@ -270,8 +309,13 @@ public:
table &add_column(const std::string &name, dtype dflt = dtype{}) {
return add_column(name, std::vector<dtype>(rows, dflt));
}
+ table &add_columns(const std::vector<std::string> &cols, dtype dflt = dtype{}) {
+ for (const auto &str : cols)
+ add_column(str, dflt);
+ return *this;
+ }
- /// Deletes a column from a table.
+ // Deletes a column from a table.
table &delete_col(const std::string &colname) {
std::vector<dtype> data_new(rows * (--columns));
size_t idx = index(colname);
@@ -286,7 +330,7 @@ public:
return *this;
}
- /// Deletes several columns
+ // Deletes several columns
table &delete_cols(const stringvec &cols) noexcept(false) {
size_t columns_new = columns - cols.size();
std::vector<dtype> data_new(rows * columns_new);
@@ -314,7 +358,7 @@ public:
}
- /// Appends a row to the table. if name is set, appends it to `opt_rownames`
+ // Appends a row 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));
@@ -328,17 +372,17 @@ public:
return os;
}
- /// Reads a table from a file in a format:
- /// ```
- /// col1 col2 col3 ...
- /// val1 val2 val3 ...
- /// val4 val5 val6 ...
- /// ...
- /// ```
- /// Note tha `val` may either be a real number or a question mark, denoting that the value is unknown
- /// `col` may be any string without whitespaeces.
- /// if the first column is named "__name__" (as in python), first val in each row is a string used as
- /// a row name.
+ // Reads a table from a file in a format:
+ // ```
+ // col1 col2 col3 ...
+ // val1 val2 val3 ...
+ // val4 val5 val6 ...
+ // ...
+ // ```
+ // Note tha `val` may either be a real number or a question mark, denoting that the value is unknown
+ // `col` may be any string without whitespaeces.
+ // if the first column is named "__name__" (as in python), first val in each row is a string used as
+ // a row name.
void read(std::ifstream& f) {
std::string header;
std::getline(f >> std::ws, header);
@@ -375,14 +419,14 @@ public:
columns = names.size();
}
- /// Reads a table from a file specified by `path`.
- /// For details, refer to documentation of `void read(std::ifstream&)` overload
+ // 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`
+ // Fills a specified column with the same value `v`
table &fill_column(const std::string &column, dtype v) {
apply([&v](const std::vector<dtype>& _) -> dtype { return v; }, {}, column);
return *this;
@@ -403,7 +447,7 @@ public:
return *this;
}
- /// returns an std::pair with coefficients A and B in that order
+ // 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::optional<dtype> sigma_fixed)
noexcept(false) {
@@ -423,7 +467,7 @@ public:
return ret;
}
- /// calculate an average of the column
+ // 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)
@@ -431,7 +475,7 @@ public:
return accum / rows;
}
- /// calculate standard deviation of the column
+ // calculate standard deviation of the column
dtype col_stddev(const std::string &column) {
dtype accum = dtype{};
dtype avg = col_avg(column);
@@ -440,9 +484,9 @@ public:
return std::sqrt(accum);
}
- /// takes columns [columns], calculates average and standard deviation for each row, puts them into `avg` and `stddev` and deleted original columns
- /// if create_columns is true, creates columns avg and stddev
- /// This is common thing to do, so might as well write a function for that
+ // takes columns [columns], calculates average and standard deviation for each row, puts them into `avg` and `stddev` and deleted original columns
+ // if create_columns is true, creates columns avg and stddev
+ // This is common thing to do, so might as well write a function for that
table& into_avgstddev(const std::vector<std::string> &columns, const std::string &avg_out, const std::string &stddev_out, bool create_columns = false) {
if (create_columns) {
add_column(avg_out, std::vector<dtype>(rows, dtype{}));
@@ -454,8 +498,8 @@ public:
return *this;
}
- /// applies a function `func` to arguments in columns `args`, stores the result in column `result` and standard error in column `result_sigma`.
- /// `sigmas` must be in a 1-to-1 correspondance with `args`
+ // applies a function `func` to arguments in columns `args`, stores the result in column `result` and standard error in column `result_sigma`.
+ // `sigmas` must be in a 1-to-1 correspondance with `args`
table& apply_with_err(function_t<dtype> func, const stringvec &args, const stringvec &sigmas, const std::string &result, const std::string result_sigma) {
if (args.size() != sigmas.size()) throw dimension_error("Args and Sigmas did not have the same dimentinons");
size_t result_index = index(result),
@@ -481,7 +525,7 @@ public:
return col_idx;
}
- /// Serialize data in format `data[args[0]][i] data[args[1]][i] data[args[2]][i]...`
+ // 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());
for (size_t i = 0; i < args.size(); ++i) {
@@ -495,7 +539,7 @@ public:
}
}
- /// Serialize data in format `data[xs][i] data[ys][i] <data[xss][i]> <data>[yss][i]>`, readable by gnuplot with xyerrorbars
+ // Serialize data in format `data[xs][i] data[ys][i] <data[xss][i]> <data>[yss][i]>`, readable by gnuplot with xyerrorbars
table &write_plot_4(const std::string &file, const std::string &xs, const std::string &ys, const std::string &xss, const std::string &yss) {
std::ofstream out(file);
size_t xi = index(xs), yi = index(ys), xsi = index(xss), ysi = index(yss);
@@ -507,7 +551,7 @@ public:
return *this;
}
- /// Serialize data in format `data[xs][i] data[ys][i] <data[ss][i]>`, readable by gnuplot with yerrorbars
+ // Serialize data in format `data[xs][i] data[ys][i] <data[ss][i]>`, readable by gnuplot with yerrorbars
table &write_plot(const std::string &xs, const std::string &ys, std::optional<std::string> yss = std::nullopt, std::ostream &out = std::cout) {
size_t nosigma = std::numeric_limits<size_t>::max();
size_t xsi = index(xs), ysi = index(ys), ssi = nosigma;
@@ -521,7 +565,7 @@ public:
return *this;
}
- /// Serialize data into a file `file`. For details, refer to documentation for overload with std::ifstream as an argument
+ // Serialize data into a file `file`. For details, refer to documentation for overload with std::ifstream as an argument
table &write_plot(const std::string &file, const std::string &xs, const std::string &ys, std::optional<std::string> yss = std::nullopt) {
std::ofstream out(file);
return write_plot(xs, ys, yss, out);