Ladies_Man

cubic spline accepted

Jun 14th, 2016
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.07 KB | None | 0 0
  1. #include <iostream>
  2. #include <math.h>
  3. #include "stdio.h"
  4.  
  5. using namespace std;
  6.  
  7. #define xtype double
  8. #define N 10
  9.  
  10. xtype _a = 2.477520;
  11. xtype _b = 0.232206;
  12.  
  13.  
  14. xtype xs[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5};
  15. xtype ys[] = {2.78, 3.13, 3.51, 3.94, 4.43, 4.97, 5.58, 6.27, 7.04, 7.91, 8.89};
  16.  
  17. xtype xsNew[] = {0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00, 2.25, 2.50, 2.75, 3.00, 3.25, 3.50, 3.75, 4.00, 4.25, 4.50, 4.75, 5.00, 5.25, 5.50};
  18. xtype ysNew[] = {2.78, 2.95, 3.13, 3.31, 3.51, 3.72, 3.94, 4.18, 4.43, 4.69, 4.97, 5.27, 5.58, 5.92, 6.27, 6.65, 7.04, 7.47, 7.91, 8.38, 8.89};
  19.  
  20. xtype f(xtype x) { return _a * exp(_b*x); }
  21.  
  22. typedef struct spline {
  23.     xtype a[N];
  24.     xtype b[N];
  25.     xtype c[N];
  26.     xtype d[N];
  27. } _spline;
  28.  
  29. void solveMatrix(int n, xtype* a, xtype* b, xtype* c, xtype* d, xtype* x) {
  30.  
  31.     int i;
  32.     xtype alpha[n], beta[n];
  33.     alpha[0] = -c[0] / b[0];
  34.     beta[0] = d[0] / b[0];
  35.  
  36.     for (i = 1; i < n-1; ++i) {
  37.         alpha[i] = (-c[i]) / (a[i] * alpha[i-1] + b[i]);
  38.         beta[i] = (d[i] - a[i] * beta[i-1]) / (a[i] * alpha[i-1] + b[i]);
  39.     }
  40.  
  41.     beta[n-1] = (d[n-1]-a[n-1] * beta[n-2]) / (a[n-1] * alpha[n-2] + b[n-1]);
  42.     x[n-1] = beta[n-1];
  43.  
  44.     for (i = n-2; i >= 0; --i) {
  45.         x[i] = alpha[i] * x[i+1] + beta[i];
  46.     }
  47. }
  48.  
  49.  
  50.  
  51.  
  52. _spline populateSpline(int n) {
  53.  
  54.     xtype ak[n-3], bk[n-2], ck[n-3], dk[n-2], ek[n];
  55.     xtype a[n], b[n], c[n], d[n];
  56.  
  57.     xtype h = xs[1] - xs[0];
  58.  
  59.     for (int i = 0; i < n - 2; i++) {
  60.  
  61.         if (i < n-3)
  62.             ak[i] = ck[i] = 1;
  63.  
  64.         bk[i] = 4;
  65.         dk[i] = 3 / (h * h) * (ys[i+2] - 2*ys[i+1] + ys[i]);
  66.     }
  67.  
  68.     solveMatrix(n-2, ak, bk, ck, dk, ek);
  69.  
  70.  
  71.     c[0] = c[n-1] = 0;
  72.     for (int i = 1; i < n-1; i++)
  73.         c[i] = ek[i-1];
  74.  
  75.     for (int i = 0; i < n-1; i++) {
  76.         a[i] = ys[i];
  77.         b[i] = (ys[i+1] - ys[i]) / h - (h/3) * (c[i+1] + 2*c[i]);
  78.         d[i] = (c[i+1] - c[i]) / (3*h);
  79.     }
  80.  
  81.  
  82.     _spline spZ;
  83.  
  84.     for (int i = 0; i < n; i++) {
  85.         spZ.a[i] = a[i];
  86.         spZ.b[i] = b[i];
  87.         spZ.c[i] = c[i];
  88.         spZ.d[i] = d[i];
  89.     }
  90.     return spZ;
  91. }
  92.  
  93. xtype countSplineAt(_spline spline, xtype x) {
  94.  
  95.     //S_j[x] = a_j + b_j(x-xj) + c_j(x-xj)^2 + d_j(x-xj)^3
  96.     int i;
  97.     for (i = 0; i < N; ++i)
  98.         if (x >= xs[i] && x <= xs[i+1])
  99.             break;
  100.  
  101.     if (N == i) i--;
  102.  
  103.     //printf("cSA: %.6f\n", xsNew[i]);
  104.     //printf("[%d] %.6f %.6f \n",i, x, xsNew[i]);
  105.  
  106.     return  spline.a[i] +
  107.             spline.b[i]*(x - xs[i]) +
  108.             spline.c[i]*(x - xs[i])*(x - xs[i]) +
  109.             spline.d[i]*(x - xs[i])*(x - xs[i])*(x - xs[i]);
  110. }
  111.  
  112. int main()
  113. {
  114.     int i;
  115.  
  116.     /*xsNew[0] = 0.25;
  117.     ysNew[0] = f(xsNew[0]);
  118.  
  119.     printf("[0](%.2f, %f)\n", xsNew[0], ysNew[0]);
  120.  
  121.     for (i = 1; i < 2*N; i++) {
  122.  
  123.         xsNew[i] = xsNew[i-1] + 0.25;
  124.         ysNew[i] = f(xsNew[i]);
  125.  
  126.         printf("[%d](%.2f, %f)\n", i, xsNew[i], ysNew[i]);
  127.     }*/
  128.  
  129.  
  130.     printf("populating spline\n");
  131.     _spline sp = populateSpline(N+1);
  132.  
  133.  
  134.  
  135.     for (i = 0; i <= 2*N; i++) {
  136.  
  137.         //printf("in: %.6f\n", xsNew[i]);
  138.         xtype sVal = countSplineAt(sp, xsNew[i]);
  139.  
  140.         //xtype sValMid = countSplineAt(sp, xsNew[i] + 0.125);
  141.  
  142.         printf("x[%d]=%.6f y[%d]=%.6f s[%d]=%.6f d=%.6f\n",
  143.                i, xsNew[i], i, ysNew[i], i, sVal, fabs(ysNew[i] - sVal));
  144.         //printf("x[%d]=%.6f                s[%d]=%.6f\n",
  145.         //        i, xsNew[i] + 0.125, i, sValMid);
  146.  
  147.         //printf ("(%.3f; %.3f) ", xsNew[i], sVal);
  148.         //printf ("(%.3f; %.3f) ", xsNew[i] + 0.125, sValMid);
  149.     }
  150.  
  151.     return 0;
  152. }
  153.  
  154.  
  155.  
  156. /*
  157. xtype nFunc(int n, int i, xtype x) {
  158.  
  159.     if (x >= xsNew[i] && x <= xsNew[i+1])
  160.         return 1;
  161.     else
  162.         return 0;
  163.  
  164.  
  165.     xtype n1 = nFunc(n-1, i, x) * (x - xsNew[i]) / (xsNew[i+n] - xsNew[i]);
  166.     xtype n2 = nFunc(n-1, i+1, x) * (xsNew[i+n+1] - x) / (xsNew[i+n+1] - xsNew[i+1]);
  167.  
  168.     return n1 + n2;
  169. }
  170.  
  171.  
  172. xtype dFunc(int k, int i, xtype x) {
  173.  
  174.     xtype alpha = (x - xsNew[i]) / (xsNew[i+N*2+1-k] - xsNew[i]);
  175.  
  176.     xtype d1 = dFunc(k-1, i-1, x);
  177.     xtype d2 = dFunc(k-1, i, x);
  178.  
  179.     return (1 - alpha)*d1 + alpha*d2;
  180. }*/
Advertisement
Add Comment
Please, Sign In to add comment