#include #include "hdnum.hh" // hdnum header template void solveTriDiag(hdnum::DenseMatrix &A, std::vector &x, std::vector &b) { int N = b.size(); x[0] = A[0][0]; // LU Zerlegung REAL l; for (int j=1; j=0; j--) { x[j] = (b[j] - A[j][j+1]*x[j+1])/x[j]; } } template class CubicSpline { public: // erstelle einen kubischen spline mit vorgegebenen stuetzstellen // und werten CubicSpline(std::vector xs, std::vector ys) { calculateCoefficients(xs, ys); } // erstelle einen kubischen spline mit vorgegebenen stuetzstellen // und einer zu interpolierenden funktion CubicSpline(std::vector xs, REAL(*f)(REAL)) { int N = xs.size(); std::vector ys(N); for (int i=0; i xs(N+1); std::vector ys(N+1); for (int i=0; i<=N; i++) { xs[i] = a + (1.0*i)/N*(b-a); ys[i] = f(xs[i]); } calculateCoefficients(xs, ys); } // werte kubischen spline an vorgegebener stelle aus REAL evaluate(REAL x) { for (int i=1; i x_s[i] && i < x_s.size() - 1) { continue; } else { return a_0[i-1] + a_1[i-1] *(x - x_s[i]) + a_2[i-1]*std::pow(x - x_s[i], 2) + a_3[i-1]*std::pow(x-x_s[i], 3); } } return 0; } // gebe alle interpolations polynome aus void print() { for(int i=0; i x_s; // koeffizienten std::vector a_0; std::vector a_1; std::vector a_2; std::vector a_3; void calculateCoefficients(std::vector xs, std::vector ys) { // stuetzstellen from x_0 ... to x_n int n = xs.size()-1; // copy stuetzstellen x_s = std::vector(n+1); x_s = xs; // setup (n-1)x(n-1) matrix for a_2 hdnum::DenseMatrix A(n-1,n-1); std::vector b(n-1); std::vector x(n-1); REAL h; // h_i REAL h1; // h_{i+1} // setup LGS for a_2 // A has tridiagonal structure for (int i = 1; i 1) { A[i-1][i-2] = h; } if (i < n-1) { A[i-1][i] = h1; } A[i-1][i-1] = 2 * (h + h1); } // initialize vectors a_0 = std::vector(n); a_1 = std::vector(n); a_2 = std::vector(n); a_3 = std::vector(n); solveTriDiag(A,a_2,b); // natuerliche randbedingung a_2[n-1] = 0; // berechne restliche koeffizienten for (int i = 1; i<=n; i++) { h = xs[i] - xs[i-1]; // h_i h1 = xs[i+1] - xs[i]; // h_{i+1} a_0[i-1] = ys[i]; if (i == 1) { // a_2[-1] = 0 a_1[i-1] = (ys[i] - ys[i-1])/h + (h/3)*(2*a_2[i-1]); a_3[i-1] = (a_2[i-1])/(3*h); } else { a_1[i-1] = (ys[i] - ys[i-1])/h + h/3*(2*a_2[i-1] + a_2[i-2]); a_3[i-1] = (a_2[i-1] - a_2[i-2])/(3 * h); } } } }; double f1(double x) { return std::pow(x,3); } int main() { // std::vector xs = {0, 1, 2}; // CubicSpline phi(xs, f1); // phi.print(); // saurier fundstellen std::vector xs = {3.75, 3.75, 2.25, 1.25, 0.25, 0.75, 4.00, 5.50, 6.25, 9.00, 12.5, 12.75, 12.25}; std::vector ys = {0.25, 1.50, 3.25, 4.25, 4.65, 4.83, 2.50, 3.25, 3.65, 3.00, 1.25, 2.150, 3.500}; std::vector ts(13); ts[0] = 0; for (int i = 1; i<=12; i++) { ts[i] = ts[i-1] + std::sqrt(std::pow(xs[i] - xs[i-1], 2) + std::pow(ys[i] - ys[i-1], 2)); } CubicSpline phi(ts, xs); CubicSpline psi(ts, ys); double xi; for (int j = 0; j<=100; j++) { xi = j*ts[12] / 100; std::cout << phi.evaluate(xi) << " " << psi.evaluate(xi) << std::endl; } }