spline.cpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #include "spline.hpp"
  2. void
  3. Spline::setPoints(Point* _points,size_t _n){
  4. P=_points;
  5. n=_n;
  6. q=new Poly3[n-1];
  7. }
  8. void Spline::compute(){
  9. double* Asub=new double[n-1];
  10. double* Adiag=new double[n];
  11. double* Asup=new double[n-1];
  12. double* B=new double[n];
  13. double* m=new double[n];
  14. double* h=new double[n-1];
  15. //Compute h
  16. for(size_t i=0;i<n-1;++i){
  17. h[i]=P[i+1].x-P[i].x;
  18. }
  19. //Compute B
  20. B[0]=0;
  21. for(size_t i=1;i<n-1;++i){
  22. B[i]=6*((P[i+1].y-P[i].y)/h[i]-(P[i].y-P[i-1].y)/h[i-1]);
  23. }
  24. B[n-1]=0;
  25. //Compute A
  26. Adiag[0]=1;
  27. Asup[0]=0;
  28. for(size_t i=1;i<n-1;++i){
  29. Asub[i-1]=h[i-1];
  30. Adiag[i]=2*(h[i-1]+h[i]);
  31. Asup[i]=h[i];
  32. }
  33. Asub[n-2]=0;
  34. Adiag[n-1]=1;
  35. //Compute m
  36. Thomas(n,Asub,Adiag,Asup,B,m);
  37. //Compute ploynimials q
  38. for(size_t i=0;i<n-1;++i){
  39. q[i].d=P[i].y;
  40. q[i].b=m[i]/2;
  41. q[i].a=(m[i+1]-m[i])/(6*h[i]);
  42. q[i].c=(P[i+1].y-P[i].y)/h[i]-h[i]*(m[i+1]-m[i])/6-(h[i]*m[i])/2;
  43. }
  44. delete[] Asub;
  45. delete[] Adiag;
  46. delete[] Asup;
  47. delete[] B;
  48. delete[] m;
  49. delete[] h;
  50. }
  51. size_t
  52. Spline::findIndex(double x) const{
  53. //Find minimal i s.t. P[i].x>x
  54. size_t i=0;
  55. while(i<n-1 and P[i].x<=x){
  56. ++i;
  57. }
  58. // Here i=n-1 or P[i].x>x
  59. return i-1;
  60. }
  61. double
  62. Spline::operator()(double x) const{
  63. size_t i=findIndex(x);
  64. return q[i](x-P[i].x);
  65. }
  66. double
  67. Spline::derivate(double x) const{
  68. size_t i=findIndex(x);
  69. return q[i].derivate(x-P[i].x);
  70. }