From 42c9872d6d0fe8b2b424acc6bd162cd1f0523cb6 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 24 Mar 2024 11:57:56 +0300 Subject: [PATCH 1/3] Interface --- Spline/Interface.py | 295 +++++++++++++++++++++++++++++++++++- Spline/lib/bin/spline.so | Bin 26520 -> 52880 bytes Spline/lib/include/TMA.h | 2 +- Spline/lib/include/spline.h | 97 +++++++++++- Spline/lib/src/compile.sh | 2 +- Spline/lib/src/sample.cpp | 6 +- Spline/lib/src/utility.cpp | 220 +++++++++++++++++++++++++-- 7 files changed, 599 insertions(+), 23 deletions(-) mode change 100644 => 100755 Spline/lib/bin/spline.so diff --git a/Spline/Interface.py b/Spline/Interface.py index 2ebeb76..ff15665 100644 --- a/Spline/Interface.py +++ b/Spline/Interface.py @@ -1,8 +1,42 @@ import ctypes +import sys +import numpy as np +import pyqtgraph as pg +from PyQt5 import QtWidgets +from PyQt5.QtWidgets import * +from PyQt5.QtCore import Qt +Num = 10000 lib = ctypes.CDLL('./lib/bin/spline.so') lib.get_approximation.restype = ctypes.POINTER(ctypes.c_double) lib.get_approximation.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_error.restype = ctypes.POINTER(ctypes.c_double) +lib.get_error.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_f.restype = ctypes.POINTER(ctypes.c_double) +lib.get_f.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_f1.restype = ctypes.POINTER(ctypes.c_double) +lib.get_f1.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_f2.restype = ctypes.POINTER(ctypes.c_double) +lib.get_f2.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_s1.restype = ctypes.POINTER(ctypes.c_double) +lib.get_s1.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_s2.restype = ctypes.POINTER(ctypes.c_double) +lib.get_s2.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_derivative_error.restype = ctypes.POINTER(ctypes.c_double) +lib.get_derivative_error.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_second_derivative_error.restype = ctypes.POINTER(ctypes.c_double) +lib.get_second_derivative_error.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32] +lib.get_a.restype = ctypes.POINTER(ctypes.c_double) +lib.get_a.argtypes = [ctypes.c_uint32] +lib.get_b.restype = ctypes.POINTER(ctypes.c_double) +lib.get_b.argtypes = [ctypes.c_uint32] +lib.get_c.restype = ctypes.POINTER(ctypes.c_double) +lib.get_c.argtypes = [ctypes.c_uint32] +lib.get_d.restype = ctypes.POINTER(ctypes.c_double) +lib.get_d.argtypes = [ctypes.c_uint32] +lib.set_spline.argtypes = [ctypes.c_double, ctypes.c_double, ctypes.c_uint32, ctypes.c_int, ctypes.c_double, ctypes.c_double] +lib.free_some.argtypes = [ctypes.c_int] + def setSpline(a: float, b: float, n: int, fun_num: int, mu1: float = 0, mu2: float = 0): lib.set_spline(a, b, n, fun_num, mu1, mu2) @@ -11,9 +45,264 @@ def getApproximation(a: float, b: float, n: int): ptr = lib.get_approximation(a, b, n) return ptr[:n] -setSpline(0, 1, 10, 1) -a = getApproximation(0, 1, 10) -print(a) +def getA( n: int): + ptr = lib.get_a(n) + return ptr[:n] + +def getB( n: int): + ptr = lib.get_b(n) + return ptr[:n] + +def getC(n: int): + ptr = lib.get_c(n) + return ptr[:n] + +def getD( n: int): + ptr = lib.get_d(n) + return ptr[:n] + +def getError(a: float, b: float, n: int): + ptr = lib.get_error(a, b, n) + return ptr[:n ] + +def getDerivativeError(a: float, b: float, n: int): + ptr = lib.get_derivative_error(a, b, n) + return ptr[:n ] + +def getSecondDerivativeError(a: float, b: float, n: int): + ptr = lib.get_second_derivative_error(a, b, n) + return ptr[:n ] + +def FreeAll(): + lib.free_all() + +def FreeSome(i: int): + lib.free_some(i) + +def getF(a: float, b: float, n: int): + ptr = lib.get_f(a, b, n) + return ptr[:n ] + +def getF1(a: float, b: float, n: int): + ptr = lib.get_f1(a, b, n) + return ptr[:n ] + +def getF2(a: float, b: float, n: int): + ptr = lib.get_f2(a, b, n) + return ptr[:n ] + +def getS1(a: float, b: float, n: int): + ptr = lib.get_s1(a, b, n) + return ptr[:n ] + +def getS2(a: float, b: float, n: int): + ptr = lib.get_s2(a, b, n) + return ptr[:n ] + +class Window(QMainWindow): + + def __init__(self): + super().__init__() + + self.setWindowTitle("Сплайны") + self.setGeometry(100, 100, 1850, 1000) + + #making graph template + self.plot_widget = pg.PlotWidget(self) + self.plot_widget.setGeometry(460, 10, 1000, 990) + self.plot_widget.showGrid(x=True, y=True, alpha=0.2) + self.plot_widget.setBackground('w') + self.plot_widget.show() + + #making tables + self.table1 = QTableWidget(self) + self.table1.setGeometry(0, 400, 450, 600) + self.table1.setColumnCount(10) + self.table1.setHorizontalHeaderLabels(["x", "F(x)", "S(x)","a", "b", "c", "d", "|f(x) - S(x)|", "|f'(x) - S'(x)|", "|f''(x) - S''(x)|"]) + + self.table2 = QTableWidget(self) + self.table2.setGeometry(1480, 10, 350, 940) + self.table2.setColumnCount(3) + self.table2.setHorizontalHeaderLabels(["x", "F(x)", "error(x)"]) + + #list of functions + text1 = QtWidgets.QLabel(self) + text1.setText("Функция") + text1.setGeometry(85, 0, 100, 40) + self.combo_box = QComboBox(self) + self.combo_box.addItem("Тестовая") + self.combo_box.addItem("F(x) = sin(exp(x))") + self.combo_box.addItem("F(x) = sin(cos(x))") + self.combo_box.addItem("F(x) = sin(x) / x") + self.combo_box.addItem("F(x) = exp(x - 3)") + self.combo_box.setGeometry(10, 40, 210, 40) + + #S"(a) = mu1; S"(b) = mu2 + text4 = QtWidgets.QLabel(self) + text4.setText("Граничные условия") + text4.setGeometry(250, 15, 140, 25) + self.line_edit1 = QLineEdit(self) + self.line_edit1.setGeometry(300, 45, 90, 30) + self.line_edit1.setText('0') + self.line_edit2 = QLineEdit(self) + self.line_edit2.setGeometry(300, 85, 90, 30) + self.line_edit2.setText('0') + text2 = QtWidgets.QLabel(self) + text2.setText("S''(a) = ") + text2.setGeometry(240, 45, 70, 30) + text3 = QtWidgets.QLabel(self) + text3.setText("S''(b) = ") + text3.setGeometry(240, 85, 70, 30) + + #n + text5 = QtWidgets.QLabel(self) + text5.setText("Число разбиений") + text5.setGeometry(10, 90, 120, 30) + self.line_edit3 = QLineEdit(self) + self.line_edit3.setGeometry(130, 90, 90, 30) + self.line_edit3.setText('10') + + #button approximation + self.button = QtWidgets.QPushButton(self) + self.button.setGeometry(240, 125, 200, 30) + self.button.setText("Аппроксимировать") + self.button.clicked.connect(self.Click) + + #button clear graph + self.button1 = QtWidgets.QPushButton(self) + self.button1.setGeometry(1500, 960, 150, 30) + self.button1.setText("Очистить график") + self.button1.clicked.connect(self.Clear) + + #a, b + text6 = QtWidgets.QLabel(self) + text6.setText("a = ") + text6.setGeometry(10, 130, 30, 30) + self.line_edit4 = QLineEdit(self) + self.line_edit4.setGeometry(40, 130, 60, 30) + self.line_edit4.setText('-1') + text7 = QtWidgets.QLabel(self) + text7.setText("b = ") + text7.setGeometry(110, 130, 30, 30) + self.line_edit5 = QLineEdit(self) + self.line_edit5.setGeometry(140, 130, 60, 30) + self.line_edit5.setText('1') + + #list of functions + text8 = QtWidgets.QLabel(self) + text8.setText("График") + text8.setGeometry(45, 160, 100, 30) + self.combo_box2 = QComboBox(self) + self.combo_box2.addItem("F(x), S(x)") + self.combo_box2.addItem("F'(x), S'(x)") + self.combo_box2.addItem("F''(x), S''(x)") + self.combo_box2.setGeometry(10, 190, 120, 30) + + def Clear(self): + self.plot_widget.clear() + + def Click(self): + mu1 = (float)(self.line_edit1.text()) + mu2 = (float)(self.line_edit2.text()) + n = (int)(self.line_edit3.text()) + fun_num = self.combo_box.currentIndex() + a = (float)(self.line_edit4.text()) + b = (float)(self.line_edit5.text()) + N = Num*(int)(abs(b-a)) + setSpline(a, b, n, fun_num, mu1, mu2) + x_vals = np.linspace(a, b, N) + if (self.combo_box2.currentIndex() == 0): + s = getApproximation(a, b, N) + f = getF(a, b, N) + error = getError(a, b, N) + elif (self.combo_box2.currentIndex() == 1): + s = getS1(a, b, N) + f = getF1(a, b, N) + error = getDerivativeError(a, b, N) + else : + s = getS2(a, b, N) + f = getF2(a, b, N) + error = getSecondDerivativeError(a, b, N) + self.plot_widget.plot(x_vals, error, pen = 'r') + self.plot_widget.plot(x_vals, s, pen = 'b') + self.plot_widget.plot(x_vals, f, pen = 'g') + self.plot_widget.show() + + self.table2.clearContents() + self.table2.setRowCount(0) + if (self.combo_box2.currentIndex() == 0): + self.table2.setHorizontalHeaderLabels(["x", "F(x)", "S(x)"]) + elif (self.combo_box2.currentIndex() == 1): + self.table2.setHorizontalHeaderLabels(["x", "F'(x)", "S'(x)"]) + else: + self.table2.setHorizontalHeaderLabels(["x", "F''(x)", "S''(x)"]) + + for i in range(N): + self.table2.insertRow(i) + itemx = QTableWidgetItem() + itemx.setData(Qt.DisplayRole, "{:.9f}".format(x_vals[i]) ) + self.table2.setItem(i, 0, itemx) + itemf = QTableWidgetItem() + itemf.setData(Qt.DisplayRole, "{:.9f}".format(f[i]) ) + self.table2.setItem(i, 1, itemf) + items = QTableWidgetItem() + items.setData(Qt.DisplayRole, "{:.9f}".format(s[i]) ) + self.table2.setItem(i, 2, items) + + FreeSome(self.combo_box2.currentIndex()) + + self.table1.clearContents() + self.table1.setRowCount(0) + s = getApproximation(a, b, n) + x_vals = np.linspace(a, b, n) + f = getF(a, b, n) + error = getError(a, b, n) + error1 = getDerivativeError(a, b, n) + error2 = getSecondDerivativeError(a, b, n) + av = getA(n) + bv = getB(n) + cv = getC(n) + dv = getD(n) + for i in range(n): + self.table1.insertRow(i) + item1 = QTableWidgetItem() + item1.setData(Qt.DisplayRole, "{:.9f}".format(x_vals[i]) ) + self.table1.setItem(i, 0, item1) + item2 = QTableWidgetItem() + item2.setData(Qt.DisplayRole, "{:.9f}".format(f[i]) ) + self.table1.setItem(i, 1, item2) + item3 = QTableWidgetItem() + item3.setData(Qt.DisplayRole, "{:.9f}".format(s[i]) ) + self.table1.setItem(i, 2, item3) + item4 = QTableWidgetItem() + item4.setData(Qt.DisplayRole, "{:.9f}".format(av[i]) ) + self.table1.setItem(i, 3, item4) + item5 = QTableWidgetItem() + item5.setData(Qt.DisplayRole, "{:.9f}".format(bv[i]) ) + self.table1.setItem(i, 4, item5) + item6 = QTableWidgetItem() + item6.setData(Qt.DisplayRole, "{:.9f}".format(cv[i]) ) + self.table1.setItem(i, 5, item6) + item7 = QTableWidgetItem() + item7.setData(Qt.DisplayRole, "{:.9f}".format(dv[i]) ) + self.table1.setItem(i, 6, item7) + item8 = QTableWidgetItem() + item8.setData(Qt.DisplayRole, "{:.3e}".format(error[i]) ) + self.table1.setItem(i, 7, item8) + item9 = QTableWidgetItem() + item9.setData(Qt.DisplayRole, "{:.3e}".format(error1[i]) ) + self.table1.setItem(i, 8, item9) + item10 = QTableWidgetItem() + item10.setData(Qt.DisplayRole, "{:.3e}".format(error2[i]) ) + self.table1.setItem(i, 9, item10) + FreeAll() + + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = Window() + window.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/Spline/lib/bin/spline.so b/Spline/lib/bin/spline.so old mode 100644 new mode 100755 index d5865fedf6f324c3a42e400ea7fde8ca794463e7..77f505d5792068e10ac13e21ea3843272de66249 GIT binary patch literal 52880 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 literal 26520 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 diff --git a/Spline/lib/include/TMA.h b/Spline/lib/include/TMA.h index 7e1546a..78d4747 100644 --- a/Spline/lib/include/TMA.h +++ b/Spline/lib/include/TMA.h @@ -46,7 +46,7 @@ void TMA::run(std::pair boundaries, std::vector f) { // Reverse running v[n] = mu2; for (size_t i = n - 1; i > 0; i--) { - v[i] = alpha[i] * v[i] + beta[i]; + v[i] = alpha[i] * v[i + 1] + beta[i]; } v[0] = mu1; } diff --git a/Spline/lib/include/spline.h b/Spline/lib/include/spline.h index b88a06e..3d753d5 100644 --- a/Spline/lib/include/spline.h +++ b/Spline/lib/include/spline.h @@ -7,6 +7,7 @@ #include #include #include +#include // class spline { // private: @@ -60,22 +61,104 @@ class spline { } public: - spline(FP l, FP r, size_t n, std::function f, FP mu1 = 0, FP mu2 = 0): l(l), r(r), n(n), f(f), mu1(mu1), mu2(mu2) { + spline(FP l, FP r, size_t n, std::function f, std::function f1, std::function f2, FP mu1 = 0, FP mu2 = 0): + l(l), r(r), n(n), f(f), f1(f1), f2(f2), mu1(mu1), mu2(mu2) { h = (r - l) / static_cast(n); set_vectors(); } spline() = default; - // Constructors with different order of arguments. All delegates to basic one - spline(std::function f, FP l, FP r, size_t n, FP mu1 = 0, FP mu2 = 0): spline(l, r, n, f, mu1, mu2) {} - spline(std::pair boundaries, size_t n, std::function f, std::pair mu): spline(boundaries.first, boundaries.second, n, f, mu.first, mu.second) {} - spline(std::function f, std::pair boundaries, size_t n, std::pair mu): spline(boundaries.first, boundaries.second, n, f, mu.first, mu.second) {} public: // Main function of this class. Return appoximated value at x FP operator()(FP x) { - return 3.14; + FP x_left, x_right; + for (int i = 0; i < n; i++) { + x_left = l + (FP)(i) * h; + x_right = l + (FP)(i + 1) * h; + if (x >= x_left && x <= x_right) + return a[i + 1] + b[i + 1] * (x - x_right) + c[i + 1] / 2.0 * pow((x - x_right), 2.0) + d[i + 1] / 6.0 * pow((x - x_right), 3.0); + } + return 0.0; + } + FP get_a(int i) { + return a[i]; + } + FP get_b(int i) { + return b[i]; + } + FP get_c(int i) { + return c[i]; + } + FP get_d(int i) { + return d[i]; + } + + FP get_f(FP i){ + return f(i); } + + FP get_f1(FP i){ + return f1(i); + } + + FP get_f2(FP i){ + return f2(i); + } + + FP get_s1(FP x){ + FP x_left, x_right; + for (size_t i = 0; i < n; i++) { + x_left = l + static_cast(i) * h; + x_right = l + static_cast(i + 1) * h; + if (x >= x_left && x <= x_right) + return (b[i + 1] + c[i + 1] * (x - x_right) + d[i + 1] / 2.0 * pow((x - x_right), 2.0)); + } + return 0.0; + } + + FP get_s2(FP x){ + FP x_left, x_right; + for (size_t i = 0; i < n; i++) { + x_left = l + static_cast(i) * h; + x_right = l + static_cast(i + 1) * h; + if (x >= x_left && x <= x_right) + return (c[i + 1] + d[i + 1] * (x - x_right)); + } + return 0.0; + } + + FP error(FP x) { + FP x_left, x_right; + for (size_t i = 0; i < n; i++) { + x_left = l + static_cast(i) * h; + x_right = l + static_cast(i + 1) * h; + if (x >= x_left && x <= x_right) + return fabs(f(x) - (a[i + 1] + b[i + 1] * (x - x_right) + c[i + 1] / 2.0 * pow((x - x_right), 2.0) + d[i + 1] / 6.0 * pow((x - x_right), 3.0))); + } + return 0.0; + } + FP derivative_error(FP x) { + FP x_left, x_right; + for (size_t i = 0; i < n; i++) { + x_left = l + static_cast(i) * h; + x_right = l + static_cast(i + 1) * h; + if (x >= x_left && x <= x_right) + return fabs(f1(x) - (b[i + 1] + c[i + 1] * (x - x_right) + d[i + 1] / 2.0 * pow((x - x_right), 2.0))); + } + return 0.0; + } + FP second_derivative_error(FP x) { + FP x_left, x_right; + for (size_t i = 0; i < n; i++) { + x_left = l + static_cast(i) * h; + x_right = l + static_cast(i + 1) * h; + if (x >= x_left && x <= x_right) + return fabs(f2(x) - (c[i + 1] + d[i + 1] * (x - x_right))); + } + return 0.0; + } + void show_vectors() { for (FP el : a) { std::cout << el << ", "; @@ -99,6 +182,8 @@ class spline { FP l, r; // Range size_t n; std::function f; + std::function f1; + std::function f2; FP mu1, mu2; // Values of second derivative FP h; std::vector a, b, c, d; // Vectors of coeffs for polynoms diff --git a/Spline/lib/src/compile.sh b/Spline/lib/src/compile.sh index 787be46..4ddfd78 100644 --- a/Spline/lib/src/compile.sh +++ b/Spline/lib/src/compile.sh @@ -1 +1 @@ -g++ TMA.cpp utility.cpp -std=c++17 -I/../include -O2 -o ../bin/spline.so \ No newline at end of file +g++ -fPIC -shared utility.cpp -std=c++17 -I/../include -O2 -o ../bin/spline.so \ No newline at end of file diff --git a/Spline/lib/src/sample.cpp b/Spline/lib/src/sample.cpp index cfe4f3e..ff393d6 100644 --- a/Spline/lib/src/sample.cpp +++ b/Spline/lib/src/sample.cpp @@ -3,11 +3,11 @@ int main() { - std::function sample_1 = [](FP x) { return sin(exp(x)); }; + // std::function sample_1 = [](FP x) { return sin(exp(x)); }; - spline spline_1(0.5, 2.0, 4, sample_1); + // spline spline_1(0.5, 2.0, 4, sample_1); - spline_1.show_vectors(); + // spline_1.show_vectors(); return 0; } diff --git a/Spline/lib/src/utility.cpp b/Spline/lib/src/utility.cpp index 0a06af7..2989978 100644 --- a/Spline/lib/src/utility.cpp +++ b/Spline/lib/src/utility.cpp @@ -3,24 +3,226 @@ static FP l, r; static size_t function_num; static spline s; +static FP* approximation; +static FP* f; +static FP* f1; +static FP* f2; +static FP* s1; +static FP* s2; +static FP* ai; +static FP* bi; +static FP* ci; +static FP* di; +static FP* error; +static FP* derivative_error; +static FP* second_derivative_error; -std::array, 4> functions { - [](FP x){return x;}, - [](FP x){return x;}, - [](FP x){return x;}, - [](FP x){return x;} + +std::array, 5> functions { + [](FP x) { + if (-1.0 <= x && x < 0.0) + return pow(x, 3.0) + 3.0 * pow(x, 2.0); + if (0.0 <= x && x <= 1.0) + return -pow(x, 3.0) + 3.0 * pow(x, 2.0); + }, + [](FP x) {return sin(exp(x)); }, + [](FP x) {return sin(cos(x)); }, + [](FP x) {return sin(x) / x; }, + [](FP x) {return exp(x - 3); } +}; + +std::array, 5> derivatives{ + [](FP x) { + if (-1.0 <= x && x < 0.0) + return 3.0 * pow(x, 2.0) + 6.0 * x; + if (0.0 <= x && x <= 1.0) + return -3.0 * pow(x, 2.0) + 6.0 * x; + }, + [](FP x) {return exp(x) * cos(exp(x)); }, + [](FP x) {return -sin(x) * cos(cos(x)); }, + [](FP x) {return -(sin(x) - x * cos(x)) / (x * x); }, + [](FP x) {return exp(x - 3); } +}; + +std::array, 5> second_derivatives{ + [](FP x) { + if (-1.0 <= x && x < 0.0) + return 6.0 * x + 6.0; + if (0.0 <= x && x <= 1.0) + return -6.0 * x + 6.0; + }, + [](FP x) {return exp(x) * cos(exp(x)) - exp(2.0 * x) * sin(exp(x)); }, + [](FP x) {return -pow(sin(x), 2.0) * sin(cos(x)) - cos(x) * cos(cos(x)); }, + [](FP x) {return -((x * x - 2) * sin(x) + 2.0 * x * cos(x)) / (x * x * x); }, + [](FP x) {return exp(x - 3); } }; extern "C" void set_spline(FP l, FP r, uint32_t n, uint8_t fun_num, FP mu1 = 0, FP mu2 = 0) { - s = spline(l, r, n, functions[fun_num], mu1, mu2); + s = spline(l, r, n, functions[fun_num], derivatives[fun_num], second_derivatives[fun_num], mu1, mu2); } extern "C" FP* get_approximation(FP a, FP b, uint32_t n) { - FP* approximation = (FP*)malloc(n * sizeof(FP)); + approximation = (FP*)malloc(n * sizeof(FP)); FP h = (b - a) / static_cast(n); for (size_t i = 0; i < n; ++i) approximation[i] = s(a + i*h); - return approximation; // Memory leak -} \ No newline at end of file + return approximation; +} + +extern "C" FP* get_f(FP a, FP b, uint32_t n) { + f = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 0; i < n; ++i) + f[i] = s.get_f(a + i*h); + + return f; +} + +extern "C" FP* get_f1(FP a, FP b, uint32_t n) { + f1 = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 0; i < n; ++i) + f1[i] = s.get_f1(a + i*h); + + return f1; +} + +extern "C" FP* get_f2(FP a, FP b, uint32_t n) { + f2 = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 0; i < n; ++i) + f2[i] = s.get_f2(a + i*h); + + return f2; +} + +extern "C" FP* get_s1(FP a, FP b, uint32_t n) { + s1 = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 0; i < n; ++i) + s1[i] = s.get_s1(a + i*h); + + return s1; +} + +extern "C" FP* get_s2(FP a, FP b, uint32_t n) { + s2 = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 0; i < n; ++i) + s2[i] = s.get_s2(a + i*h); + + return s2; +} + + +extern "C" FP * get_a(uint32_t n) +{ + ai = (FP*)malloc(n * sizeof(FP)); + + for (size_t i = 1; i <= n; ++i) + ai[i - 1] = s.get_a(i); + + return ai; +} + +extern "C" FP * get_b(uint32_t n) +{ + bi = (FP*)malloc(n * sizeof(FP)); + + for (size_t i = 1; i <= n; ++i) + bi[i - 1] = s.get_b(i); + + return bi; +} + +extern "C" FP * get_c(uint32_t n) +{ + ci = (FP*)malloc(n * sizeof(FP)); + + for (size_t i = 1; i <= n; ++i) + ci[i - 1] = s.get_c(i); + + return ci; +} + +extern "C" FP * get_d( uint32_t n) +{ + di = (FP*)malloc(n * sizeof(FP)); + + for (size_t i = 1; i <= n; ++i) + di[i - 1] = s.get_d(i); + + return di; +} + +extern "C" FP* get_error(FP a, FP b, uint32_t n) { + error = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 1; i <= n; ++i) + error[i - 1] = s.error(a + i * h); + + return error; +} + +extern "C" FP* get_derivative_error(FP a, FP b, uint32_t n) { + derivative_error = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 1; i <= n; ++i) + derivative_error[i - 1] = s.derivative_error(a + i * h); + + return derivative_error; +} + +extern "C" FP* get_second_derivative_error(FP a, FP b, uint32_t n) { + second_derivative_error = (FP*)malloc(n * sizeof(FP)); + FP h = (b - a) / static_cast(n); + + for (size_t i = 1; i <= n; ++i) + second_derivative_error[i - 1] = s.second_derivative_error(a + i * h); + + return second_derivative_error; +} + +extern "C" void free_all() { + free(approximation); + free(f); + free(f1); + free(f2); + free(s1); + free(s2); + free(ai); + free(bi); + free(ci); + free(di); + free(error); + free(derivative_error); + free(second_derivative_error); +} + +extern "C" void free_some(uint8_t i) { + if (i == 0){ + free(approximation); + free(f); + free(error); + }else if (i == 1){ + free(f1); + free(s1); + free(derivative_error); + }else{ + free(f2); + free(s2); + free(second_derivative_error); + } + + + +} From 849d64eb3ca19e4fe3b1793ebfa8121254463baf Mon Sep 17 00:00:00 2001 From: root Date: Sun, 24 Mar 2024 12:02:46 +0300 Subject: [PATCH 2/3] Interface0 --- Spline/Interface.py | 2 +- Spline/lib/include/TMA.h | 2 +- Spline/lib/include/root.h | 2 +- Spline/lib/include/spline.h | 2 +- Spline/lib/src/TMA.cpp | 2 +- Spline/lib/src/sample.cpp | 2 +- Spline/lib/src/utility.cpp | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Spline/Interface.py b/Spline/Interface.py index ff15665..0eb1d9f 100644 --- a/Spline/Interface.py +++ b/Spline/Interface.py @@ -295,7 +295,7 @@ def Click(self): item10 = QTableWidgetItem() item10.setData(Qt.DisplayRole, "{:.3e}".format(error2[i]) ) self.table1.setItem(i, 9, item10) - FreeAll() + FreeAll() diff --git a/Spline/lib/include/TMA.h b/Spline/lib/include/TMA.h index 78d4747..cdd22cb 100644 --- a/Spline/lib/include/TMA.h +++ b/Spline/lib/include/TMA.h @@ -2,7 +2,7 @@ #define __TMA__ #include "root.h" - + class TMA { private: std::vector v; // Numerical solution diff --git a/Spline/lib/include/root.h b/Spline/lib/include/root.h index d9317f4..172205f 100644 --- a/Spline/lib/include/root.h +++ b/Spline/lib/include/root.h @@ -1,6 +1,6 @@ #ifndef __ROOT__ #define __ROOT__ - + #include #include #include diff --git a/Spline/lib/include/spline.h b/Spline/lib/include/spline.h index 3d753d5..279ecc2 100644 --- a/Spline/lib/include/spline.h +++ b/Spline/lib/include/spline.h @@ -96,7 +96,7 @@ class spline { FP get_f(FP i){ return f(i); - } + } FP get_f1(FP i){ return f1(i); diff --git a/Spline/lib/src/TMA.cpp b/Spline/lib/src/TMA.cpp index 642a291..2d5dc09 100644 --- a/Spline/lib/src/TMA.cpp +++ b/Spline/lib/src/TMA.cpp @@ -1 +1 @@ -#include "../include/TMA.h" \ No newline at end of file +#include "../include/TMA.h" \ No newline at end of file diff --git a/Spline/lib/src/sample.cpp b/Spline/lib/src/sample.cpp index ff393d6..8169de0 100644 --- a/Spline/lib/src/sample.cpp +++ b/Spline/lib/src/sample.cpp @@ -7,7 +7,7 @@ int main() { // spline spline_1(0.5, 2.0, 4, sample_1); - // spline_1.show_vectors(); + // spline_1.show_vectors(); return 0; } diff --git a/Spline/lib/src/utility.cpp b/Spline/lib/src/utility.cpp index 2989978..f0b45ad 100644 --- a/Spline/lib/src/utility.cpp +++ b/Spline/lib/src/utility.cpp @@ -1,7 +1,7 @@ #include "../include/spline.h" static FP l, r; -static size_t function_num; +static size_t function_num; static spline s; static FP* approximation; static FP* f; From bc5defd39ce01320c097e8564a8dfee5f19f8528 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 25 Mar 2024 14:43:45 +0300 Subject: [PATCH 3/3] Maxs --- Spline/Interface.py | 51 ++++++++++++++++++++++++++++++++++++- Spline/lib/bin/spline.so | Bin 52880 -> 52880 bytes Spline/lib/src/utility.cpp | 4 --- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Spline/Interface.py b/Spline/Interface.py index 0eb1d9f..289bfc7 100644 --- a/Spline/Interface.py +++ b/Spline/Interface.py @@ -116,7 +116,7 @@ def __init__(self): #making tables self.table1 = QTableWidget(self) - self.table1.setGeometry(0, 400, 450, 600) + self.table1.setGeometry(0, 350, 450, 650) self.table1.setColumnCount(10) self.table1.setHorizontalHeaderLabels(["x", "F(x)", "S(x)","a", "b", "c", "d", "|f(x) - S(x)|", "|f'(x) - S'(x)|", "|f''(x) - S''(x)|"]) @@ -197,6 +197,46 @@ def __init__(self): self.combo_box2.addItem("F'(x), S'(x)") self.combo_box2.addItem("F''(x), S''(x)") self.combo_box2.setGeometry(10, 190, 120, 30) + + #maxs + text9 = QtWidgets.QLabel(self) + text9.setText("max |F(x) - S(x)| = ") + text9.setGeometry(10, 230, 120, 30) + self.text9_1 = QtWidgets.QLabel(self) + self.text9_1.setStyleSheet('background-color: white;') + self.text9_1.setGeometry(130, 230, 120, 30) + text9_2 = QtWidgets.QLabel(self) + text9_2.setText(" в x =") + text9_2.setGeometry(260, 230, 40, 30) + self.text9_3 = QtWidgets.QLabel(self) + self.text9_3.setStyleSheet('background-color: white;') + self.text9_3.setGeometry(310, 230, 100, 30) + + text10 = QtWidgets.QLabel(self) + text10.setText("max |F'(x) - S'(x)| = ") + text10.setGeometry(10, 270, 120, 30) + self.text10_1 = QtWidgets.QLabel(self) + self.text10_1.setStyleSheet('background-color: white;') + self.text10_1.setGeometry(135, 270, 120, 30) + text10_2 = QtWidgets.QLabel(self) + text10_2.setText(" в x =") + text10_2.setGeometry(265, 270, 40, 30) + self.text10_3 = QtWidgets.QLabel(self) + self.text10_3.setStyleSheet('background-color: white;') + self.text10_3.setGeometry(315, 270, 100, 30) + + text11 = QtWidgets.QLabel(self) + text11.setText("max |F''(x) - S''(x)| = ") + text11.setGeometry(10, 310, 130, 30) + self.text11_1 = QtWidgets.QLabel(self) + self.text11_1.setStyleSheet('background-color: white;') + self.text11_1.setGeometry(140, 310, 120, 30) + text11_2 = QtWidgets.QLabel(self) + text11_2.setText(" в x =") + text11_2.setGeometry(270, 310, 40, 30) + self.text11_3 = QtWidgets.QLabel(self) + self.text11_3.setStyleSheet('background-color: white;') + self.text11_3.setGeometry(320, 310, 100, 30) def Clear(self): self.plot_widget.clear() @@ -259,6 +299,15 @@ def Click(self): error = getError(a, b, n) error1 = getDerivativeError(a, b, n) error2 = getSecondDerivativeError(a, b, n) + max_ind0 = error.index(max(error)) + max_ind1 = error1.index(max(error1)) + max_ind2 = error2.index(max(error2)) + self.text9_1.setText("{:.3e}".format(error[max_ind0])) + self.text9_3.setText("{:.9f}".format(x_vals[max_ind0])) + self.text10_1.setText("{:.3e}".format(error1[max_ind1])) + self.text10_3.setText("{:.9f}".format(x_vals[max_ind1])) + self.text11_1.setText("{:.3e}".format(error2[max_ind2])) + self.text11_3.setText("{:.9f}".format(x_vals[max_ind2])) av = getA(n) bv = getB(n) cv = getC(n) diff --git a/Spline/lib/bin/spline.so b/Spline/lib/bin/spline.so index 77f505d5792068e10ac13e21ea3843272de66249..34ddbeef20b9ea1de9054fb36059dc4c9e666b58 100755 GIT binary patch delta 4069 zcmZ`+4OCQR8ouAi=#0S3CBb0;`EiG<1=PF~MkKWpKw`wA?^J@Q)t_9S8+G?1BZ! zI4Iy-ZSJuR_Lw3{!j5&eqwN8;!oLm53|e#1GKZujD^~mQ?(^L{cx?9UJqL^elv`tnTqozkLH|S5biN zUii;`ajb<-`sGrlzetJxk;YN4>pVX}3ENGj{$^-fac-i1e*+R8_D^Fe6t6R2-_mtv zYSW2SuZvXmU3xQgCt-^eAf{novqZDevO&o$%9G-!8fCp2 zY84Hv)AgqKaoXZtO9jCl_=O}{oym3F)+lx|Rzx=a!X$Nz0zY zl4whIng8GwN%}?~{=L=l_Hf6}oCH=tvvTrP!Xo-hP6#w_<~+u3(oZ?TESIJ(Pf>+u zxH6Z|Qn5c$W8RFAiH{4y4Sj(6tHm6}T2mWR<-`^0%UdwD9kkV{c5!e79h65w9b{P% zuHAtFbQ=~^*UC^TTd~A2O%dO#h$9qndVx*GK?ZtE}7c2NRGUVgCl6C zJPIP(wlZ8(jsYSsfi`+g0r$LHYqBt<7UU#@F|axlmdTUVsq*AnQzBTNdKkvCERxF{ z>R69I#pCxG_s1yyz(w@%s_@wtGN7)L$~D&eZo8lSH?N;sla))H$wS53rz}%drwiS?5sO z?hae+30tXzP4tB2Ls{-jNKnFtdji&Y0&zr*_2g=oGDQ!dhh z)uD68KH-;g)FfXDe4^EPSV57=hPE{dE#8Y~FIz8_0cew;o+ z`TuR=NusbO-q2^O`?&ww;Q#e^a{p;MRurv@9-!eOlYb+`@^fbFBjo&jQ5ZW`6tj-TfGP!8>5au1)! z2IymYAxt%Cc-B|xo#ObA7r=X^=-vX(-9P~)p?H9gvJV#g>88i~e|4Gyz(n}=~hS!xWp5W{946@$GFX$EeXUViFTfBUtdIQ}q zX;#fVN6qVvs(a4S!S%+l|9rsf`bZOMpO?Je>U6bm8-;s;F0FqN1yQ-7m=)5M4Rcuo zMcIQ4zkgqn(w#{ruJ=!OmYYPbw$nm;82gmg+T&Rl?Y7@P@r{05>>@g2Kf?~wuF|ln zlR#WMB)>Ooj$<~*n9cE?`xu=rHLHZU@}f?MJ$itIhGb`#K*w-T}iO-tM70Lw;fIe#(AokX6vE z^119^R93!H&t;RN?Is-+Xh#W?N zKLS(m1R2r_Lf@y7l&8YP&m^fFXaUv(^MJd7O~6iIH}C{-6gU8k#M^xYm;n^<)l~xw z1a<;rfJ49}p!m5YWlRvNg%lX8LD+$nz!qQwup8I{90DE&3Rfkm7ia+v0W*L%fp(zi z10661Xm=wpP{fByAutbE1?&bs&-pJT=^!uzc*18cGJ`R|iEEM+jBnZ&U@9u4+c~-;ocQ1~=ozHo34d6z-xE64J zs1!T`<%93QVQ|4-TrW72!l9?Yf#;%d0i=aWpEEEkwLUjR?Z?Xomcf__X)%{sbrw~w zPGf?Z1aBwxKR3e|j8fY*?yc8p_@Y(twot&^us%ONzyp!buA!&{ydNq$koG_A-jJW7 zLCVYm_V6uKdeDG(v*V!IIFzmU>hSF1 z#~w6^JU29?2h)t5>lF4;1%#(jGu#_V@g4l?R&*H9LT~OcQ)P#!ef*yBoO?P9#?caG zQo3jEX^*#tzQ!yIXZ|ar5WBV=+8e?qQ2Z&gw$^j+YF$OA HX88OU6``d$ delta 4131 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 diff --git a/Spline/lib/src/utility.cpp b/Spline/lib/src/utility.cpp index f0b45ad..a0b1fd4 100644 --- a/Spline/lib/src/utility.cpp +++ b/Spline/lib/src/utility.cpp @@ -195,10 +195,6 @@ extern "C" FP* get_second_derivative_error(FP a, FP b, uint32_t n) { extern "C" void free_all() { free(approximation); free(f); - free(f1); - free(f2); - free(s1); - free(s2); free(ai); free(bi); free(ci);