CherMi

Куровая

May 20th, 2020
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.60 KB | None | 0 0
  1. #include "pch.h"
  2. #include <iostream>
  3. #include <cmath>
  4. #include <string>
  5. #include <fstream>
  6.  
  7. using namespace std;
  8.  
  9. class DHT
  10. {
  11. private:
  12.     double *arr;
  13.     int length;
  14. public:
  15.     DHT(int length, double *arr);
  16.     ~DHT();
  17.     void SetArray(int NewLength, double *NewArr);
  18.     void SetLength(int length);
  19.     int SetArrayElement(int index, double element);
  20.     int GetLength();
  21.     double *GetArray();
  22.     double GetArrayElemnt(int index);
  23.     double *CalculateDHT();
  24.     double *CalculateReverseDHT();
  25.     double *CalculateDFTRe();
  26.     double *CalculateDFTIm();
  27.     double *CalculateAmp();
  28.     double *CalculatePhi();
  29. };
  30.  
  31. class SequenceGenerator
  32. {
  33. public:
  34.     static double *GenerateSin(int length, double Amp, double T, double offset);
  35.     static double *GenerateDecreasingExp(int length);
  36. };
  37.  
  38. class Utilities
  39. {
  40. public:
  41.     static double *ChooseSequence(int *length);
  42.     static bool ActionWithDHT(DHT *d);
  43.     static double *InputFromFile(int *length);
  44.     static double *InputFromFile(int length);
  45.     static void OutputIntoFile(int length, double *arr);
  46.     static void OutputIntoFile(int length, string *arr);
  47.     static bool ValidateInput();
  48.     static void PrintArray(int length, double *arr);
  49. };
  50.  
  51. DHT::DHT(int length, double *arr)
  52. {
  53.     this->length = length;
  54.     this->arr = arr;
  55. }
  56. DHT::~DHT(){delete arr;}
  57. void DHT::SetArray(int NewLength, double *NewArr)
  58. {
  59.     delete(arr);
  60.     length = NewLength;
  61.     arr = NewArr;
  62. }
  63. int DHT::SetArrayElement(int index, double element)
  64. {
  65.     if (index >= 0 && index < length)
  66.     {
  67.         arr[index] = element;
  68.         return 0;
  69.     }
  70.     return -1;
  71. }
  72. double *DHT::GetArray(){return arr;}
  73. void DHT::SetLength(int length){this->length = length;}
  74. int DHT::GetLength(){return length;}
  75. double DHT::GetArrayElemnt(int index)
  76. {
  77.     if (index >= 0 && index < length){return arr[index];}
  78.     return -1000000; //Код ошибки
  79. }
  80. double *DHT::CalculateDHT()
  81. {
  82.     double *H = new double[length];
  83.     double Pi = 4 * atan(1);
  84.     int k, u;
  85.     for (u = 0; u < length; u++) //u - номер частоты
  86.     {
  87.         H[u] = 0;
  88.         for (k = 0; k < length; k++) //k - шаг по времени
  89.         {
  90.             H[u] += arr[k] * (cos(2 * Pi * k * u / length) + sin(2 * Pi * k * u / length));
  91.         }
  92.         H[u] *= 1 / sqrt(length);
  93.     }
  94.     return H;
  95. }
  96. double *DHT::CalculateReverseDHT()
  97. {
  98.     double *x = new double[length];
  99.     double Pi = 4 * atan(1);
  100.     int k, u;
  101.     for (k = 0; k < length; k++)
  102.     {
  103.         x[k] = 0;
  104.         for (u = 0; u < length; u++)
  105.         {
  106.             x[k] += arr[u] * (cos(2 * Pi * k * u / length) + sin(2 * Pi * k * u / length));
  107.         }
  108.         x[k] *= 1 / sqrt(length);
  109.     }
  110.     return x;
  111. }
  112.  
  113. double *DHT::CalculateDFTRe()
  114. {
  115.     double *Re = new double[length];
  116.     double *dht = CalculateDHT();
  117.     int u;
  118.     for (u = 0; u < length; u++){Re[u] = (dht[u] + dht[length - u]) / 2;}
  119.     delete dht;
  120.     return Re;
  121. }
  122. double *DHT::CalculateDFTIm()
  123. {
  124.     double *Im = new double[length];
  125.     double *dht = CalculateDHT();
  126.     int u;
  127.     for (u = 0; u < length; u++){Im[u] = (dht[u] - dht[length - u]) / 2;}
  128.     delete dht;
  129.     return Im;
  130. }
  131. double *DHT::CalculateAmp()
  132. {
  133.     double *A = new double[length];
  134.     double *Re = CalculateDFTRe();
  135.     double *Im = CalculateDFTIm();
  136.     int u;
  137.     for (u = 0; u < length; u++){A[u] = hypot(Re[u], Im[u]);}
  138.     delete(Re);
  139.     delete(Im);
  140.     return A;
  141. }
  142.  
  143. double *DHT::CalculatePhi()
  144. {
  145.     double *phi = new double[length];
  146.     double *Re = CalculateDFTRe();
  147.     double *Im = CalculateDFTIm();
  148.     int u;
  149.     for (u = 0; u < length; u++){phi[u] = atan2(Im[u], Re[u]);}
  150.     delete(Re);
  151.     delete(Im);
  152.     return phi;
  153. }
  154.  
  155. double *SequenceGenerator::GenerateSin(int length, double Amp, double T, double offset)
  156. {
  157.     //A * sin(wt + phi), где A = Amp, w = 2 * Pi / T, phi = offset
  158.     int i;
  159.     double Pi = 4 * atan(1);
  160.     double *arr = new double[length];
  161.     for (i = 0; i < length; i++){arr[i] = Amp * sin(2 * Pi * i / T + offset);}
  162.     return arr;
  163. }
  164. double *SequenceGenerator::GenerateDecreasingExp(int length)
  165. {
  166.     //exp(-tau/2)
  167.     int i;
  168.     double *arr = new double[length];
  169.     for (i = 1; i <= length; i++){arr[i - 1] = exp(- (double)i / 2);}
  170.     return arr;
  171. }
  172.  
  173. bool Utilities::ValidateInput()
  174. {
  175.     if (cin.fail()) //Если не получилось извлечь данные из буффера в переменную
  176.     {
  177.         cout << "Incorrect input format." << endl << endl;
  178.         cin.clear(); //Сбрасываем все флаги ошибок
  179.         cin.ignore(32767, '\n'); //Удаляем все лишние символы из буффера
  180.         return false;
  181.     }
  182.     cin.ignore(32767, '\n'); //Удаляем все лишние символы из буффера
  183.     return true;
  184. }
  185. void Utilities::PrintArray(int length, double *arr)
  186. {
  187.     int i;
  188.     for (i = 0; i < length - 1; i++){cout << arr[i] << ";\t";}
  189.     cout << arr[i] << "." << endl;
  190. }
  191. double *Utilities::ChooseSequence(int *length) {
  192.     int l, choice;
  193.     cout << "Enter length of the array:" << endl;
  194.     cin >> l;
  195.     if (!Utilities::ValidateInput()) return nullptr; //Если введено не число
  196.     if (l < 0)
  197.     {
  198.         cout << "Incorrect input format." << endl << endl;
  199.         return nullptr;
  200.     }
  201.     double *arr;
  202.     cout << "Choose function with which array will be generated:" << endl;
  203.     cout << "1 - A * sin(2 * Pi * i/T + phi); 2 - exp(-tau/2), tau changes from 1 to -length." << endl;
  204.     cout << "Your choice:" << endl;
  205.     cin >> choice;
  206.     if (!Utilities::ValidateInput()) return nullptr;
  207.     switch (choice) {
  208.     case 1:
  209.     {
  210.         double A, T, offset;
  211.         cout << "Enter the amplitude A = ";
  212.         cin >> A;
  213.         if (!Utilities::ValidateInput()) return nullptr;
  214.         cout << "Enter the period T = ";
  215.         cin >> T;
  216.         if (!Utilities::ValidateInput()) return nullptr;
  217.         cout << "Enter the initial frequency phi = ";
  218.         cin >> offset;
  219.         if (!Utilities::ValidateInput()) return nullptr;
  220.         cout << "Your function is: " << A << " * sin(2 * Pi * i/" << T << " + " << offset << ")" << endl;
  221.         arr = SequenceGenerator::GenerateSin(l, A, T, offset);
  222.         *length = l;
  223.         return arr;
  224.     }
  225.     case 2:
  226.     {
  227.         arr = SequenceGenerator::GenerateDecreasingExp(l);
  228.         *length = l;
  229.         return arr;
  230.     }
  231.     default:
  232.     {
  233.         cout << "Incorrect input format." << endl << endl;
  234.         return nullptr;
  235.     }
  236.     }
  237. }
  238. bool Utilities::ActionWithDHT(DHT *d)
  239. {
  240.     int action, i;
  241.     double *tmp1, *tmp2;
  242.     string *complex;
  243.     cout << "Choose what action you want to perform with your array:" << endl;
  244.     cout << "0 - exit into main menu; 1 - calculate DHT; 2 - calculate reverse DHT;" << endl;
  245.     cout << "3 - calculate DFT in algebraic form based on DHT" << endl;
  246.     cout << "4 - calculate DFT in exponential form based on DHT" << endl;
  247.     cout << "5 - save current working array to a file." << endl;
  248.     cout << "Your action:" << endl;
  249.     cin >> action;
  250.     if (!Utilities::ValidateInput()) return true;
  251.     switch (action)
  252.     {
  253.     case 0: //выйти в главное меню
  254. {return false;}
  255.     case 1: //вычислить ДПХ
  256.     {
  257.         tmp1 = d->CalculateDHT();
  258.         for (i = 0; i < d->GetLength(); i++)
  259.         {
  260.             cout << "x(" << i + 1 << ") =  " << d->GetArrayElemnt(i);
  261.             cout << "-->  H(" << i + 1 << ") = " << tmp1[i] << endl;
  262.         }
  263.         cout << "Do you want to save array of calculated values to a file?" << endl;
  264.         cout << "Enter 1 to save or anything else to continue:" << endl;
  265.         action = -1;
  266.         cin >> action;
  267.         Utilities::ValidateInput();
  268.         if (action == 1) Utilities::OutputIntoFile(d->GetLength(), tmp1);
  269.         cout << "Do you want to set array of calculated values as your working array?" << endl;
  270.         cout << "Enter 1 to agree or anything else to continue:" << endl;
  271.         action = -1;
  272.         cin >> action;
  273.         Utilities::ValidateInput();
  274.         if (action == 1)
  275.         {
  276.             d->SetArray(d->GetLength(), tmp1);
  277.             cout << "Array of calculated values set as your working array." << endl;
  278.             return true;
  279.         }
  280.         delete tmp1;
  281.         return true;
  282.     }
  283.     case 2: //вычислить обратное ДПХ
  284.     {
  285.         tmp1 = d->CalculateReverseDHT();
  286.         for (i = 0; i < d->GetLength(); i++)
  287.         {
  288.             cout << "H(" << i + 1 << ") =  " << d->GetArrayElemnt(i);
  289.             cout << "-->  x(" << i + 1 << ") = " << tmp1[i] << endl;
  290.         }
  291.         cout << "Do you want to save array of calculated values to a file?" << endl;
  292.         cout << "Enter 1 to save or anything else to continue:" << endl;
  293.         action = -1;
  294.         cin >> action;
  295.         Utilities::ValidateInput();
  296.         if (action == 1) Utilities::OutputIntoFile(d->GetLength(), tmp1);
  297.         cout << "Do you want to set array of calculated values as your working array?" << endl;
  298.         cout << "Enter 1 to agree or anything else to continue:" << endl;
  299.         action = -1;
  300.         cin >> action;
  301.         Utilities::ValidateInput();
  302.         if (action == 1)
  303.         {
  304.             d->SetArray(d->GetLength(), tmp1);
  305.             cout << "Array of calculated values set as your working array." << endl;
  306.             return true;
  307.         }
  308.         delete tmp1;
  309.         return true;
  310.     }
  311.     case 3: //вычислить ДПФ в алгебраической форме на основе ДПХ
  312.     {
  313.         tmp1 = d->CalculateDFTRe();
  314.         tmp2 = d->CalculateDFTIm();
  315.         for (i = 0; i < d->GetLength(); i++)
  316.         {
  317.             cout << "x(" << i + 1 << ") =  " << d->GetArrayElemnt(i);
  318.             cout << "-->  " << tmp1[i] << " + i" << tmp2[i] << endl;
  319.         }
  320.         cout << "Do you want to save array of calculated values to a file?" << endl;
  321.         cout << "Enter 1 to save or anything else to continue:" << endl;
  322.         action = -1;
  323.         cin >> action;
  324.         Utilities::ValidateInput();
  325.         if (action == 1)
  326.         {
  327.             complex = new string[d->GetLength()];
  328.             for (i = 0; i < d->GetLength(); i++)
  329.             {
  330.                 complex[i] = to_string(tmp1[i]) + " + i" + to_string(tmp2[i]);
  331.             }
  332.             Utilities::OutputIntoFile(d->GetLength(), complex);
  333.             delete complex;
  334.         }
  335.         delete tmp1;
  336.         delete tmp2;
  337.         return true;
  338.     }
  339.     case 4: //вычислить ДПФ в показательной форме на основе ДПХ
  340.     {
  341.         tmp1 = d->CalculateAmp();
  342.         tmp2 = d->CalculatePhi();
  343.         for (i = 0; i < d->GetLength(); i++)
  344.         {
  345.             cout << "x(" << i + 1 << ") =  " << d->GetArrayElemnt(i);
  346.             cout << "-->  " << tmp1[i] << " * exp(" << tmp2[i] << ")" << endl;
  347.         }
  348.         cout << "Do you want to save array of calculated values to a file?" << endl;
  349.         cout << "Enter 1 to save or anything else to continue:" << endl;
  350.         action = -1;
  351.         cin >> action;
  352.         Utilities::ValidateInput();
  353.         if (action == 1)
  354.         {
  355.             complex = new string[d->GetLength()];
  356.             for (i = 0; i < d->GetLength(); i++)
  357.             {
  358.                 complex[i] = to_string(tmp1[i]) + " * exp(" + to_string(tmp2[i]) + ")";
  359.             }
  360.             Utilities::OutputIntoFile(d->GetLength(), complex);
  361.             delete complex;
  362.         }
  363.         delete tmp1;
  364.         delete tmp2;
  365.         return true;
  366.     }
  367.     case 5: //сохранить текущий (рабочий) массив в файл
  368.     {
  369.         cout << "Do you want to save initial array to a file?" << endl;
  370.         cout << "Enter 1 to save or anything else to continue:" << endl;
  371.         action = -1;
  372.         cin >> action;
  373.         Utilities::ValidateInput();
  374.         if (action == 1) Utilities::OutputIntoFile(d->GetLength(), d->GetArray());
  375.         return true;
  376.     }
  377.     default:
  378.     {
  379.         cout << "Incorrect input format." << endl << endl;
  380.         return true;
  381.     }
  382.     }
  383. }
  384. double *Utilities::InputFromFile(int *length)
  385. {
  386.     ifstream in;
  387.     int i = -1;
  388.     double *arr;
  389.     string FileName, tmp;
  390.     while(true)
  391.     {
  392.         cout << "Enter file name:" << endl;
  393.         cin >> FileName;
  394.         in.open(FileName); //Пытаемся открыть файл для чтения
  395.         if (!in) //Если не удалось открыть файл
  396.         {
  397.             cout << "Couldn't open file." << endl;
  398.             cout << "If you want to try again, enter 1. If you want to enter array another way, enter anything but 1." << endl;
  399.             cin >> i;
  400.             if (i == 1){continue;}
  401.             else{return nullptr;}
  402.         }
  403.         else break;
  404.     }
  405.     in >> tmp;
  406.     try
  407.     {
  408.         *length = stoi(tmp);
  409.         if (*length <= 0) throw - 1;
  410.     }
  411.     catch (...)
  412.     {
  413.         cout << "Incorrect data in file" << endl;
  414.         in.close();
  415.         return nullptr;
  416.     }
  417.     arr = new double[*length];
  418.     for (i = 0; i < *length; i++)
  419.     {
  420.         in >> tmp;
  421.         try{arr[i] = stod(tmp);}
  422.         catch (...)
  423.         {
  424.             cout << "Incorrect data in file" << endl;
  425.             in.close();
  426.             delete arr;
  427.             return nullptr;
  428.         }
  429.     }
  430.     in.close();
  431.     cout << "Successfully entered from file." << endl;
  432.     return arr;
  433. }
  434. double *Utilities::InputFromFile(int length)
  435. {
  436.     ifstream in;
  437.     int i = -1;
  438.     double *arr;
  439.     string FileName, tmp;
  440.     while (true)
  441.     {
  442.         cout << "Enter file name:" << endl;
  443.         cin >> FileName;
  444.         in.open(FileName); //Пытаемся открыть файл для чтения
  445.         if (!in) //Если не удалось открыть файл
  446.         {
  447.             cout << "Couldn't open file." << endl;
  448.             cout << "If you want to try again, enter 1. If you want to enter array another way, enter anything but 1." << endl;
  449.             cin >> i;
  450.             if (i == 1){continue;}
  451.             else{return nullptr;}
  452.         }
  453.         else break;
  454.     }
  455.     arr = new double[length];
  456.     for (i = 0; i < length; i++)
  457.     {
  458.         in >> tmp;
  459.         try{arr[i] = stod(tmp);}
  460.         catch (...)
  461.         {
  462.             cout << "Incorrect data in file" << endl;
  463.             in.close();
  464.             delete arr;
  465.             return nullptr;
  466.         }
  467.     }
  468.     in.close();
  469.     cout << "Successfully entered from file." << endl;
  470.     return arr;
  471. }
  472. void Utilities::OutputIntoFile(int length, double *arr)
  473. {
  474.     int i = -1;
  475.     ofstream out;
  476.     string FileName;
  477.     while (true)
  478.     {
  479.         cout << "Enter file name:" << endl;
  480.         cin >> FileName;
  481.         out.open(FileName); //Пытаемся открыть файл для записи
  482.         if (!out) //Если не удалось открыть файл
  483.         {
  484.             cout << "Couldn't open file." << endl;
  485.             cout << "If you want to try again, enter 1. If you want to abandon saving array to a file, enter anything but 1." << endl;
  486.             cin >> i;
  487.             if (i == 1){continue;}
  488.             else{return;}
  489.         }
  490.         else break;
  491.     }
  492.     for (i = 0; i < length; i++){out << arr[i] << endl;}
  493.     cout << "Successfully saved in the file." << endl;
  494. }
  495. void Utilities::OutputIntoFile(int length, string *arr)
  496. {
  497.     int i = -1;
  498.     ofstream out;
  499.     string FileName;
  500.     while (true)
  501.     {
  502.         cout << "Enter file name:" << endl;
  503.         cin >> FileName;
  504.         out.open(FileName); //Пытаемся открыть файл для записи
  505.         if (!out) //Если не удалось открыть файл
  506.         {
  507.             cout << "Couldn't open file." << endl;
  508.             cout << "If you want to try again, enter 1. If you want to abandon saving array to a file, enter anything but 1." << endl;
  509.             cin >> i;
  510.             if (i == 1){continue;}
  511.             else{return;}
  512.         }
  513.         else break;
  514.     }
  515.     for (i = 0; i < length; i++){out << arr[i] << endl;}
  516.     cout << "Successfully saved in the file." << endl;
  517. }
  518.  
  519.  
  520. int main()
  521. {
  522.     int action;
  523.     bool flag = true;
  524.     cout << "This program calculates DHT and its various parameters." << endl;
  525.     while (flag)
  526.     {
  527.         cout << "You must enter or generate an array of numbers to work with." << endl;
  528.         cout << "Please select your action: " << endl << "1 - generate array from preprogrammed functions;" << endl;
  529.         cout << "2 - enter an array from keyboard" << endl << "3 - enter an array from file" << endl;
  530.         cout << "0 - exit program" << endl << "Action:" << endl;
  531.         cin >> action;
  532.         if (!Utilities::ValidateInput()) continue; //Если введнео не число
  533.  
  534.         switch (action)
  535.         {
  536.         case 0:
  537.         {
  538.             cout << "Exiting the program" << endl;
  539.             flag = false;
  540.             break;
  541.         }
  542.         case 1: //Генерация массива
  543.         {
  544.             int length;
  545.             double *arr = Utilities::ChooseSequence(&length);
  546.             if (arr == nullptr) break;
  547.             cout << "Generated array is: " << endl;
  548.             Utilities::PrintArray(length, arr);
  549.             DHT d(length, arr);
  550.             while (Utilities::ActionWithDHT(&d));
  551.             break;
  552.         }
  553.         case 2: //Ввод с клавиатуры
  554.         {
  555.             int length, i;
  556.             double tmp;
  557.             cout << "Enter length of the array:" << endl;
  558.             cin >> length;
  559.             if (!Utilities::ValidateInput()) break; //Если введено не число
  560.             double *arr = new double[length];
  561.             for (i = 0; i < length; i++)
  562.             {
  563.                 cout << "Enter arr[" << i << "] = ";
  564.                 cin >> tmp;
  565.                 if (!Utilities::ValidateInput())
  566.                 {
  567.                     i--;
  568.                     continue;
  569.                 }
  570.                 arr[i] = tmp;
  571.             }
  572.             cout << endl << "Entered array is: " << endl;
  573.             Utilities::PrintArray(length, arr);
  574.             DHT d(length, arr);
  575.             while (Utilities::ActionWithDHT(&d));
  576.             break;
  577.         }
  578.         case 3: //Ввод из файла
  579.         {
  580.             int length;
  581.             cout << "Do you know length of the array?" << endl;
  582.             cout << "Enter it if you do, all numbers in file will be treated like array elements then." << endl;
  583.             cout << "Enter 0 if length of an array is the first number in file." << endl;
  584.             cout << "Length = ";
  585.             cin >> length;
  586.             if (!Utilities::ValidateInput()) break; //Если введено не число
  587.             double *arr;
  588.             if (length == 0) arr = Utilities::InputFromFile(&length);
  589.             else if (length > 0) arr = Utilities::InputFromFile(length);
  590.             else
  591.             {
  592.                 cout << "Incorrect input format." << endl << endl;
  593.                 break;
  594.             }
  595.             if (arr == nullptr)
  596.                 break;
  597.             cout << endl << "Entered array is: " << endl;
  598.             Utilities::PrintArray(length, arr);
  599.             DHT d(length, arr);
  600.             while (Utilities::ActionWithDHT(&d));
  601.             break;
  602.         }
  603.         default:{break;}
  604.         }
  605.     }
  606.     return 0;
  607. }
Add Comment
Please, Sign In to add comment