Advertisement
Guest User

Untitled

a guest
Feb 24th, 2020
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.58 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define OK 0
  6. #define ALLOC_ERROR 1
  7. #define ERROR 2
  8. #define NOT_FOUND -1
  9. #define EPS 1e-5
  10. #define INTERPOLATION 0
  11. #define INVERSE_INTERPOLATION 1
  12.  
  13. /* Дисциплина: Вычислительные алгоритмы, ИУ7-43Б */
  14. /* Интерполя́ция, интерполи́рование — в вычислительной математике способ нахождения промежуточных значений величины по имеющемуся дискретному набору известных значений */
  15. /* Задание: 1 - Построить интерполяционный полином Ньютона с помощью таблицы; 2 - Найти корень табличной функции методом ПОЛОВИННОГО ДЕЛЕНИЯ и методом ОБРАТНОЙ ИНТЕРПОЛЯЦИИ */
  16.  
  17. typedef struct
  18. { //Структура для хранения таблицы. Таблица хранится в виде матрицы, строки
  19. double **mtr; //которой считываются из файла, а число столбцов равно (n + 2), где n - это
  20. int row; //степень полинома
  21. int start;
  22. int end;
  23. } table;
  24.  
  25. void menu()
  26. {
  27. printf("1 - Calculate Newton interpolation polynomial\n2 - Find the radix of a table function using the dichotomy method\n3 - Find the radix of a table function by inverse interpolation\n0 - Exit\n**Warning! the column of x should be sorted in increasing or descending order**\n");
  28. }
  29.  
  30. int fill_matrix(FILE *f, table *tbl, int n, int indicate)
  31. {
  32. fseek(f, 0, 0);
  33. fscanf(f, "%d", &tbl->row);
  34.  
  35. if (!(tbl->mtr = (double**)malloc(tbl->row * sizeof(double*))))
  36. return ALLOC_ERROR;
  37. for (int i = 0; i < tbl->row; i++)
  38. if (!(tbl->mtr[i] = (double*)malloc((n + 2) * sizeof(double))))
  39. return ALLOC_ERROR;
  40.  
  41. for (int i = 0; i < tbl->row; i++)
  42. for (int j = 0; j < n + 2; j++)
  43. tbl->mtr[i][j] = 0;
  44.  
  45. if (indicate == INTERPOLATION)
  46. for (int i = 0; i < tbl->row + 1; i++)
  47. for (int j = 0; j < 2; j++)
  48. fscanf(f, "%lf", &tbl->mtr[i][j]);
  49. else
  50. for (int i = 0; i < tbl->row + 1; i++)
  51. for (int j = 1; j >= 0; j--)
  52. fscanf(f, "%lf", &tbl->mtr[i][j]);
  53.  
  54. return OK;
  55. }
  56.  
  57. void print_matrix(table *tbl, int n, int m)
  58. {
  59. for (int i = 0; i < n; i++)
  60. {
  61. for (int j = 0; j < m; j++)
  62. {
  63. printf("%lf ", tbl->mtr[i][j]);
  64. }
  65. printf("\n");
  66. }
  67. }
  68.  
  69. int find_insert(table *tbl, double x)
  70. {
  71. for (int i = 0; i < tbl->row - 1; i++)
  72. {
  73. if ((x >= tbl->mtr[i][0] && x <= tbl->mtr[i + 1][0]) || (x <= tbl->mtr[i][0] && x >= tbl->mtr[i + 1][0]))
  74. {
  75. tbl->start = i;
  76. tbl->end = i + 1;
  77. printf("%lf %lf\n", tbl->mtr[i][0], tbl->mtr[i + 1][0]);
  78. return OK;
  79. }
  80. }
  81. return ERROR; //Extrapolation
  82. }
  83.  
  84. int find_interval(table *tbl, int n)
  85. {
  86. int h = n - 1;
  87.  
  88. while ((int)(h / 2) > 0)
  89. {
  90. if (tbl->end == tbl->row - 1 || tbl->start == 0)
  91. break;
  92. tbl->end++;
  93. tbl->start--;
  94. if (tbl->start < 0 && tbl->end == tbl->row)
  95. {
  96. tbl->start++;
  97. tbl->end--;
  98. return ERROR;
  99. }
  100. else
  101. {
  102. if (tbl->end == tbl->row)
  103. {
  104. tbl->end--;
  105. h++;
  106. break;
  107. }
  108. if (tbl->start < 0)
  109. {
  110. tbl->start++;
  111. h++;
  112. break;
  113. }
  114. }
  115. h -= 2;
  116. }
  117. if (h != 0)
  118. {
  119. printf("\nAsymmetric\n");
  120. if (tbl->start == 0)
  121. {
  122. tbl->end += h;
  123. if (tbl->end >= tbl->row)
  124. return ERROR;
  125. }
  126. else if (tbl->end == tbl->row - 1)
  127. {
  128. tbl->start -= h;
  129. if (tbl->start <= 0)
  130. return ERROR;
  131. }
  132. else
  133. {
  134. if (tbl->start >= h)
  135. tbl->start -= h;
  136. else if (tbl->row - tbl->end - 1 >= h)
  137. tbl->end += h;
  138. else
  139. return ERROR;
  140. }
  141. }
  142. return OK;
  143. }
  144.  
  145. int find_difference(table *tbl, int n)
  146. {
  147. int start = tbl->start, end = tbl->end;
  148. int interval = n + 1;
  149. int j = 0, q = 1;
  150.  
  151. for (int k = 2; k < n + 2; k++)
  152. {
  153. j = 0;
  154. for (int i = tbl->start; i < end; i++)
  155. {
  156. tbl->mtr[j][k] = (tbl->mtr[start][k - 1] - tbl->mtr[start + 1][k - 1]) / (tbl->mtr[i][0] - tbl->mtr[i + q][0]);
  157. j++;
  158. start++;
  159. }
  160. start = 0;
  161. end--;
  162. q++;
  163. }
  164.  
  165. print_matrix(tbl, tbl->row, n + 2);
  166.  
  167. return OK;
  168. }
  169.  
  170. double polynom(table tbl, int n, double x)
  171. {
  172. double p = tbl.mtr[tbl.start][1];
  173. double mul = 1;
  174. int start = tbl.start;
  175.  
  176. for (int i = 2; i < n + 2; i++)
  177. {
  178. mul *= x - tbl.mtr[start][0];
  179. start++;
  180. p += mul * tbl.mtr[0][i];
  181. }
  182. return p;
  183. }
  184.  
  185. int dichotomy(table tbl, int n)
  186. {
  187. int flag = NOT_FOUND;
  188. double a = tbl.mtr[tbl.start][0], b = tbl.mtr[tbl.end][0], c = 0;
  189.  
  190. if (fabs(polynom(tbl, n, a)) < EPS)
  191. {
  192. printf("\nX = %lf\n", a);
  193. return OK;
  194. }
  195. if (fabs(polynom(tbl, n, b)) < EPS)
  196. {
  197. printf("\nX = %lf\n", b);
  198. return OK;
  199. }
  200. if (b < a)
  201. {
  202. b = tbl.mtr[tbl.start][0];
  203. a = tbl.mtr[tbl.end][0];
  204. }
  205. c = (a + b) / 2;
  206. while (fabs(b - a) >= fabs(c) * EPS + EPS)
  207. {
  208. if (polynom(tbl, n, b) * polynom(tbl, n, c) < 0)
  209. {
  210. flag = 1;
  211. a = c;
  212. }
  213. else
  214. b = c;
  215. c = (a + b) / 2;
  216. }
  217. if (flag == NOT_FOUND)
  218. return NOT_FOUND;
  219.  
  220. printf("\nX = %lf\n", c);
  221.  
  222. return OK;
  223. }
  224.  
  225. void del_tbl(table *tbl)
  226. {
  227. if (tbl->mtr)
  228. {
  229. for (int i = 0; i < tbl->row; i++)
  230. if (tbl->mtr[i])
  231. free(tbl->mtr[i]);
  232. free(tbl->mtr);
  233. }
  234. }
  235.  
  236. int main()
  237. {
  238. FILE *f = fopen("table_x.txt", "r");
  239. if (!f)
  240. {
  241. printf("\nFile was not found\n");
  242. return -1;
  243. }
  244. int tmp;
  245. double rc;
  246.  
  247. fscanf(f, "%d", &tmp);
  248. printf("\n");
  249. for (int i = 0; i < tmp; i++)
  250. {
  251. for (int j = 0; j < 2; j++)
  252. {
  253. fscanf(f, "%lf", &rc);
  254. printf("%lf ", rc);
  255. }
  256. printf("\n");
  257. }
  258. printf("\n");
  259.  
  260. table tbl;
  261. int n = 0;
  262. double x = 0;
  263.  
  264. int ch;
  265. menu();
  266. printf("Input your choice: ");
  267. scanf("%d", &ch);
  268.  
  269. while (ch != 0)
  270. {
  271. switch (ch)
  272. {
  273. case 1:
  274. printf("Input the power of polynom (n): ");
  275. scanf("%d", &n);
  276. printf("Input the value (x): ");
  277. scanf("%lf", &x);
  278.  
  279. fill_matrix(f, &tbl, n, INTERPOLATION);
  280. if (find_insert(&tbl, x) != OK)
  281. {
  282. printf("Extrapolation! (the input valuse is out of table)\n");
  283. return ERROR;
  284. }
  285. printf("\n%d %d\n", tbl.start, tbl.end);
  286.  
  287. if (find_interval(&tbl, n) != OK)
  288. {
  289. printf("\nCannot take an interval: the table is too small\n");
  290. return ERROR;
  291. }
  292. printf("\n%d %d\n", tbl.start, tbl.end);
  293.  
  294. find_difference(&tbl, n);
  295. double p = polynom(tbl, n, x);
  296. printf("\nValue = %lf\n", p);
  297.  
  298. del_tbl(&tbl);
  299. break;
  300.  
  301. case 2:
  302. printf("Input the power of polynom (n): ");
  303. scanf("%d", &n);
  304. printf("Input the value (x): ");
  305. scanf("%lf", &x);
  306.  
  307. fill_matrix(f, &tbl, n, INTERPOLATION);
  308.  
  309. if (find_insert(&tbl, x) != OK)
  310. {
  311. printf("Extrapolation! (the input valuse is out of table)\n");
  312. return ERROR;
  313. }
  314. printf("\n%d %d\n", tbl.start, tbl.end);
  315.  
  316. if (find_interval(&tbl, n) != OK)
  317. {
  318. printf("\nCannot take an interval: the table is too small\n");
  319. return ERROR;
  320. }
  321. printf("\n%d %d\n", tbl.start, tbl.end);
  322. find_difference(&tbl, n);
  323. printf("-------------\n| DICHOTOMY |\n-------------\n");
  324. if (dichotomy(tbl, n) != OK)
  325. printf("The radix was not found (the interval does not contain it)");
  326.  
  327. del_tbl(&tbl);
  328. break;
  329.  
  330. case 3:
  331. printf("Input the power of polynom (n): ");
  332. scanf("%d", &n);
  333.  
  334. fill_matrix(f, &tbl, n, INVERSE_INTERPOLATION);
  335.  
  336. if (find_insert(&tbl, 0) != OK)
  337. {
  338. printf("Extrapolation! (the input valuse is out of table)\n");
  339. return ERROR;
  340. }
  341. //printf("\n%d %d\n", tbl.start, tbl.end);
  342. if (find_interval(&tbl, n) != OK)
  343. {
  344. printf("\nCannot take an interval: the table is too small\n");
  345. return ERROR;
  346. }
  347. printf("\n%d %d\n", tbl.start, tbl.end);
  348. find_difference(&tbl, n);
  349. printf("-------------------------\n| INVERSE_INTERPOLATION |\n-------------------------\n");
  350. double radix = polynom(tbl, n, 0);
  351. printf("\nX = %lf\n", radix);
  352.  
  353. del_tbl(&tbl);
  354. break;
  355.  
  356. case 0:
  357.  
  358. del_tbl(&tbl);
  359. break;
  360.  
  361. default:
  362.  
  363. del_tbl(&tbl);
  364. printf("\nWrong input\n");
  365. break;
  366. }
  367. printf("\nInput your choice: ");
  368. scanf("%d", &ch);
  369. }
  370.  
  371. fclose(f);
  372. return 0;
  373. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement