Guest User

Untitled

a guest
Oct 24th, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.58 KB | None | 0 0
  1. let (RL_Output, IM_Output) = Some_Swift_Function([1,2,-3,4], [-4,3,2,1]) // INPUT RL & IM
  2. print(RL_Output)
  3. print(IM_Output)
  4.  
  5. // RL_Output = [4, 6, -8, 2] //Answer (REAL)
  6. // IM_Output = [2, -4, -6, -8] //Answer (IMAG)
  7.  
  8. //FftRealPairTest.cpp
  9. #include <algorithm>
  10. #include <cmath>
  11. #include <cstdlib>
  12. #include <iomanip>
  13. #include <iostream>
  14. #include <random>
  15. #include <vector>
  16. #include "FftRealPair.hpp"
  17.  
  18. using std::cout;
  19. using std::endl;
  20. using std::vector;
  21.  
  22. int main() {
  23.     vector<double> inputreal({1,2,-3,4});
  24.  
  25.     vector<double> inputimag({-4,3,2,1});
  26.  
  27.     vector<double> actualoutreal(inputreal);
  28.  
  29.     vector<double> actualoutimag(inputimag);
  30.  
  31.     Fft::transform(actualoutreal, actualoutimag);
  32.  
  33.     std::cout << "REAL:" << std::endl;
  34.     for (int i = 0; i < inputimag.size(); ++i)
  35.     {
  36.         std::cout << actualoutreal[i] << std::endl;
  37.     }
  38.  
  39.  
  40.     std::cout << "IMAG" << std::endl;
  41.     for (int i = 0; i < inputimag.size(); ++i)
  42.     {
  43.         std::cout << actualoutimag[i] << std::endl;
  44.     }
  45.     
  46. }
  47.  
  48.  
  49. /////////////////////////////////////////////////
  50.  
  51. //FftRealPair.cpp
  52. /*
  53.  * Free FFT and convolution (C++)
  54.  *
  55.  * Copyright (c) 2017 Project Nayuki. (MIT License)
  56.  * https://www.nayuki.io/page/free-small-fft-in-multiple-languages
  57.  *
  58.  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  59.  * this software and associated documentation files (the "Software"), to deal in
  60.  * the Software without restriction, including without limitation the rights to
  61.  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  62.  * the Software, and to permit persons to whom the Software is furnished to do so,
  63.  * subject to the following conditions:
  64.  * - The above copyright notice and this permission notice shall be included in
  65.  *   all copies or substantial portions of the Software.
  66.  * - The Software is provided "as is", without warranty of any kind, express or
  67.  *   implied, including but not limited to the warranties of merchantability,
  68.  *   fitness for a particular purpose and noninfringement. In no event shall the
  69.  *   authors or copyright holders be liable for any claim, damages or other
  70.  *   liability, whether in an action of contract, tort or otherwise, arising from,
  71.  *   out of or in connection with the Software or the use or other dealings in the
  72.  *   Software.
  73.  */
  74.  
  75. #include <algorithm>
  76. #include <cmath>
  77. #include <cstddef>
  78. #include <cstdint>
  79. #include "FftRealPair.hpp"
  80.  
  81. using std::size_t;
  82. using std::vector;
  83.  
  84.  
  85. // Private function prototypes
  86. static size_t reverseBits(size_t x, int n);
  87.  
  88.  
  89. void Fft::transform(vector<double> &real, vector<double> &imag) {
  90.     size_t n = real.size();
  91.     if (n != imag.size())
  92.         throw "Mismatched lengths";
  93.     if (n == 0)
  94.         return;
  95.     else if ((n & (n - 1)) == 0)  // Is power of 2
  96.         transformRadix2(real, imag);
  97.     else  // More complicated algorithm for arbitrary sizes
  98.         transformBluestein(real, imag);
  99. }
  100.  
  101.  
  102. void Fft::inverseTransform(vector<double> &real, vector<double> &imag) {
  103.     transform(imag, real);
  104. }
  105.  
  106.  
  107. void Fft::transformRadix2(vector<double> &real, vector<double> &imag) {
  108.     // Length variables
  109.     size_t n = real.size();
  110.     if (n != imag.size())
  111.         throw "Mismatched lengths";
  112.     int levels = 0;  // Compute levels = floor(log2(n))
  113.     for (size_t temp = n; temp > 1U; temp >>= 1)
  114.         levels++;
  115.     if (static_cast<size_t>(1U) << levels != n)
  116.         throw "Length is not a power of 2";
  117.  
  118.     // Trignometric tables
  119.     vector<double> cosTable(n / 2);
  120.     vector<double> sinTable(n / 2);
  121.     for (size_t i = 0; i < n / 2; i++) {
  122.         cosTable[i] = std::cos(2 * M_PI * i / n);
  123.         sinTable[i] = std::sin(2 * M_PI * i / n);
  124.     }
  125.  
  126.     // Bit-reversed addressing permutation
  127.     for (size_t i = 0; i < n; i++) {
  128.         size_t j = reverseBits(i, levels);
  129.         if (j > i) {
  130.             std::swap(real[i], real[j]);
  131.             std::swap(imag[i], imag[j]);
  132.         }
  133.     }
  134.  
  135.     // Cooley-Tukey decimation-in-time radix-2 FFT
  136.     for (size_t size = 2; size <= n; size *= 2) {
  137.         size_t halfsize = size / 2;
  138.         size_t tablestep = n / size;
  139.         for (size_t i = 0; i < n; i += size) {
  140.             for (size_t j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
  141.                 size_t l = j + halfsize;
  142.                 double tpre =  real[l] * cosTable[k] + imag[l] * sinTable[k];
  143.                 double tpim = -real[l] * sinTable[k] + imag[l] * cosTable[k];
  144.                 real[l] = real[j] - tpre;
  145.                 imag[l] = imag[j] - tpim;
  146.                 real[j] += tpre;
  147.                 imag[j] += tpim;
  148.             }
  149.         }
  150.         if (size == n)  // Prevent overflow in 'size *= 2'
  151.             break;
  152.     }
  153. }
  154.  
  155.  
  156. void Fft::transformBluestein(vector<double> &real, vector<double> &imag) {
  157.     // Find a power-of-2 convolution length m such that m >= n * 2 + 1
  158.     size_t n = real.size();
  159.     if (n != imag.size())
  160.         throw "Mismatched lengths";
  161.     size_t m = 1;
  162.     while (m / 2 <= n) {
  163.         if (m > SIZE_MAX / 2)
  164.             throw "Vector too large";
  165.         m *= 2;
  166.     }
  167.  
  168.     // Trignometric tables
  169.     vector<double> cosTable(n), sinTable(n);
  170.     for (size_t i = 0; i < n; i++) {
  171.         unsigned long long temp = static_cast<unsigned long long>(i) * i;
  172.         temp %= static_cast<unsigned long long>(n) * 2;
  173.         double angle = M_PI * temp / n;
  174.         // Less accurate alternative if long long is unavailable: double angle = M_PI * i * i / n;
  175.         cosTable[i] = std::cos(angle);
  176.         sinTable[i] = std::sin(angle);
  177.     }
  178.  
  179.     // Temporary vectors and preprocessing
  180.     vector<double> areal(m), aimag(m);
  181.     for (size_t i = 0; i < n; i++) {
  182.         areal[i] =  real[i] * cosTable[i] + imag[i] * sinTable[i];
  183.         aimag[i] = -real[i] * sinTable[i] + imag[i] * cosTable[i];
  184.     }
  185.     vector<double> breal(m), bimag(m);
  186.     breal[0] = cosTable[0];
  187.     bimag[0] = sinTable[0];
  188.     for (size_t i = 1; i < n; i++) {
  189.         breal[i] = breal[m - i] = cosTable[i];
  190.         bimag[i] = bimag[m - i] = sinTable[i];
  191.     }
  192.  
  193.     // Convolution
  194.     vector<double> creal(m), cimag(m);
  195.     convolve(areal, aimag, breal, bimag, creal, cimag);
  196.  
  197.     // Postprocessing
  198.     for (size_t i = 0; i < n; i++) {
  199.         real[i] =  creal[i] * cosTable[i] + cimag[i] * sinTable[i];
  200.         imag[i] = -creal[i] * sinTable[i] + cimag[i] * cosTable[i];
  201.     }
  202. }
  203.  
  204.  
  205. void Fft::convolve(const vector<double> &x, const vector<double> &y, vector<double> &out) {
  206.     size_t n = x.size();
  207.     if (n != y.size() || n != out.size())
  208.         throw "Mismatched lengths";
  209.     vector<double> outimag(n);
  210.     convolve(x, vector<double>(n), y, vector<double>(n), out, outimag);
  211. }
  212.  
  213.  
  214. void Fft::convolve(
  215.                    const vector<double> &xreal, const vector<double> &ximag,
  216.                    const vector<double> &yreal, const vector<double> &yimag,
  217.                    vector<double> &outreal, vector<double> &outimag) {
  218.  
  219.     size_t n = xreal.size();
  220.     if (n != ximag.size() || n != yreal.size() || n != yimag.size()
  221.         || n != outreal.size() || n != outimag.size())
  222.         throw "Mismatched lengths";
  223.  
  224.     vector<double> xr(xreal);
  225.     vector<double> xi(ximag);
  226.     vector<double> yr(yreal);
  227.     vector<double> yi(yimag);
  228.     transform(xr, xi);
  229.     transform(yr, yi);
  230.     
  231.     for (size_t i = 0; i < n; i++) {
  232.         double temp = xr[i] * yr[i] - xi[i] * yi[i];
  233.         xi[i] = xi[i] * yr[i] + xr[i] * yi[i];
  234.         xr[i] = temp;
  235.     }
  236.     inverseTransform(xr, xi);
  237.     
  238.     for (size_t i = 0; i < n; i++) {  // Scaling (because this FFT implementation omits it)
  239.         outreal[i] = xr[i] / n;
  240.         outimag[i] = xi[i] / n;
  241.     }
  242. }
  243.  
  244.  
  245. static size_t reverseBits(size_t x, int n) {
  246.     size_t result = 0;
  247.     for (int i = 0; i < n; i++, x >>= 1)
  248.         result = (result << 1) | (x & 1U);
  249.     return result;
  250. }
  251.  
  252.  
  253.  
  254. ////////////////////////////////////////////////////
  255.  
  256.  
  257. //FftRealPair.hpp
  258.  
  259. /*
  260.  * Free FFT and convolution (C++)
  261.  *
  262.  * Copyright (c) 2017 Project Nayuki. (MIT License)
  263.  * https://www.nayuki.io/page/free-small-fft-in-multiple-languages
  264.  *
  265.  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  266.  * this software and associated documentation files (the "Software"), to deal in
  267.  * the Software without restriction, including without limitation the rights to
  268.  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  269.  * the Software, and to permit persons to whom the Software is furnished to do so,
  270.  * subject to the following conditions:
  271.  * - The above copyright notice and this permission notice shall be included in
  272.  *   all copies or substantial portions of the Software.
  273.  * - The Software is provided "as is", without warranty of any kind, express or
  274.  *   implied, including but not limited to the warranties of merchantability,
  275.  *   fitness for a particular purpose and noninfringement. In no event shall the
  276.  *   authors or copyright holders be liable for any claim, damages or other
  277.  *   liability, whether in an action of contract, tort or otherwise, arising from,
  278.  *   out of or in connection with the Software or the use or other dealings in the
  279.  *   Software.
  280.  */
  281.  
  282. #pragma once
  283.  
  284. #include <vector>
  285.  
  286.  
  287. namespace Fft {
  288.  
  289.     /*
  290.      * Computes the discrete Fourier transform (DFT) of the given complex vector, storing the result back into the vector.
  291.      * The vector can have any length. This is a wrapper function.
  292.      */
  293.     void transform(std::vector<double> &real, std::vector<double> &imag);
  294.  
  295.  
  296.     /*
  297.      * Computes the inverse discrete Fourier transform (IDFT) of the given complex vector, storing the result back into the vector.
  298.      * The vector can have any length. This is a wrapper function. This transform does not perform scaling, so the inverse is not a true inverse.
  299.      */
  300.     void inverseTransform(std::vector<double> &real, std::vector<double> &imag);
  301.  
  302.  
  303.  
  304.  
  305.  
  306.     /*
  307.      * Computes the discrete Fourier transform (DFT) of the given complex vector, storing the result back into the vector.
  308.      * The vector's length must be a power of 2. Uses the Cooley-Tukey decimation-in-time radix-2 algorithm.
  309.      */
  310.     void transformRadix2(std::vector<double> &real, std::vector<double> &imag);
  311.  
  312.  
  313.     /*
  314.      * Computes the discrete Fourier transform (DFT) of the given complex vector, storing the result back into the vector.
  315.      * The vector can have any length. This requires the convolution function, which in turn requires the radix-2 FFT function.
  316.      * Uses Bluestein's chirp z-transform algorithm.
  317.      */
  318.     void transformBluestein(std::vector<double> &real, std::vector<double> &imag);
  319.  
  320.  
  321.     /*
  322.      * Computes the circular convolution of the given real vectors. Each vector's length must be the same.
  323.      */
  324.     void convolve(const std::vector<double> &x, const std::vector<double> &y, std::vector<double> &out);
  325.  
  326.  
  327.     /*
  328.      * Computes the circular convolution of the given complex vectors. Each vector's length must be the same.
  329.      */
  330.     void convolve(
  331.                   const std::vector<double> &xreal, const std::vector<double> &ximag,
  332.                   const std::vector<double> &yreal, const std::vector<double> &yimag,
  333.                   std::vector<double> &outreal, std::vector<double> &outimag);
  334.     
  335. }
Add Comment
Please, Sign In to add comment