Ladies_Man

F*CK beesplines

Jun 21st, 2016
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.63 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];
  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.  
  56.  
  57.  
  58. _spline populateSpline(int n) {
  59.  
  60.     xtype ak[n-3], bk[n-2], ck[n-3], dk[n-2], ek[n];
  61.     xtype a[n], b[n], c[n], d[n];
  62.  
  63.     xtype h = xs[1] - xs[0];
  64.  
  65.     for (int i = 0; i < n - 2; i++) {
  66.  
  67.         if (i < n-3)
  68.             ak[i] = ck[i] = 1;
  69.  
  70.         bk[i] = 4;
  71.         dk[i] = 3 / (h * h) * (ys[i+2] - 2*ys[i+1] + ys[i]);
  72.     }
  73.  
  74.     solveMatrix(n-2, ak, bk, ck, dk, ek);
  75.  
  76.  
  77.     c[0] = c[n-1] = 0;
  78.     for (int i = 1; i < n-1; i++)
  79.         c[i] = ek[i-1];
  80.  
  81.     for (int i = 0; i < n-1; i++) {
  82.         a[i] = ys[i];
  83.         b[i] = (ys[i+1] - ys[i]) / h - (h/3) * (c[i+1] + 2*c[i]);
  84.         d[i] = (c[i+1] - c[i]) / (3*h);
  85.     }
  86.  
  87.  
  88.     _spline spZ;
  89.  
  90.     for (int i = 0; i < n; i++) {
  91.         spZ.a[i] = a[i];
  92.         spZ.b[i] = b[i];
  93.         spZ.c[i] = c[i];
  94.         spZ.d[i] = d[i];
  95.     }
  96.     return spZ;
  97. }
  98.  
  99. xtype countSplineAt(_spline spline, xtype x) {
  100.  
  101.     //S_j[x] = a_j + b_j(x-xj) + c_j(x-xj)^2 + d_j(x-xj)^3
  102.     int i;
  103.     for (i = 0; i < N; ++i)
  104.         if (x >= xs[i] && x <= xs[i+1])
  105.             break;
  106.  
  107.     if (N == i) i--;
  108.  
  109.     //printf("cSA: %.6f\n", xsNew[i]);
  110.     //printf("[%d] %.6f %.6f \n",i, x, xsNew[i]);
  111.  
  112.     return  spline.a[i] +
  113.             spline.b[i]*(x - xs[i]) +
  114.             spline.c[i]*(x - xs[i])*(x - xs[i]) +
  115.             spline.d[i]*(x - xs[i])*(x - xs[i])*(x - xs[i]);
  116. }
  117.  
  118.  
  119. xtype nFunc(int q, int k, xtype t) {
  120.  
  121.     if (1 == q) {
  122.         if (t >= xs[k] && t <= xs[k+1])
  123.             return 1;
  124.         else
  125.             return 0;
  126.     }
  127.  
  128.     xtype n1 = nFunc(q-1, k, t) * (t - xs[k]) / (xs[k+q-1] - xs[k]);
  129.     xtype n2 = nFunc(q-1, k+1, t) * (xs[k+q] - t) / (xs[k+q] - xs[k+1]);
  130.  
  131.     return n1 + n2;
  132. }
  133.  
  134.  
  135.  
  136. bispline populateBiSpline(int n) {
  137.  
  138.     xtype ak[n], bk[n], ck[n], dk[n], ek[n+2];
  139.     xtype a[n], b[n], c[n], d[n];
  140.  
  141.     for (int i = 1; i < n - 2; i++) {
  142.         a[i] = 1;
  143.         b[i] = 4;
  144.         c[i] = 1;
  145.         d[i] = 6*ys[i];
  146.     }
  147.  
  148.     a[0] = 0;
  149.     b[0] = 1;
  150.     c[0] = 0;
  151.     d[0] = ys[0];
  152.  
  153.     a[n-3] = 0;
  154.     b[n-3] = 1;
  155.     c[n-3] = 0;
  156.     d[n-3] = ys[N-3];
  157.  
  158.     for (int i = 0; i < n; i++) {
  159.         d[i] /= h*h*h;
  160.     }
  161.  
  162.     solveMatrix(n-2, a, b, c, d, ek);
  163.  
  164.  
  165.     _bispline bsp;
  166.  
  167.     for (int i = 1; i < n-1; i++)
  168.         bsp.x[i] = ek[i-1];
  169.  
  170.     bsp.x[0] = 2*xs[1] - xs[2];
  171.     bsp.x[n-2] = 2*xs[n-2] - xs[n-3];
  172.  
  173.     return bsp;
  174. }
  175.  
  176. xtype baseX(int k, xtype x, xtype kh) {
  177.     if (0 == k) {
  178.  
  179.         if (xs[0] + 2*h <= x) return 0;
  180.         if (xs[0] + h <= x && x < xs[0] + 2*h) return pow(2*h + xs[0] - kh - (x - kh), 3)/6;
  181.         if (xs[0] <= x && x < xs[0] + h)
  182.             return 2*pow(h, 3)/3 - pow(-xs[0] + kh + (x - kh), 2)*(2*h + xs[0] - kh - (x - kh))/2;
  183.         if (xs[0] - h <= x && x < xs[0])
  184.             return 2*pow(h, 3)/3 - pow(-xs[0] + kh + (x - kh), 2)*(2*h - xs[0] + kh + (x - kh))/2;
  185.         if (xs[0] - 2*h <= x && x < xs[0] - h) return pow(2*h - xs[0] + kh + (x - kh), 3)/6;
  186.         if (x < xs[0] - 2*h) return 0;
  187.  
  188.     } else {
  189.         return baseX(0, x - k*h, -k*h);
  190.     }
  191.  
  192. }
  193.  
  194. xtype countBiSplineAt(_bispline bsp, xtype val) {
  195.  
  196.     int i;
  197.     for (i = 0; i < N; ++i)
  198.         if (xs[i] <= val && val <= xs[i+1])
  199.             break;
  200.  
  201.     if (N == i) i--;
  202.  
  203.     //printf("%.2f<=%.2f<=%.2f\n", xs[i], val, xs[i+1]);
  204.     if (xs[i] <= val && val <= xs[i+1]) {
  205.         return  bsp.x[i + 0] * baseX(i - 1, val, 0) +
  206.                 bsp.x[i + 1] * baseX(i + 0, val, 0) +
  207.                 bsp.x[i + 2] * baseX(i + 1, val, 0) +
  208.                 bsp.x[i + 3] * baseX(i + 2, val, 0);
  209.     } else {
  210.         return -1;
  211.     }
  212. }
  213.  
  214.  
  215. int main()
  216. {
  217.     printf("populating spline\n");
  218.     _spline sp = populateSpline(N+1);
  219.     _bispline bs = populateBiSpline(N+1);
  220.  
  221.  
  222.     for ( int i = 0; i <= 2*N; i++) {
  223.  
  224.         xtype sVal = countSplineAt(sp, xsNew[i]);
  225.  
  226.         xtype bsVal = countBiSplineAt(bs, xsNew[i]);
  227.  
  228.         printf("x[%d]=%.2f y=%.5f s=%.5f d=%.5f b=%.5f d=%.5f\n",
  229.                i, xsNew[i], ysNew[i], sVal, fabs(ysNew[i] - sVal), bsVal, fabs(ysNew[i] - bsVal));
  230.  
  231.         //printf("x[%d]=%.2f y[%d]=%.6f bs[%d]=%.6f\n",
  232.         //        i, xsNew[i], i, ysNew[i], i, bsVal);
  233.     }
  234.  
  235. /*  xtype s = 0;
  236.     int k = 3;
  237.     int q = 4;
  238.  
  239.  
  240.     for ( int k = 0; k < N; k++) {
  241.  
  242.         s += nFunc(q, k, 0.1) * ys[k];
  243.     }
  244.     printf("s=%.6f", s);*/
  245.  
  246.     return 0;
  247. }
Advertisement
Add Comment
Please, Sign In to add comment