Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include <iostream>
- #include <cmath>
- #include <string>
- #include <fstream>
- using namespace std;
- class DHT
- {
- private:
- double *arr;
- int length;
- public:
- DHT(int length, double *arr);
- ~DHT();
- void SetArray(int NewLength, double *NewArr);
- void SetLength(int length);
- int SetArrayElement(int index, double element);
- int GetLength();
- double *GetArray();
- double GetArrayElemnt(int index);
- double *CalculateDHT();
- double *CalculateReverseDHT();
- double *CalculateDFTRe();
- double *CalculateDFTIm();
- double *CalculateAmp();
- double *CalculatePhi();
- };
- class SequenceGenerator
- {
- public:
- static double *GenerateSin(int length, double Amp, double T, double offset);
- static double *GenerateDecreasingExp(int length);
- };
- class Utilities
- {
- public:
- static double *ChooseSequence(int *length);
- static bool ActionWithDHT(DHT *d);
- static double *InputFromFile(int *length);
- static double *InputFromFile(int length);
- static void OutputIntoFile(int length, double *arr);
- static void OutputIntoFile(int length, string *arr);
- static bool ValidateInput();
- static void PrintArray(int length, double *arr);
- };
- DHT::DHT(int length, double *arr)
- {
- this->length = length;
- this->arr = arr;
- }
- DHT::~DHT(){delete arr;}
- void DHT::SetArray(int NewLength, double *NewArr)
- {
- delete(arr);
- length = NewLength;
- arr = NewArr;
- }
- int DHT::SetArrayElement(int index, double element)
- {
- if (index >= 0 && index < length)
- {
- arr[index] = element;
- return 0;
- }
- return -1;
- }
- double *DHT::GetArray(){return arr;}
- void DHT::SetLength(int length){this->length = length;}
- int DHT::GetLength(){return length;}
- double DHT::GetArrayElemnt(int index)
- {
- if (index >= 0 && index < length){return arr[index];}
- return -1000000; //Код ошибки
- }
- double *DHT::CalculateDHT()
- {
- double *H = new double[length];
- double Pi = 4 * atan(1);
- int k, u;
- for (u = 0; u < length; u++) //u - номер частоты
- {
- H[u] = 0;
- for (k = 0; k < length; k++) //k - шаг по времени
- {
- H[u] += arr[k] * (cos(2 * Pi * k * u / length) + sin(2 * Pi * k * u / length));
- }
- H[u] *= 1 / sqrt(length);
- }
- return H;
- }
- double *DHT::CalculateReverseDHT()
- {
- double *x = new double[length];
- double Pi = 4 * atan(1);
- int k, u;
- for (k = 0; k < length; k++)
- {
- x[k] = 0;
- for (u = 0; u < length; u++)
- {
- x[k] += arr[u] * (cos(2 * Pi * k * u / length) + sin(2 * Pi * k * u / length));
- }
- x[k] *= 1 / sqrt(length);
- }
- return x;
- }
- double *DHT::CalculateDFTRe()
- {
- double *Re = new double[length];
- double *dht = CalculateDHT();
- int u;
- for (u = 0; u < length; u++){Re[u] = (dht[u] + dht[length - u]) / 2;}
- delete dht;
- return Re;
- }
- double *DHT::CalculateDFTIm()
- {
- double *Im = new double[length];
- double *dht = CalculateDHT();
- int u;
- for (u = 0; u < length; u++){Im[u] = (dht[u] - dht[length - u]) / 2;}
- delete dht;
- return Im;
- }
- double *DHT::CalculateAmp()
- {
- double *A = new double[length];
- double *Re = CalculateDFTRe();
- double *Im = CalculateDFTIm();
- int u;
- for (u = 0; u < length; u++){A[u] = hypot(Re[u], Im[u]);}
- delete(Re);
- delete(Im);
- return A;
- }
- double *DHT::CalculatePhi()
- {
- double *phi = new double[length];
- double *Re = CalculateDFTRe();
- double *Im = CalculateDFTIm();
- int u;
- for (u = 0; u < length; u++){phi[u] = atan2(Im[u], Re[u]);}
- delete(Re);
- delete(Im);
- return phi;
- }
- double *SequenceGenerator::GenerateSin(int length, double Amp, double T, double offset)
- {
- //A * sin(wt + phi), где A = Amp, w = 2 * Pi / T, phi = offset
- int i;
- double Pi = 4 * atan(1);
- double *arr = new double[length];
- for (i = 0; i < length; i++){arr[i] = Amp * sin(2 * Pi * i / T + offset);}
- return arr;
- }
- double *SequenceGenerator::GenerateDecreasingExp(int length)
- {
- //exp(-tau/2)
- int i;
- double *arr = new double[length];
- for (i = 1; i <= length; i++){arr[i - 1] = exp(- (double)i / 2);}
- return arr;
- }
- bool Utilities::ValidateInput()
- {
- if (cin.fail()) //Если не получилось извлечь данные из буффера в переменную
- {
- cout << "Incorrect input format." << endl << endl;
- cin.clear(); //Сбрасываем все флаги ошибок
- cin.ignore(32767, '\n'); //Удаляем все лишние символы из буффера
- return false;
- }
- cin.ignore(32767, '\n'); //Удаляем все лишние символы из буффера
- return true;
- }
- void Utilities::PrintArray(int length, double *arr)
- {
- int i;
- for (i = 0; i < length - 1; i++){cout << arr[i] << ";\t";}
- cout << arr[i] << "." << endl;
- }
- double *Utilities::ChooseSequence(int *length) {
- int l, choice;
- cout << "Enter length of the array:" << endl;
- cin >> l;
- if (!Utilities::ValidateInput()) return nullptr; //Если введено не число
- if (l < 0)
- {
- cout << "Incorrect input format." << endl << endl;
- return nullptr;
- }
- double *arr;
- cout << "Choose function with which array will be generated:" << endl;
- cout << "1 - A * sin(2 * Pi * i/T + phi); 2 - exp(-tau/2), tau changes from 1 to -length." << endl;
- cout << "Your choice:" << endl;
- cin >> choice;
- if (!Utilities::ValidateInput()) return nullptr;
- switch (choice) {
- case 1:
- {
- double A, T, offset;
- cout << "Enter the amplitude A = ";
- cin >> A;
- if (!Utilities::ValidateInput()) return nullptr;
- cout << "Enter the period T = ";
- cin >> T;
- if (!Utilities::ValidateInput()) return nullptr;
- cout << "Enter the initial frequency phi = ";
- cin >> offset;
- if (!Utilities::ValidateInput()) return nullptr;
- cout << "Your function is: " << A << " * sin(2 * Pi * i/" << T << " + " << offset << ")" << endl;
- arr = SequenceGenerator::GenerateSin(l, A, T, offset);
- *length = l;
- return arr;
- }
- case 2:
- {
- arr = SequenceGenerator::GenerateDecreasingExp(l);
- *length = l;
- return arr;
- }
- default:
- {
- cout << "Incorrect input format." << endl << endl;
- return nullptr;
- }
- }
- }
- bool Utilities::ActionWithDHT(DHT *d)
- {
- int action, i;
- double *tmp1, *tmp2;
- string *complex;
- cout << "Choose what action you want to perform with your array:" << endl;
- cout << "0 - exit into main menu; 1 - calculate DHT; 2 - calculate reverse DHT;" << endl;
- cout << "3 - calculate DFT in algebraic form based on DHT" << endl;
- cout << "4 - calculate DFT in exponential form based on DHT" << endl;
- cout << "5 - save current working array to a file." << endl;
- cout << "Your action:" << endl;
- cin >> action;
- if (!Utilities::ValidateInput()) return true;
- switch (action)
- {
- case 0: //выйти в главное меню
- {return false;}
- case 1: //вычислить ДПХ
- {
- tmp1 = d->CalculateDHT();
- for (i = 0; i < d->GetLength(); i++)
- {
- cout << "x(" << i + 1 << ") = " << d->GetArrayElemnt(i);
- cout << "--> H(" << i + 1 << ") = " << tmp1[i] << endl;
- }
- cout << "Do you want to save array of calculated values to a file?" << endl;
- cout << "Enter 1 to save or anything else to continue:" << endl;
- action = -1;
- cin >> action;
- Utilities::ValidateInput();
- if (action == 1) Utilities::OutputIntoFile(d->GetLength(), tmp1);
- cout << "Do you want to set array of calculated values as your working array?" << endl;
- cout << "Enter 1 to agree or anything else to continue:" << endl;
- action = -1;
- cin >> action;
- Utilities::ValidateInput();
- if (action == 1)
- {
- d->SetArray(d->GetLength(), tmp1);
- cout << "Array of calculated values set as your working array." << endl;
- return true;
- }
- delete tmp1;
- return true;
- }
- case 2: //вычислить обратное ДПХ
- {
- tmp1 = d->CalculateReverseDHT();
- for (i = 0; i < d->GetLength(); i++)
- {
- cout << "H(" << i + 1 << ") = " << d->GetArrayElemnt(i);
- cout << "--> x(" << i + 1 << ") = " << tmp1[i] << endl;
- }
- cout << "Do you want to save array of calculated values to a file?" << endl;
- cout << "Enter 1 to save or anything else to continue:" << endl;
- action = -1;
- cin >> action;
- Utilities::ValidateInput();
- if (action == 1) Utilities::OutputIntoFile(d->GetLength(), tmp1);
- cout << "Do you want to set array of calculated values as your working array?" << endl;
- cout << "Enter 1 to agree or anything else to continue:" << endl;
- action = -1;
- cin >> action;
- Utilities::ValidateInput();
- if (action == 1)
- {
- d->SetArray(d->GetLength(), tmp1);
- cout << "Array of calculated values set as your working array." << endl;
- return true;
- }
- delete tmp1;
- return true;
- }
- case 3: //вычислить ДПФ в алгебраической форме на основе ДПХ
- {
- tmp1 = d->CalculateDFTRe();
- tmp2 = d->CalculateDFTIm();
- for (i = 0; i < d->GetLength(); i++)
- {
- cout << "x(" << i + 1 << ") = " << d->GetArrayElemnt(i);
- cout << "--> " << tmp1[i] << " + i" << tmp2[i] << endl;
- }
- cout << "Do you want to save array of calculated values to a file?" << endl;
- cout << "Enter 1 to save or anything else to continue:" << endl;
- action = -1;
- cin >> action;
- Utilities::ValidateInput();
- if (action == 1)
- {
- complex = new string[d->GetLength()];
- for (i = 0; i < d->GetLength(); i++)
- {
- complex[i] = to_string(tmp1[i]) + " + i" + to_string(tmp2[i]);
- }
- Utilities::OutputIntoFile(d->GetLength(), complex);
- delete complex;
- }
- delete tmp1;
- delete tmp2;
- return true;
- }
- case 4: //вычислить ДПФ в показательной форме на основе ДПХ
- {
- tmp1 = d->CalculateAmp();
- tmp2 = d->CalculatePhi();
- for (i = 0; i < d->GetLength(); i++)
- {
- cout << "x(" << i + 1 << ") = " << d->GetArrayElemnt(i);
- cout << "--> " << tmp1[i] << " * exp(" << tmp2[i] << ")" << endl;
- }
- cout << "Do you want to save array of calculated values to a file?" << endl;
- cout << "Enter 1 to save or anything else to continue:" << endl;
- action = -1;
- cin >> action;
- Utilities::ValidateInput();
- if (action == 1)
- {
- complex = new string[d->GetLength()];
- for (i = 0; i < d->GetLength(); i++)
- {
- complex[i] = to_string(tmp1[i]) + " * exp(" + to_string(tmp2[i]) + ")";
- }
- Utilities::OutputIntoFile(d->GetLength(), complex);
- delete complex;
- }
- delete tmp1;
- delete tmp2;
- return true;
- }
- case 5: //сохранить текущий (рабочий) массив в файл
- {
- cout << "Do you want to save initial array to a file?" << endl;
- cout << "Enter 1 to save or anything else to continue:" << endl;
- action = -1;
- cin >> action;
- Utilities::ValidateInput();
- if (action == 1) Utilities::OutputIntoFile(d->GetLength(), d->GetArray());
- return true;
- }
- default:
- {
- cout << "Incorrect input format." << endl << endl;
- return true;
- }
- }
- }
- double *Utilities::InputFromFile(int *length)
- {
- ifstream in;
- int i = -1;
- double *arr;
- string FileName, tmp;
- while(true)
- {
- cout << "Enter file name:" << endl;
- cin >> FileName;
- in.open(FileName); //Пытаемся открыть файл для чтения
- if (!in) //Если не удалось открыть файл
- {
- cout << "Couldn't open file." << endl;
- cout << "If you want to try again, enter 1. If you want to enter array another way, enter anything but 1." << endl;
- cin >> i;
- if (i == 1){continue;}
- else{return nullptr;}
- }
- else break;
- }
- in >> tmp;
- try
- {
- *length = stoi(tmp);
- if (*length <= 0) throw - 1;
- }
- catch (...)
- {
- cout << "Incorrect data in file" << endl;
- in.close();
- return nullptr;
- }
- arr = new double[*length];
- for (i = 0; i < *length; i++)
- {
- in >> tmp;
- try{arr[i] = stod(tmp);}
- catch (...)
- {
- cout << "Incorrect data in file" << endl;
- in.close();
- delete arr;
- return nullptr;
- }
- }
- in.close();
- cout << "Successfully entered from file." << endl;
- return arr;
- }
- double *Utilities::InputFromFile(int length)
- {
- ifstream in;
- int i = -1;
- double *arr;
- string FileName, tmp;
- while (true)
- {
- cout << "Enter file name:" << endl;
- cin >> FileName;
- in.open(FileName); //Пытаемся открыть файл для чтения
- if (!in) //Если не удалось открыть файл
- {
- cout << "Couldn't open file." << endl;
- cout << "If you want to try again, enter 1. If you want to enter array another way, enter anything but 1." << endl;
- cin >> i;
- if (i == 1){continue;}
- else{return nullptr;}
- }
- else break;
- }
- arr = new double[length];
- for (i = 0; i < length; i++)
- {
- in >> tmp;
- try{arr[i] = stod(tmp);}
- catch (...)
- {
- cout << "Incorrect data in file" << endl;
- in.close();
- delete arr;
- return nullptr;
- }
- }
- in.close();
- cout << "Successfully entered from file." << endl;
- return arr;
- }
- void Utilities::OutputIntoFile(int length, double *arr)
- {
- int i = -1;
- ofstream out;
- string FileName;
- while (true)
- {
- cout << "Enter file name:" << endl;
- cin >> FileName;
- out.open(FileName); //Пытаемся открыть файл для записи
- if (!out) //Если не удалось открыть файл
- {
- cout << "Couldn't open file." << endl;
- cout << "If you want to try again, enter 1. If you want to abandon saving array to a file, enter anything but 1." << endl;
- cin >> i;
- if (i == 1){continue;}
- else{return;}
- }
- else break;
- }
- for (i = 0; i < length; i++){out << arr[i] << endl;}
- cout << "Successfully saved in the file." << endl;
- }
- void Utilities::OutputIntoFile(int length, string *arr)
- {
- int i = -1;
- ofstream out;
- string FileName;
- while (true)
- {
- cout << "Enter file name:" << endl;
- cin >> FileName;
- out.open(FileName); //Пытаемся открыть файл для записи
- if (!out) //Если не удалось открыть файл
- {
- cout << "Couldn't open file." << endl;
- cout << "If you want to try again, enter 1. If you want to abandon saving array to a file, enter anything but 1." << endl;
- cin >> i;
- if (i == 1){continue;}
- else{return;}
- }
- else break;
- }
- for (i = 0; i < length; i++){out << arr[i] << endl;}
- cout << "Successfully saved in the file." << endl;
- }
- int main()
- {
- int action;
- bool flag = true;
- cout << "This program calculates DHT and its various parameters." << endl;
- while (flag)
- {
- cout << "You must enter or generate an array of numbers to work with." << endl;
- cout << "Please select your action: " << endl << "1 - generate array from preprogrammed functions;" << endl;
- cout << "2 - enter an array from keyboard" << endl << "3 - enter an array from file" << endl;
- cout << "0 - exit program" << endl << "Action:" << endl;
- cin >> action;
- if (!Utilities::ValidateInput()) continue; //Если введнео не число
- switch (action)
- {
- case 0:
- {
- cout << "Exiting the program" << endl;
- flag = false;
- break;
- }
- case 1: //Генерация массива
- {
- int length;
- double *arr = Utilities::ChooseSequence(&length);
- if (arr == nullptr) break;
- cout << "Generated array is: " << endl;
- Utilities::PrintArray(length, arr);
- DHT d(length, arr);
- while (Utilities::ActionWithDHT(&d));
- break;
- }
- case 2: //Ввод с клавиатуры
- {
- int length, i;
- double tmp;
- cout << "Enter length of the array:" << endl;
- cin >> length;
- if (!Utilities::ValidateInput()) break; //Если введено не число
- double *arr = new double[length];
- for (i = 0; i < length; i++)
- {
- cout << "Enter arr[" << i << "] = ";
- cin >> tmp;
- if (!Utilities::ValidateInput())
- {
- i--;
- continue;
- }
- arr[i] = tmp;
- }
- cout << endl << "Entered array is: " << endl;
- Utilities::PrintArray(length, arr);
- DHT d(length, arr);
- while (Utilities::ActionWithDHT(&d));
- break;
- }
- case 3: //Ввод из файла
- {
- int length;
- cout << "Do you know length of the array?" << endl;
- cout << "Enter it if you do, all numbers in file will be treated like array elements then." << endl;
- cout << "Enter 0 if length of an array is the first number in file." << endl;
- cout << "Length = ";
- cin >> length;
- if (!Utilities::ValidateInput()) break; //Если введено не число
- double *arr;
- if (length == 0) arr = Utilities::InputFromFile(&length);
- else if (length > 0) arr = Utilities::InputFromFile(length);
- else
- {
- cout << "Incorrect input format." << endl << endl;
- break;
- }
- if (arr == nullptr)
- break;
- cout << endl << "Entered array is: " << endl;
- Utilities::PrintArray(length, arr);
- DHT d(length, arr);
- while (Utilities::ActionWithDHT(&d));
- break;
- }
- default:{break;}
- }
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment