Advertisement
Ladies_Man

fck dat beesplines

Jun 22nd, 2016
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.51 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. xtype h = xs[1] - xs[0];
  23.  
  24. typedef struct spline {
  25.     xtype a[N];
  26.     xtype b[N];
  27.     xtype c[N];
  28.     xtype d[N];
  29. } _spline;
  30.  
  31. typedef struct bispline {
  32.     xtype x[N+3];
  33. } _bispline;
  34.  
  35. void solveMatrix(int n, xtype* a, xtype* b, xtype* c, xtype* d, xtype* x) {
  36.  
  37.     int i;
  38.     xtype alpha[n], beta[n];
  39.     alpha[0] = -c[0] / b[0];
  40.     beta[0] = d[0] / b[0];
  41.  
  42.     for (i = 1; i < n-1; ++i) {
  43.         alpha[i] = (-c[i]) / (a[i] * alpha[i-1] + b[i]);
  44.         beta[i] = (d[i] - a[i] * beta[i-1]) / (a[i] * alpha[i-1] + b[i]);
  45.     }
  46.  
  47.     beta[n-1] = (d[n-1]-a[n-1] * beta[n-2]) / (a[n-1] * alpha[n-2] + b[n-1]);
  48.     x[n-1] = beta[n-1];
  49.  
  50.     for (i = n-2; i >= 0; --i) {
  51.         x[i] = alpha[i] * x[i+1] + beta[i];
  52.     }
  53. }
  54.  
  55. void solveMatrixNew(int len, xtype* a, xtype* b, xtype* c, xtype* d, xtype* x) {
  56.  
  57.     int size = len;
  58.     int n = size - 1;
  59.     int i;
  60.  
  61.     xtype alpha[size], beta[size];
  62.  
  63.     alpha[0] = -c[0] / b[0];
  64.     beta[0] = d[0] / b[0];
  65.  
  66.     for (i = 1; i <= n; i++) {
  67.         alpha[i] = (-c[i]) / (a[i] * alpha[i-1] + b[i]);
  68.         beta[i] = (d[i] - a[i] * beta[i-1]) / (a[i] * alpha[i-1] + b[i]);
  69.     }
  70.  
  71.     //beta[n-1] = (d[n-1]-a[n-1] * beta[n-2]) / (a[n-1] * alpha[n-2] + b[n-1]);
  72.     x[n+1] = beta[n];
  73.  
  74.     for (i = n; i >= 1; i--) {
  75.         x[i] = alpha[i-1] * x[i+1] + beta[i-1];
  76.     }
  77.     x[0] = 2*x[1] - x[2];
  78.     x[n+2] = 2*x[n+1] - x[n];
  79. }
  80.  
  81.  
  82.  
  83.  
  84. _spline populateSpline(int n) {
  85.  
  86.     xtype ak[n-3], bk[n-2], ck[n-3], dk[n-2], ek[n];
  87.     xtype a[n], b[n], c[n], d[n];
  88.  
  89.     xtype h = xs[1] - xs[0];
  90.  
  91.     for (int i = 0; i < n - 2; i++) {
  92.  
  93.         if (i < n-3)
  94.             ak[i] = ck[i] = 1;
  95.  
  96.         bk[i] = 4;
  97.         dk[i] = 3 / (h * h) * (ys[i+2] - 2*ys[i+1] + ys[i]);
  98.     }
  99.  
  100.     solveMatrix(n-2, ak, bk, ck, dk, ek);
  101.  
  102.  
  103.     c[0] = c[n-1] = 0;
  104.     for (int i = 1; i < n-1; i++)
  105.         c[i] = ek[i-1];
  106.  
  107.     for (int i = 0; i < n-1; i++) {
  108.         a[i] = ys[i];
  109.         b[i] = (ys[i+1] - ys[i]) / h - (h/3) * (c[i+1] + 2*c[i]);
  110.         d[i] = (c[i+1] - c[i]) / (3*h);
  111.     }
  112.  
  113.  
  114.     _spline spZ;
  115.  
  116.     for (int i = 0; i < n; i++) {
  117.         spZ.a[i] = a[i];
  118.         spZ.b[i] = b[i];
  119.         spZ.c[i] = c[i];
  120.         spZ.d[i] = d[i];
  121.     }
  122.     return spZ;
  123. }
  124.  
  125. xtype countSplineAt(_spline spline, xtype x) {
  126.  
  127.     //S_j[x] = a_j + b_j(x-xj) + c_j(x-xj)^2 + d_j(x-xj)^3
  128.     int i;
  129.     for (i = 0; i < N; ++i)
  130.         if (x >= xs[i] && x <= xs[i+1])
  131.             break;
  132.  
  133.     if (N == i) i--;
  134.  
  135.     //printf("cSA: %.6f\n", xsNew[i]);
  136.     //printf("[%d] %.6f %.6f \n",i, x, xsNew[i]);
  137.  
  138.     return  spline.a[i] +
  139.             spline.b[i]*(x - xs[i]) +
  140.             spline.c[i]*(x - xs[i])*(x - xs[i]) +
  141.             spline.d[i]*(x - xs[i])*(x - xs[i])*(x - xs[i]);
  142. }
  143.  
  144.  
  145. xtype nFunc(int q, int k, xtype t) {
  146.  
  147.     if (1 == q) {
  148.         if (t >= xs[k] && t <= xs[k+1])
  149.             return 1;
  150.         else
  151.             return 0;
  152.     }
  153.  
  154.     xtype n1 = nFunc(q-1, k, t) * (t - xs[k]) / (xs[k+q-1] - xs[k]);
  155.     xtype n2 = nFunc(q-1, k+1, t) * (xs[k+q] - t) / (xs[k+q] - xs[k+1]);
  156.  
  157.     return n1 + n2;
  158. }
  159.  
  160.  
  161.  
  162. bispline populateBiSpline(int len) {
  163.  
  164.     int size = len;
  165.     int n = size - 1;
  166.  
  167.     xtype a[size], b[size], c[size], d[size], e[size+2];
  168.  
  169.     for (int i = 1; i < n; i++) {
  170.         a[i] = 1;
  171.         b[i] = 4;
  172.         c[i] = 1;
  173.         d[i] = 6*ys[i];
  174.     }
  175.  
  176.     a[0] = 0;
  177.     b[0] = 1;
  178.     c[0] = 0;
  179.     d[0] = ys[0];
  180.  
  181.     a[n] = 0;
  182.     b[n] = 1;
  183.     c[n] = 0;
  184.     d[n] = ys[n];
  185.  
  186.     for (int i = 0; i < n; i++) {
  187.         d[i] /= (h*h*h);
  188.     }
  189.  
  190.     solveMatrixNew(len, a, b, c, d, e);
  191.  
  192.  
  193.     _bispline bsp;
  194.  
  195.  
  196.     for (int i = 0; i < size+2; i++)
  197.         bsp.x[i] = e[i];
  198.  
  199.     return bsp;
  200. }
  201.  
  202. xtype baseX(int k, xtype x, xtype kh) {
  203.     if (0 == k) {
  204.  
  205.         xtype xz = xs[0];
  206.  
  207.         if (xz + 2*h <= x) return 0;
  208.         if (xz + h <= x && x < xz + 2*h) return pow(2*h + xz - kh - (x - kh), 3)/6;
  209.         if (xz <= x && x < xz + h)
  210.             return 2*pow(h, 3)/3 - pow(-xz + kh + (x - kh), 2)*(2*h + xz - kh - (x - kh))/2;
  211.         if (xz - h <= x && x < xz)
  212.             return 2*pow(h, 3)/3 - pow(-xz + kh + (x - kh), 2)*(2*h - xz + kh + (x - kh))/2;
  213.         if (xz - 2*h <= x && x < xz - h) return pow(2*h - xz + kh + (x - kh), 3)/6;
  214.         if (x < xz - 2*h) return 0;
  215.  
  216.     } else {
  217.         return baseX(0, x - k*h, -k*h);
  218.     }
  219.  
  220. }
  221.  
  222. xtype countBiSplineAt(_bispline bsp, xtype val) {
  223.  
  224.     int i;
  225.  
  226.     for (i = 0; i < N+2; ++i)
  227.         if (xs[i] <= val && val <= xs[i+1])
  228.             break;
  229.  
  230.     if (N+2 == i) i--;
  231.  
  232.     //printf("%.2f < %.2f < %.2f\n", xs[i], val, xs[i+1]);
  233.     //if (xs[i] <= val && val <= xs[i+1]) {
  234.         return  bsp.x[i + 0] * baseX(i - 1, val, 0) +
  235.                 bsp.x[i + 1] * baseX(i + 0, val, 0) +
  236.                 bsp.x[i + 2] * baseX(i + 1, val, 0) +
  237.                 bsp.x[i + 3] * baseX(i + 2, val, 0);
  238.     /*} else {
  239.         return -1;
  240.     }*/
  241. }
  242.  
  243.  
  244. int main()
  245. {
  246.     printf("populating spline\n");
  247.     _spline sp = populateSpline(N+1);
  248.  
  249.     printf("populating bispline\n");
  250.     _bispline bs = populateBiSpline(N+2);
  251.  
  252.     /*for (int i = 0; i <= 2*N; i++) {
  253.         xtype val = xsNew[i];
  254.         xtype bsVal = countBiSplineAt(bs, val);
  255.  
  256.         printf("[%d] x[i]:%.5f y:%.5f bs:%.5f :%.5f\n",
  257.                 i, val, ysNew[i], bsVal, fabs(ysNew[i] - bsVal));
  258.     }*/
  259.  
  260.     for ( int i = 0; i <= 2*N; i++) {
  261.  
  262.         xtype sVal = countSplineAt(sp, xsNew[i]);
  263.  
  264.         xtype bsVal = countBiSplineAt(bs, xsNew[i]);
  265.  
  266.         printf("x[%d]=%.2f y=%.5f s=%.5f d=%.5f b=%.5f d=%.5f\n",
  267.                i, xsNew[i], ysNew[i], sVal, fabs(ysNew[i] - sVal), bsVal, fabs(ysNew[i] - bsVal));
  268.  
  269.         //printf("x[%d]=%.2f y[%d]=%.6f bs[%d]=%.6f\n",
  270.         //        i, xsNew[i], i, ysNew[i], i, bsVal);
  271.     }
  272.  
  273. /*  xtype s = 0;
  274.     int k = 3;
  275.     int q = 4;
  276.  
  277.  
  278.     for ( int k = 0; k < N; k++) {
  279.  
  280.         s += nFunc(q, k, 3.0) * ys[k];
  281.     }
  282.     printf("s=%.6f", s);*/
  283.  
  284.     return 0;
  285. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement