lab9.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. typedef struct{
  5. double a, b, c, d;
  6. double x;
  7. }CubicSpline;
  8. double *EquallySpaced(double a, double b, int node){
  9. int i;
  10. double step;
  11. step = (b-a)/(node-1);
  12. double* x = (double*)malloc(node*sizeof(double));
  13. for (i=0; i<node; i++){
  14. x[i] = a + i*step;
  15. }
  16. return x;
  17. }
  18. void FindCubicSplines(CubicSpline* splines, int n, double *xk, double *yk, double dfa, double dfb)
  19. {
  20. double* h = (double*)malloc((n-1)*sizeof(double));
  21. double* b = (double*)malloc(n * sizeof(double));
  22. double* c = (double*)malloc(n * sizeof(double));
  23. double* d = (double*)malloc(n * sizeof(double));
  24. double* f = (double*)malloc(n * sizeof(double));
  25. double* M = (double*)malloc(n * sizeof(double));
  26. int i;
  27. b[0] = 0;
  28. d[n-1] = 0;
  29. for (i = 0; i < n - 1; i++)
  30. {
  31. h[i] = xk[i+1] - xk[i];
  32. }
  33. c[0] = -h[0] / 3;
  34. d[0] = -h[0] / 6;
  35. b[n-1] = h[n-2] / 6;
  36. c[n-1] = h[n-2] / 3;
  37. f[0] = dfa - (yk[1]-yk[0]) / h[0];
  38. f[n-1] = dfb - (yk[n-1]-yk[n-2]) / h[n-2];
  39. for(i = 1; i < n - 1; i++)
  40. {
  41. b[i] = h[i-1] / (h[i-1] + h[i]);
  42. c[i] = 2;
  43. d[i] = h[i] / (h[i-1] + h[i]);
  44. f[i] = (6 / (h[i-1] + h[i])) * ((yk[i+1] - yk[i]) / h[i] - (yk[i] - yk[i-1]) / h[i-1]);
  45. }
  46. //Найти Mi
  47. for(i = 1; i < n; i++)
  48. {
  49. c[i] = c[i] - b[i] * d[i-1] / c[i-1];
  50. f[i] = f[i] - b[i] * f[i-1]/c[i-1];
  51. b[i] = 0;
  52. }
  53. M[n-1] = f[n-1] / c[n-1];
  54. for(i = n - 2; i >= 0; i--)
  55. {
  56. M[i] = (f[i] - d[i] * M[i+1]) / c[i];
  57. }
  58. //Найти коэффициенты
  59. for(i = 0; i < n - 1; i++){
  60. splines[i].a = M[i] / (6*h[i]);
  61. splines[i].b = M[i+1] / (6*h[i]);
  62. splines[i].c = (yk[i+1] - yk[i]) / h[i] - h[i] * (M[i+1]-M[i]) / 6;
  63. splines[i].d = yk[i] - M[i] * h[i] * h[i] / 6;
  64. splines[i].x = xk[i];
  65. }
  66. splines[n-1].x = xk[n-1];
  67. free(h);
  68. free(b);
  69. free(c);
  70. free(d);
  71. free(f);
  72. free(M);
  73. }
  74. double cubicSplineInterpolate(CubicSpline* splines, int n, double x) {
  75. int i;
  76. double dx1, dx2;
  77. for (i = 0; i < n - 1; i++) {
  78. if (x >= splines[i].x && x <= splines[i+1].x) {
  79. dx1 = x - splines[i].x;
  80. dx2 = splines[i+1].x - x;
  81. return splines[i].a*dx2*dx2*dx2 + splines[i].b*dx1*dx1*dx1 + splines[i].c*dx1 + splines[i].d;
  82. }
  83. }
  84. return 0;
  85. }
  86. double Func1(double x) {
  87. return 1.0*(exp(x) - exp(-x))/(exp(x)+exp(-x));
  88. }
  89. double Func2(double x) {
  90. double sign_x;
  91. if (x>0) sign_x =1;
  92. else if (x==0) sign_x =0;
  93. else sign_x = -1;
  94. return 3 * sign_x * pow(x*1.0, 4) + 4 * pow(x*1.0, 3) - 12 * pow(x*1.0, 2) + 4;
  95. }
  96. int main() {
  97. FILE *f = fopen("data.txt", "w");
  98. if (f == NULL) {
  99. printf("Error opening file!\n");
  100. return 1;
  101. }
  102. int nodes[] = {5,7,10};
  103. int i,j,n;
  104. double dfa, dfb, a, b, x, y;
  105. dfa = 48;
  106. dfb = 31.5;
  107. a = -1; b = 1.5;
  108. for(i=0; i<3;i++){
  109. n = nodes[i];
  110. double *xk;
  111. CubicSpline* splines = (CubicSpline*)malloc(n * sizeof(CubicSpline));
  112. double* yk = (double*)malloc(n*sizeof(double));
  113. fprintf(f,"%d ", n);
  114. xk = EquallySpaced(a, b, n);
  115. for(j =0; j< n; j++) yk[j] = Func2(xk[j]);
  116. FindCubicSplines(splines, n, xk, yk, dfa, dfb);
  117. for(j=0; j<1000;j++){
  118. x = a+j*(b-a)/999;
  119. y = cubicSplineInterpolate(splines, n, x);
  120. fprintf(f, "%.13f ", y);
  121. }
  122. fprintf(f,"\n");
  123. free(splines);
  124. free(xk);
  125. free(yk);
  126. }
  127. fclose(f);
  128. return 0;
  129. }