diff --git a/Spline/Interface.py b/Spline/Interface.py index 2ebeb76..289bfc7 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,313 @@ 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, 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)|"]) + + 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) + + #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() + + 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) + 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) + 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 d5865fe..34ddbee Binary files a/Spline/lib/bin/spline.so and b/Spline/lib/bin/spline.so differ diff --git a/Spline/lib/include/TMA.h b/Spline/lib/include/TMA.h index 7e1546a..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 @@ -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/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 b88a06e..279ecc2 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/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/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..8169de0 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..a0b1fd4 100644 --- a/Spline/lib/src/utility.cpp +++ b/Spline/lib/src/utility.cpp @@ -1,26 +1,224 @@ #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; +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(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); + } + + + +}