Advertisement
m4ly

Interpolacja wielomianowa. Wzór Lagrange. Wzór Czebyszwa.

Jan 21st, 2014
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.48 KB | None | 0 0
  1. /*
  2. Autor: Dawid Mocek
  3. Działa na MS VS Express 2013 lub jakimkolwiek kompilatorze  C++11
  4. Generuje pliki do otwarcia od razu w Excel`u i skonstruowania wykresów
  5. wersja: 2013/01/27  mam nadzieje że w 100% poprawna
  6.  
  7. Zadanie:
  8.  
  9. Interpolacja wielomianowa, wzór Lagrange`a
  10. Funkcja interpolowana: f(x)=|cos(x)|
  11. Parametry:
  12. x E <-3,3>, x E <-6,6>
  13. n = 7,8,15,16
  14. mn.n E <100;200>
  15.  
  16. W programie nalzey zmienic: string katalog_wynikowy
  17.  
  18. */
  19. #include <iostream>
  20. #include <iomanip>
  21. #include <cmath>
  22. #include <ostream>
  23. #include <fstream>
  24. #include <cmath>
  25. #include <string>
  26. #include <vector>
  27.  
  28. // 0 lub 1. Pokazuje troche więcej informacji na stand. wyjsciu
  29. #define DEBUG 1
  30.  
  31. #define PI 3.14
  32.  
  33. using namespace std;
  34.  
  35.  
  36. /*
  37. Filtr konwersji CSV z pakietu Microsoft Office pracuje przy założeniu, że plik CSV używa przecinka jako separatora,
  38. tymczasem Microsoft Excel i Access wyświetlają i zapisują plik CSV w formacie zgodnym z ustawieniami regionalnymi systemu,
  39. czyli w przypadku języka polskiego używa średnika zamiast przecinka do rozdzielania pól. Aby umożliwić automatyczną konwersję,
  40. tworzone są dedykowane makra.
  41. */
  42. #define DELIMITER  ";"
  43.  
  44. #pragma region Funkcje dla debug
  45.  
  46. void ShowArr_1D(const string nazwa, const double *arr, const int size)
  47. {
  48.     cout << nazwa << ": ";
  49.     for (int i = 0; i < size; i++)
  50.         cout << arr[i] << " ";
  51.     cout << endl;
  52. }
  53.  
  54.  
  55. #pragma endregion
  56.  
  57. string intToStr(int n)
  58. {
  59.     string tmp, ret;
  60.     if (n < 0) {
  61.         ret = "-";
  62.         n = -n;
  63.     }
  64.     do {
  65.         tmp += n % 10 + 48;
  66.         n -= n % 10;
  67.     } while (n /= 10);
  68.     for (int i = tmp.size() - 1; i >= 0; i--)
  69.         ret += tmp[i];
  70.     return ret;
  71. }
  72.  
  73.  
  74. // imbue(locale("")); powoduje zapis liczb zmiennoprzecinkowych z przecinkiem(0,33333) nie kropką(0.333) dla systemow z Locale pl_PL
  75. inline void SetFileAttr(fstream &f, const int precision)
  76. {
  77.     f.imbue(locale(""));
  78.     f.precision(precision);
  79. }
  80.  
  81. // Nasza funkcja interpolowana f(x)
  82. inline double fcosx(const double x)
  83. {
  84.     return abs(cos(x));
  85. }
  86.  
  87. // interpolacja
  88. double lagrangeInterpolation(const double *X, const int x_len, const double *Y, const int y_len, const double x)
  89. {
  90.  
  91.     double y = 0;
  92.  
  93.     for (int i = 0; i < x_len; i++)
  94.     {
  95.         double t = 1;
  96.         for (int j = 0; j < y_len; j++)
  97.         {
  98.             if (j != i)
  99.             {
  100.                 t *= (x - X[j]) / (X[i] - X[j]);
  101.             }
  102.         }
  103.         y += Y[i] * t;
  104.     }
  105.     return y;
  106. }
  107.  
  108. // Wzor Czebyszwa jest bardzo mocno rozbity ponieważ na technicznym kalulatorze wychodzily znacznie wyzsze(bliższe) wyniki
  109. double * czebyszew(const double a, const double b, const int n)
  110. {
  111.     double *tablica_czebyszewa = new double[n];
  112.     double arg = 0, res = 0;
  113.     double part1 = 0.5 * (a + b);
  114.     double part2 = 0.5 * (b - a);
  115.     int i = 0;
  116.  
  117.     for (int i = 0; i < n; i++)
  118.     {
  119.         double tmp_n = (double)(n - 1);
  120.         double tmp_i = (double)i;
  121.         double tmp_k = (double)((2 * tmp_i) + 1);
  122.         double tmp_l = (double)((2 * tmp_n) + 2);
  123.         double tmp_o = tmp_k / tmp_l;
  124.         arg = tmp_o * PI;
  125.         double z = cos(arg);
  126.         res = part1 - (part2 * z);
  127.         tablica_czebyszewa[i] = res;
  128.     }
  129.  
  130.     return tablica_czebyszewa;
  131. }
  132.  
  133. double * rownoodlegle(const double a, const double b, const int n)
  134. {
  135.  
  136.     double *tablica_przedzialow = new double[n];
  137.     double h = (b - a) / (double)(n - 1);
  138.     for (int i = 0; i < n; i++)
  139.         tablica_przedzialow[i] = a + ((double)i * h);;
  140.  
  141.     return tablica_przedzialow;
  142. }
  143.  
  144. void InterpolacjaRownoodlegle(const string dir, const double a, const double b, const int n, const double density, const int precision)
  145. {
  146. #if(DEBUG)
  147.     cout << "<rownoodlegle>" << endl << endl;
  148. #endif
  149.  
  150.     int real_n = n + 1;
  151.  
  152.     string csv_plik = dir + "\\InterpolacjaRownoodegle_n" + intToStr(n) + "_a" + intToStr(a) + "_b" + intToStr(b) + ".csv";
  153.     string csv_wezly_plik = dir + "\\InterpolacjaRownoodegle_n" + intToStr(n) + "_a" + intToStr(a) + "_b" + intToStr(b) + "_wezly.csv";
  154.  
  155.     fstream csv(csv_plik, ios::trunc | ios::in | ios::out);
  156.     fstream csv_wezly(csv_wezly_plik, ios::trunc | ios::in | ios::out);
  157.  
  158.     SetFileAttr(csv, precision);
  159.     SetFileAttr(csv_wezly, precision);
  160.  
  161.     double *rowno_data = rownoodlegle(a, b, real_n);
  162.     double *y_fcosx = new double[real_n];
  163.     double *y_wezly = new double[real_n];
  164.     for (int z = 0; z < real_n; z++)
  165.     {
  166.         y_fcosx[z] = fcosx(rowno_data[z]);
  167.         y_wezly[z] = lagrangeInterpolation(rowno_data, real_n, y_fcosx, real_n, rowno_data[z]);
  168.     }
  169.  
  170.  
  171. #if(DEBUG)
  172.     ShowArr_1D("    x", rowno_data, real_n);
  173.     ShowArr_1D(" f(x)", y_fcosx, real_n);
  174.     ShowArr_1D("wezly", y_wezly, real_n);
  175.  
  176. #endif
  177.  
  178.     // Zliacza ilosc iteracji
  179.     int i_tmp = 0;
  180.  
  181.     // Nagłowek CSV
  182.     csv << "\"x\"" << DELIMITER << "\"f(x)\"" << DELIMITER << "\"L(x) - rownoodegle\"" << DELIMITER << "\"L(x)-f(x)\"" << endl;
  183.  
  184.     double z = a;
  185.     while (z < b)
  186.     {
  187.         // Dane CSV
  188.         double x = fcosx(z);
  189.         double lag = lagrangeInterpolation(rowno_data, real_n, y_fcosx, real_n, z);
  190.         csv << z << DELIMITER << fixed << x << DELIMITER << lag  << DELIMITER << lag-x << endl;
  191.         z += density;
  192.         ++i_tmp;
  193.     }
  194.  
  195.     // Zrzuca wezly
  196.     csv_wezly << "\"x\"" << DELIMITER << "\"f(x)\"" << DELIMITER << "\"L(x) - rownoodegle\"" << endl;
  197.     for (int z = 0; z < real_n; z++)
  198.         csv_wezly << rowno_data[z] << DELIMITER << y_fcosx[z] << DELIMITER << y_wezly[z] << endl;
  199.  
  200.     delete[] rowno_data;
  201.     delete[] y_fcosx;
  202.     delete[] y_wezly;
  203.  
  204.  
  205.     rowno_data = NULL;
  206.     y_fcosx = NULL;
  207.     y_wezly = NULL;
  208.  
  209.     csv.close();
  210.     csv_wezly.close();
  211.  
  212. #if(DEBUG)
  213.     cout << "   Ilosc iteracji: " << i_tmp << endl;
  214.     cout << endl << "</rownoodlegle>" << endl;
  215. #endif
  216.  
  217. }
  218.  
  219. void InterpolacjaCzebyszew(const string dir, const double a, const double b, const int n, const double density, const int precision)
  220. {
  221. #if(DEBUG)
  222.     cout << "<czebyszew>" << endl << endl;
  223. #endif
  224.  
  225.     int real_n = n + 1;
  226.  
  227.     string csv_plik = dir + "\\InterpolacjaCzebyszew_n" + intToStr(n) + "_a" + intToStr(a) + "_b" + intToStr(b) + ".csv";
  228.     string csv_wezly_plik = dir + "\\InterpolacjaCzebyszew_n" + intToStr(n) + "_a" + intToStr(a) + "_b" + intToStr(b) + "_wezly.csv";
  229.    
  230.     fstream csv(csv_plik, ios::trunc | ios::in | ios::out);
  231.     fstream csv_wezly(csv_wezly_plik, ios::trunc | ios::in | ios::out);
  232.  
  233.     SetFileAttr(csv, precision);
  234.     SetFileAttr(csv_wezly, precision);
  235.  
  236.     double *czebyszew_data = czebyszew(a, b, real_n);
  237.     double *y_fcosx = new double[real_n];
  238.     double *y_wezly = new double[real_n];
  239.  
  240.     for (int z = 0; z < real_n; z++)
  241.     {
  242.         y_fcosx[z] = fcosx(czebyszew_data[z]);
  243.         y_wezly[z] = lagrangeInterpolation(czebyszew_data, real_n, y_fcosx, real_n, czebyszew_data[z]);
  244.     }
  245.  
  246. #if(DEBUG)
  247.     ShowArr_1D("    x", czebyszew_data, real_n);
  248.     ShowArr_1D(" f(x)", y_fcosx, real_n);
  249.     ShowArr_1D("wezly", y_wezly, real_n);
  250. #endif
  251.  
  252.     // Zliacza ilosc iteracji
  253.     int i_tmp = 0;
  254.  
  255.     // Nagłowek CSV
  256.     csv << "\"x\"" << DELIMITER << "\"f(x)\"" << DELIMITER << "\"L(x) - czebyszew\"" << DELIMITER << "\"L(x)-f(x)\"" << endl;
  257.  
  258.     double z = a;
  259.     while (z < b)
  260.     {
  261.         // Dane CSV
  262.         double x = fcosx(z);
  263.         double lag = lagrangeInterpolation(czebyszew_data, real_n, y_fcosx, real_n, z);
  264.         csv << z << DELIMITER << fixed << x << DELIMITER << lag << DELIMITER << lag - x << endl;
  265.  
  266.         z += density;
  267.         ++i_tmp;
  268.     }
  269.  
  270.     // Zrzuca wezly
  271.     csv_wezly << "\"x\"" << DELIMITER << "\"f(x)\"" << DELIMITER << "\"L(x) - czebyszew\"" << endl;
  272.     for (int z = 0; z < real_n; z++)
  273.         csv_wezly << czebyszew_data[z] << DELIMITER << y_fcosx[z] << DELIMITER << y_wezly[z] << endl;
  274.  
  275.  
  276.     delete[] czebyszew_data;
  277.     delete[] y_fcosx;
  278.     delete[] y_wezly;
  279.  
  280.     czebyszew_data = NULL;
  281.     y_fcosx = NULL;
  282.     y_wezly = NULL;
  283.  
  284.     csv.close();
  285.     csv_wezly.close();
  286.  
  287. #if(DEBUG)
  288.     cout << "   Ilosc iteracji: " << i_tmp << endl;
  289.     cout << endl << "</czebyszew>" << endl;
  290. #endif
  291. }
  292.  
  293. int main(void)
  294. {
  295.     int stop;
  296.  
  297.     // lista zakresow <a; b>
  298.     vector<vector<int>> zakresy{ { -3, 3 }, { -6, 6 } };
  299.     //vector<vector<int>> zakresy{ { -6, 6 } };
  300.  
  301.     // Gestosc - zmiana tego spowoduje utracenie zgodnosc wezlow na wykresie z funkcjami interpolujaca i interpolowana
  302.     double density = 0.05;
  303.  
  304.     // Precyzja liczb zmiennoprzecinkowych
  305.     int precision = 10;
  306.  
  307.     // Węzeł/y
  308.     int nTab[] = { 7, 8, 15, 16 };
  309.    
  310.     // Katalog wynikowy
  311.     string dir = "D:\\inter";
  312.  
  313.     for (vector<vector<int>>::iterator it = zakresy.begin(); it != zakresy.end(); ++it)
  314.     {
  315.         vector<int> tmp = *it;
  316.  
  317.         int a = tmp[0];
  318.         int b = tmp[1];
  319.  
  320.         for each (int n in nTab)
  321.         {
  322.  
  323.        
  324.  
  325. #if(DEBUG)
  326.             cout << "Generacja dla: <a, b> = <" << a << ", " << b << ">" << ", n = " << n << ", gestosc = " << density << endl << endl;
  327. #endif
  328.             InterpolacjaRownoodlegle(dir, a, b, n, density, precision);
  329.             InterpolacjaCzebyszew(dir, a, b, n, density, precision);
  330.  
  331.         }
  332.     }
  333.     cout << "Koniec";
  334.     cin >> stop;
  335.     return 0;
  336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement