constk

DefiniteIntegral_sourceFile

Sep 8th, 2020
90
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "DefiniteIntegral.h"
  2.  
  3. DefiniteIntegral::DefiniteIntegral(pointFunc f,double leftBorder, double rightBorder) : f(f), leftBorder(leftBorder), rightBorder(rightBorder) {}
  4.  
  5. DefiniteIntegral::DefiniteIntegral(pointFunc f, double leftBorder, double rightBorder, double eps) : f(f), leftBorder(leftBorder), rightBorder(rightBorder), eps(eps) {}
  6.  
  7. // Class public interface methods
  8.  
  9. double DefiniteIntegral::calculate(const char* method)
  10. {
  11.     if ( strcmp(toLowerCase(method), "left recktangle") == 0 || strcmp(toLowerCase(method), "leftrecktangle") == 0 )
  12.         return this->leftRecktangleMethod(this->calculateAmountOfIterations(&DefiniteIntegral::leftRecktangleMethod));
  13.     else if (strcmp(toLowerCase(method), "right recktangle") == 0 || strcmp(toLowerCase(method), "rightrecktangle") == 0)
  14.         return this->rightRecktangleMethod(this->calculateAmountOfIterations(&DefiniteIntegral::rightRecktangleMethod));
  15.     else if (strcmp(toLowerCase(method), "center recktangle") == 0 || strcmp(toLowerCase(method), "centerrecktangle") == 0)
  16.         return this->centerRecktangleMethod(this->calculateAmountOfIterations(&DefiniteIntegral::centerRecktangleMethod));
  17.     else if (strcmp(toLowerCase(method), "trapeze") == 0)
  18.         return this->trapezeMethod(this->calculateAmountOfIterations(&DefiniteIntegral::trapezeMethod));
  19.     else if (strcmp(toLowerCase(method), "newton") == 0)
  20.         return this->newtonMethod(this->calculateAmountOfIterations(&DefiniteIntegral::newtonMethod));
  21.     else if (strcmp(toLowerCase(method), "simpson") == 0)
  22.         return this->simpsonMethod(this->calculateAmountOfIterations(&DefiniteIntegral::simpsonMethod));
  23.     else {
  24.         std::cout << "Error: there is no such method of calculating integral" << std::endl;
  25.         system("pause>nul");
  26.         exit(1);
  27.     }
  28.  
  29.     return 0.0;
  30. }
  31.  
  32. int DefiniteIntegral::getAmountOfIterations(const char * method)
  33. {
  34.     if ( strcmp(toLowerCase(method), "left recktangle") == 0 || strcmp(toLowerCase(method), "leftrecktangle") == 0 )
  35.         return this->calculateAmountOfIterations(&DefiniteIntegral::leftRecktangleMethod);
  36.     else if ( strcmp(toLowerCase(method), "right recktangle") == 0 || strcmp(toLowerCase(method), "rightrecktangle") == 0 )
  37.         return this->calculateAmountOfIterations(&DefiniteIntegral::rightRecktangleMethod);
  38.     else if( strcmp(toLowerCase(method), "center recktangle") == 0 || strcmp(toLowerCase(method), "centerrecktangle") == 0 )
  39.         return this->calculateAmountOfIterations(&DefiniteIntegral::centerRecktangleMethod);
  40.     else if ( strcmp(toLowerCase(method), "trapeze") == 0 )
  41.         return this->calculateAmountOfIterations(&DefiniteIntegral::trapezeMethod);
  42.     else if ( strcmp(toLowerCase(method), "newton") == 0 )
  43.         return this->calculateAmountOfIterations(&DefiniteIntegral::newtonMethod);
  44.     else if ( strcmp(toLowerCase(method), "simpson") == 0 )
  45.         return this->calculateAmountOfIterations(&DefiniteIntegral::simpsonMethod);
  46.     else {
  47.         std::cout << "Error: there is no such method of calculating integral" << std::endl;
  48.         system("pause>nul");
  49.         exit(1);
  50.     }
  51.  
  52.     return -1;
  53. }
  54.  
  55. // Method to calculate amount of iterations
  56.  
  57. int DefiniteIntegral::calculateAmountOfIterations(double(DefiniteIntegral::*method)(int amountOfIterations))
  58. {
  59.     double P = 0;
  60.  
  61.     if (method == &DefiniteIntegral::leftRecktangleMethod ||
  62.         method == &DefiniteIntegral::rightRecktangleMethod) {
  63.         P = 1.0;
  64.     }
  65.     else if (method == &DefiniteIntegral::centerRecktangleMethod ||
  66.         method == &DefiniteIntegral::trapezeMethod) {
  67.         P = 2.0;
  68.     }
  69.     else if (method == &DefiniteIntegral::newtonMethod ||
  70.         method == &DefiniteIntegral::simpsonMethod) {
  71.         P = 4.0;
  72.     }
  73.     else {
  74.         std::cout << "Error: can't calculate amount of iterations, there is no such method in the class" << std::endl;
  75.         system("pause>nul");
  76.         exit(1);
  77.     }
  78.  
  79.     int n = 10; // start amount of iterations
  80.     const double k = 1 / (pow(2, P) - 1);
  81.  
  82.     while ( k * abs( (this->*method)(n) - (this->*method)(2 * n) ) > eps )
  83.         n *= 10;
  84.  
  85.     return n;
  86. }
  87.  
  88. // Methods for integral calcutation
  89.  
  90. double DefiniteIntegral::leftRecktangleMethod(int amountOfIterations)
  91. {
  92.     if (amountOfIterations <= 0) {
  93.         std::cout << "Error: amount of iterations must be positive number" << std::endl;
  94.         system("pause>nul");
  95.         exit(1);
  96.     }
  97.  
  98.     double h = abs(rightBorder - leftBorder) / amountOfIterations;
  99.     double result = 0.0;
  100.  
  101.     double x = leftBorder;
  102.     for (int i = 0; i != amountOfIterations; ++i) {
  103.         result += f(x);
  104.         x += h;
  105.     }
  106.  
  107.     return (result * h);
  108. }
  109.  
  110. double DefiniteIntegral::rightRecktangleMethod(int amountOfIterations)
  111. {
  112.     if (amountOfIterations <= 0) {
  113.         std::cout << "Error: amount of iterations must be positive number" << std::endl;
  114.         system("pause>nul");
  115.         exit(1);
  116.     }
  117.  
  118.     double h = abs(rightBorder - leftBorder) / amountOfIterations;
  119.     double result = 0.0;
  120.  
  121.     double x = leftBorder;
  122.     for (int i = 1; i != amountOfIterations + 1; ++i) {
  123.         result += f(x);
  124.         x += h;
  125.     }
  126.  
  127.     return (result * h);
  128. }
  129.  
  130. double DefiniteIntegral::centerRecktangleMethod(int amountOfIterations)
  131. {
  132.     if (amountOfIterations <= 0) {
  133.         std::cout << "Error: amount of iterations must be positive number" << std::endl;
  134.         system("pause>nul");
  135.         exit(1);
  136.     }
  137.  
  138.     double h = abs(rightBorder - leftBorder) / amountOfIterations;
  139.     double result = 0.0;
  140.  
  141.     double x = leftBorder + (h / 2.0);
  142.     for (int i = 0; i != amountOfIterations; ++i) {
  143.         result += f(x);
  144.         x += h;
  145.     }
  146.  
  147.     return (result * h);
  148. }
  149.  
  150. double DefiniteIntegral::trapezeMethod(int amountOfIterations)
  151. {
  152.     if (amountOfIterations <= 0) {
  153.         std::cout << "Error: amount of iterations must be positive number" << std::endl;
  154.         system("pause>nul");
  155.         exit(1);
  156.     }
  157.  
  158.     double h = abs(rightBorder - leftBorder) / amountOfIterations;
  159.     double result = 0.0;
  160.  
  161.     double x = leftBorder;
  162.     for (int i = 1; i != amountOfIterations; ++i) {
  163.         result += f(x);
  164.         x += h;
  165.     }
  166.  
  167.     result += ( this->f( this->leftBorder ) + this->f( this->rightBorder ) ) / 2;
  168.  
  169.     return ( result * h );
  170. }
  171.  
  172. double DefiniteIntegral::simpsonMethod(int amountOfIterations)
  173. {
  174.     double h = (rightBorder - leftBorder) / ( amountOfIterations * 2 );
  175.     double x = leftBorder + h;
  176.     double result = 0, result2 = 0, result4 = 0;
  177.  
  178.     for (int i = 0; i != amountOfIterations; ++i) {
  179.         result4 += f(x);
  180.         x += h;
  181.         result2 += f(x);
  182.         x += h;
  183.     }
  184.  
  185.     result = 2 * result2 + 4 * result4 + (f(leftBorder) - f(rightBorder));
  186.  
  187.     return result * h / 3.0;
  188. }
  189.  
  190. double DefiniteIntegral::newtonMethod(int amountOfIterations)
  191. {
  192.     double h = (rightBorder - leftBorder) / ( amountOfIterations * 3 );
  193.     double result2 = 0, result3 = 0, result = 0;
  194.     double x = leftBorder + h;
  195.  
  196.     for (int i = 0; i != amountOfIterations; ++i) {
  197.         result3 += f(x);
  198.         x += h;
  199.         result3 += f(x);
  200.         x += h;
  201.         result2 += f(x);
  202.         x += h;
  203.     }
  204.  
  205.     result = 2 * result2 + 3 * result3 + f(leftBorder) - f(rightBorder);
  206.  
  207.     return ( 3.0 / 8.0 ) * result * h;
  208. }
  209.  
  210. // Not a class members
  211.  
  212. char * toLowerCase(const char* str)
  213. {
  214.     char * ptr = (char*)malloc(strlen(str));
  215.     ptr = strcpy(ptr, str);
  216.  
  217.     for (char * tmpPtr = ptr; *tmpPtr; ++tmpPtr)
  218.         *tmpPtr = char(tolower(*tmpPtr));
  219.  
  220.     return ptr;
  221. }
  222.  
RAW Paste Data