Ladies_Man

chmet3 cubic beespline

Jun 13th, 2016
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.60 KB | None | 0 0
  1. #include <iostream>
  2. #include <math.h>
  3. #include "stdio.h"
  4.  
  5. using namespace std;
  6.  
  7. #define xtype float
  8. #define N 10
  9.  
  10. xtype _a = 2.477520;
  11. xtype _b = 0.232206;
  12.  
  13. xtype xs[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0};
  14. xtype ys[] = {3.02, 3.21, 2.95, 4.06, 4.03, 5.39, 5.97, 6.51, 6.77, 7.79};
  15.  
  16. xtype xsNew[N*2];
  17. xtype ysNew[N*2];
  18.  
  19. xtype f(xtype x) { return _a * exp(_b*x); }
  20.  
  21. typedef struct spline {
  22.     xtype a[N*2-3];
  23.     xtype b[N*2-2];
  24.     xtype c[N*2-3];
  25.     xtype d[N*2-2];
  26. } _spline;
  27.  
  28. void solveMatrix(int n, xtype* a, xtype* b, xtype* c, xtype* d, xtype* x) {
  29.  
  30. // |b a . .|  |d|  |x|
  31. // |c b a .|  |d|  |x|
  32. // |. c b a|  |d|  |x|
  33. // |. . c b|  |d|  |x|
  34.  
  35.     int i;
  36.     xtype alpha[n], beta[n];
  37.     alpha[0] = -c[0] / b[0];
  38.     beta[0] = d[0] / b[0];
  39.  
  40.     for (i = 1; i < n-1; ++i) {
  41.         alpha[i] = (-c[i]) / (a[i] * alpha[i-1] + b[i]);
  42.         beta[i] = (d[i] - a[i] * beta[i-1]) / (a[i] * alpha[i-1] + b[i]);
  43.     }
  44.  
  45.     beta[n-1] = (d[n-1]-a[n-1] * beta[n-2]) / (a[n-1] * alpha[n-2] + b[n-1]);
  46.     x[n-1] = beta[n-1];
  47.  
  48.     for (i = n-2; i >= 0; --i) {
  49.         x[i] = alpha[i] * x[i+1] + beta[i];
  50.     }
  51. }
  52.  
  53. _spline populateSpline(int n) {
  54.  
  55.     xtype a[n-3], b[n-2], c[n-3], d[n-2], e[n];
  56.  
  57.     xtype h = (xsNew[n-1] - xsNew[0]) / n;
  58.  
  59.     for (int i = 0; i < n - 2; ++i) {
  60.  
  61.         if (i < n-3)
  62.             a[i] = c[i] = 1;
  63.  
  64.         b[i] = 4;
  65.         d[i] = 3 / (h * h) * (ysNew[i+2] - 2*ysNew[i+1] + ysNew[i]);
  66.     }
  67.  
  68.     solveMatrix(n-2, a, b, c, d, e);
  69.  
  70.     c[0] = c[n-1] = 0;
  71.  
  72.     for (int i = 1; i < n-1; ++i)
  73.         c[i] = e[i-1];
  74.  
  75.     for (int i = 0; i < n-1; ++i) {
  76.         a[i] = ysNew[i];
  77.         b[i] = (ysNew[i+1] - ysNew[i]) / h - (h/3) * (c[i+1] + 2*c[i]);
  78.         d[i] = (c[i+1] - c[i]) / (3*h);
  79.     }
  80.  
  81.     _spline spZ;
  82.     for (int i = 0; i < n; i++) {
  83.         spZ.a[i] = a[i];
  84.         spZ.b[i] = b[i];
  85.         spZ.c[i] = c[i];
  86.         spZ.d[i] = d[i];
  87.         printf("[%d] a:%.3f b:%.3f c:%.3f d:%.3f\n",
  88.                 i, a[i], b[i], c[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-1; ++i)
  98.         if (x >= xsNew[i] && x <= xsNew[i+1])
  99.             break;
  100.  
  101.     if (N-1 == i) i--;
  102.  
  103.     return  spline.a[i] +
  104.             spline.b[i]*(x - xsNew[i]) +
  105.             spline.c[i]*(x - xsNew[i])*(x - xsNew[i]) +
  106.             spline.d[i]*(x - xsNew[i])*(x - xsNew[i])*(x - xsNew[i]);
  107. }
  108.  
  109. xtype nFunc(int n, int i, xtype x) {
  110.  
  111.     if (x >= xsNew[i] && x <= xsNew[i+1])
  112.         return 1;
  113.     else
  114.         return 0;
  115.  
  116.     xtype n1 = nFunc(n-1, i, x) * (x - xsNew[i]) / (xsNew[i+n] - xsNew[i]);
  117.     xtype n2 = nFunc(n-1, i+1, x) * (xsNew[i+n+1] - x) / (xsNew[i+n+1] - xsNew[i+1]);
  118.  
  119.     return n1 + n2;
  120. }
  121.  
  122.  
  123. xtype dFunc(int k, int i, xtype x) {
  124.  
  125.     xtype alpha = (x - xsNew[i]) / (xsNew[i+N*2+1-k] - xsNew[i]);
  126.  
  127.     xtype d1 = dFunc(k-1, i-1, x);
  128.     xtype d2 = dFunc(k-1, i, x);
  129.  
  130.     return (1 - alpha)*d1 + alpha*d2;
  131. }
  132.  
  133. int main()
  134. {
  135.     int i;
  136.  
  137.     xsNew[0] = 0.25;
  138.     ysNew[0] = f(xsNew[0]);
  139.  
  140.     printf("increasing frequency of X-values\n");
  141.     printf("[0](%.2f, %f)\n", xsNew[0], ysNew[0]);
  142.  
  143.     for (i = 1; i < 20; i++) {
  144.  
  145.         xsNew[i] = xsNew[i-1] + 0.25;
  146.         ysNew[i] = f(xsNew[i]);
  147.  
  148.         printf("[%d](%.2f, %f)\n", i, xsNew[i], ysNew[i]);
  149.     }
  150.  
  151.     printf("populating spline\n");
  152.     _spline sp = populateSpline(N*2);
  153.  
  154.  
  155.     for (i = 0; i < N*2; i++) {
  156.  
  157.         xtype sVal = countSplineAt(sp, xsNew[i]);
  158.  
  159.         printf("y[%d]=%f s[%d]=%.16f d=%f\n",
  160.                 i, ysNew[i], i, sVal, fabs(ysNew[i] - sVal));
  161.     }
  162.  
  163.     return 0;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment