Advertisement
osipyonok

4m_lab1_s2

Feb 22nd, 2017
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.60 KB | None | 0 0
  1. // 4m_lab1_s2.cpp: определяет точку входа для консольного приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5.  
  6. #include<bits/stdc++.h>
  7. #include"gnuplot_i.hpp"
  8. #include <conio.h>
  9. #include <windows.h>
  10.  
  11. #define INF 1000010000
  12. #define nl '\n'
  13. #define pb push_back
  14. #define ppb pop_back
  15. #define mp make_pair
  16. #define fi first
  17. #define se second
  18. #define pii pair<int,int>
  19. #define pdd pair<double,double>
  20. #define all(c) (c).begin(), (c).end()
  21. #define SORT(c) sort(all(c))
  22. #define sz(c) (c).size()
  23. #define rep(i,n) for( int i = 0; i < n; ++i )
  24. #define repi(i,n) for( int i = 1 ; i <= n; ++i )
  25. #define repn(i,n) for( int i = n - 1 ; i >= 0 ; --i )
  26. #define repf(j,i,n) for( int j = i ; j < n ; ++j )
  27. #define die(s) {std::cout << s << nl;}
  28. #define dier(s) {std::cout << s; return 0;}
  29. #define vi vector<int>
  30. typedef long long ll;
  31. #define M_PI 3.14159265358979323846
  32. #define M_E 2.71828182845904523536
  33.  
  34. using namespace std;
  35.  
  36. string parse_path(char* path);
  37. void concat(vector<char> & v , string s);
  38.  
  39. class Solver{
  40. protected:
  41.     double (*f)(double x);
  42.     double a , b , h;
  43.     int n;
  44.    
  45. public:
  46.     Solver(double _a , double _b , int _n , double (*_func)(double x)){
  47.         a = _a;
  48.         b = _b;
  49.         n = _n;
  50.         f = _func;
  51.         h = (b - a) / n;
  52.     }
  53.     virtual double Solve() = 0;
  54. };
  55.  
  56. class Trapezoidal_rule : public Solver{
  57. public:
  58.     Trapezoidal_rule(double _a , double _b , int _n , double (*_func)(double x))
  59.     : Solver(_a , _b , _n , _func){}
  60.         double Solve(){
  61.         double sum = 0.;
  62.         for(int i = 0 ; i < n ; ++i){
  63.             double x = a + h * (double)i;
  64.             double xx = a + h * (double)(i + 1);
  65.             sum += f(x) + f(xx);
  66.         }
  67.         sum *= h;
  68.         sum /= 2.;
  69.         return sum;
  70.     }
  71. };
  72.  
  73.  
  74. class Simpson : public Solver{
  75. public:
  76.     Simpson(double _a , double _b , int _n , double (*_func)(double x))
  77.     : Solver(_a , _b , _n , _func){}
  78.        
  79.     double Solve(){
  80.         if(a == b)return 0;
  81.         double sum = 0.;
  82.         int k = 0;
  83.         for(int i = 1 ; i < n ; ++i){
  84.             double x = a + h * (double)i;
  85.             int c = 2 + 2 * (i & 1);
  86.             sum += (double)c * f(x);
  87.         }
  88.         sum += f(a) + f(b);
  89.         sum *= h;
  90.         sum /= 3.;
  91.         return sum;
  92.     }
  93. };
  94.  
  95. class Rectangle_method : public Solver{
  96. public:
  97.     Rectangle_method(double _a , double _b , int _n , double (*_func)(double x))
  98.     : Solver(_a , _b , _n , _func){}
  99.            
  100.     double Solve(){
  101.         double sum = 0.;
  102.         for(int i = 0 ; i < n ; ++i){
  103.             double x = a + h * (double)i;
  104.             sum += f(0.5 * (x + x + h));
  105.         }
  106.         return h * sum;
  107.     }
  108. };
  109.  
  110.  
  111. template <typename D , typename B>
  112. class IsDeriviedFrom{
  113. private:
  114.     class No {};
  115.     class Yes { No no[2]; };
  116.     static No Test(...);
  117.     static Yes Test(B*);
  118.  
  119. public:
  120.     enum{
  121.         Is = (sizeof(Test(static_cast<D*>(0))) == sizeof(Yes))
  122.     };
  123. };
  124.  
  125. template<class T , int = IsDeriviedFrom<T , Solver>::Is>
  126. class IFUL{     //integral as a function of the upper limit
  127. private:
  128.     double a , b;
  129.     int n;
  130.     double (*f)(double x);
  131.     vector<char> path;
  132.  
  133. public:
  134.     IFUL(double _a , double _b , int _n , double (*_func)(double x) , char* _path){
  135.         a = _a;
  136.         b = _b;
  137.         n = _n;
  138.         f = _func;
  139.         string parse_p = parse_path(_path);
  140.         path = vector<char>(parse_p.begin() , parse_p.end());
  141.         path.push_back('\0');
  142.         concat(path , "temp.txt");
  143.     }
  144.  
  145.     void Plot(){
  146.         double h = (b - a) / (double)n;
  147.         vector<pair<double , double>> segments;
  148.         segments.push_back(make_pair(a , 0.));
  149.  
  150.         for(int i = 1 ; i <= n ; ++i){
  151.             double x = a + h * (double)i;
  152.             double xx = a + h * (double)(i - 1);
  153.             T solver = T(xx , x , 100 , f);
  154.             segments.push_back(make_pair(x , solver.Solve()));
  155.             segments[segments.size() - 1].second += segments[segments.size() - 2].second;
  156.         }
  157.  
  158.         GnuPlot(segments);
  159.     }
  160.  
  161. private:
  162.     void GnuPlot(vector<pair<double , double>> & segments){
  163.         FILE * file = fopen(&path[0] , "w");
  164.         fprintf(file , "# X   Y\n");
  165.         for(int i = 0 ; i < segments.size() ; ++i){
  166.             fprintf(file , "  %lf   %lf\n" , segments[i].first , segments[i].second);
  167.         }
  168.         fclose(file);
  169.  
  170.         Gnuplot gnu("lines");
  171.         string a = "set style line 1 lc rgb '#0060ad' lt 2 lw 2 pt 0 ps 1.5";
  172.         string b = &path[0]; b = "plot '" + b; b += "' with linespoints ls 1";
  173.  
  174.         gnu.set_title("IFUL");
  175.         gnu.plot_points(b , a);
  176.  
  177.         wait();
  178.  
  179.         gnu.remove_tmpfiles();
  180.         remove(&path[0]);
  181.     }
  182.  
  183.     void wait(){
  184.         FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
  185.         #ifndef FOUT
  186.             cout << endl << "Press any key to continue..." << endl;
  187.         #endif
  188.         _getch();
  189.     }
  190. };
  191.  
  192. template <class T>
  193. class IFUL<T , 0>{
  194.     IFUL(double _a , double _b , int _n , double (*_func)(double x) , char* _path){}
  195. };
  196.  
  197. double f(double x){
  198.     return sin(x * x);
  199. }
  200.  
  201.  
  202. int main(int argc , char* argv[]) {
  203.     ios_base::sync_with_stdio(false);
  204.     cin.tie(NULL);
  205.     cout.precision(10);
  206.     cout.setf(ios::fixed);
  207.  
  208.     double a , b;
  209.     int n;
  210.     cin >> a >> b >> n;
  211.  
  212.  
  213.     Trapezoidal_rule tr(a , b , n , &f);
  214.     cout << "Trapezoidal_rule " << tr.Solve() << nl;
  215.  
  216.     Simpson si(a , b , n , &f);
  217.     cout << "Simpson " << si.Solve() << nl;
  218.  
  219.     Rectangle_method re(a , b , n , &f);
  220.     cout << "Rectangle_method " << re.Solve() << nl;
  221.  
  222.     system("pause");
  223.  
  224.     IFUL<Trapezoidal_rule> iful_tr(a , b , n , &f , argv[0]);
  225.     iful_tr.Plot();
  226.  
  227. //  IFUL<Simpson> iful_si(a , b , n , &f , argv[0]);
  228. //  iful_si.Plot();
  229.  
  230. //  IFUL<Rectangle_method> iful_re(a , b , n , &f , argv[0]);
  231. //  iful_re.Plot();
  232.  
  233.     system("pause");
  234.  
  235.     return 0;
  236. }
  237.  
  238. string parse_path(char* path){
  239.     string s = path;
  240.     size_t pos = s.find_last_of('\\');
  241.     if(pos != string::npos){
  242.         return s.substr(0 , pos + 1);
  243.     }
  244.     if(s[s.size() - 1] != '\\')s += '\\';
  245.     return s;
  246. }
  247.  
  248. void concat(vector<char> & v , string s){
  249.     v.pop_back();
  250.     for(int i = 0 ; i < s.size() ; ++i){
  251.         v.push_back(s[i]);
  252.     }
  253.     v.push_back('\0');
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement