Почему мои алгоритмы Кули-Тьюки и грубой силы (Фурье) дают очень разные результаты? - PullRequest
0 голосов
/ 29 апреля 2019

Я закончил писать свой код алгоритма Фурье.Он реализует методы cooley-tukey и brute force (преобразование Фурье) в текстовый файл с одним столбцом для времени (индекс) и другим для температуры в Кельвинах (значение).Мой код принимает txt-файл, затем выполняет brute-force или cooley-tukey и, наконец, выводит его в виде txt-файла.Brute Force выпускает только реальные цифры, а Кули-Тьюки выводит как реальные, так и мнимые.

Я тоже совсем не знаком с физикой ... Я думаю, что это ошибка в математике:

Алгоритм грубой силы (файл .cpp):

      void Brute_force<T>::DFT(std::vector<double>* index,
        std::vector<double>* value, 
        std::vector<complex<double>> &result)
      {

      // For each output element
      for (size_t freq = 0; freq < index->size(); freq += 
      this->frequency_step)
      {
        complex<double> sum(0.0, 0.0);
        // For each input element
        for (size_t time = 0; time < index->size(); time++)
        {
          double angle = 2 * M_PI * time * freq / index- 
          >size();
          sum = sum + index->at(time) * exp(-angle);
        }
        result.push_back(sum);
      }
    }

    template class Brute_force<double>;

Алгоритм Кули-Тьюки (файл .cpp):

            void Cooley_tukey<T>::FFT(std::vector<T>* index, std::vector<T>* value, std::vector<complex<T>>& result)
            {
                std::cout << index->size() << std::endl;
                // Make copy of array and apply window
                for (unsigned int time = 0; time < index->size(); time++)
                {
                    result.push_back(index->at(time));
                    std::cout << result.at(time) << std::endl;
                    //temp.at(time) *= 1; // Window
                }

                // Start recursion function to split up the tasks
                FFT_REC(result, index->size());
            }


            template<typename T>
            void Cooley_tukey<T>::FFT_REC(std::vector<complex<T>>& result, int total_time)
            {
                // Check if it is split up enough
                if (total_time >= 2)
                {

                    // Split even and odds up
            std::vector<complex<T>> odd;
            std::vector<complex<T>> even;
            odd.reserve(total_time/2);
            even.reserve(total_time/2);
            for (int i = 0; i < total_time / 2; i++)
            {
                even.push_back(result.at(i*2));
                odd.push_back(result.at(i*2+1));
            }


                    // DFT portion of FFT - calculates after everything has been split up through FFT_REC
                    for (int frequency = 0; frequency < total_time / 2; frequency += this->frequency_step)
                    {
                        std::complex<T> t = exp(std::complex<T>(0, -2 * M_PI * frequency / total_time)) * odd.at(frequency);

                        //Result of Cooley-Tukey algorithm:
                            //*This gives us the frequency values at certain times
                        result.at(frequency) = even.at(frequency) + t;
                        result.at(total_time / 2 + frequency) = even.at(frequency) - t;

                    }
                }
            }

Результаты перебора (текстовый файл) (только его часть):

    6.003e+06 0
    736788 0
    344823 0
    224583 0
    166575 0
    132447 0
    109977 0
    94064.6 0
    82206.1 0
    73027.7 0
    65713.2 0
    59747.3 0

Кули-Результаты Tukey (текстовый файл) (только часть):

      4001 0
      4004.99 -6.28946
      4008.96 -12.5914
      4012.91 -18.9058
      4016.84 -25.2326
      4020.75 -31.5716
      4024.64 -37.9229
      4028.51 -44.2865
      4032.36 -50.6621
      4036.19 -57.0498
      4040 -63.4494

1 Ответ

2 голосов
/ 29 апреля 2019

Реальный результат весьма подозрительный.Поэтому я быстро взглянул на этот код.

Вам не хватает i в вашем показателе.Вы вычисляете показатель реальной стоимости, приводя к реальной стоимости.Вам нужно использовать

std::exp(std::complex<double>{0,-angle})

Я не смотрел на остальной код.Как я сказал в комментарии, вы должны сравнить свои результаты с результатами существующих инструментов, которые, по вашему мнению, являются правильными (MATLAB, Python / NumPy и т. Д.), Чтобы сузить формулировку проблемы.

...