5
$\begingroup$

I am looking for a C++ library for Fast Fourier Transform (FFT) in high precision (e.g., using high precision real data types similar to mpfr_t in MPFR or cpp_dec_float in BOOST). The preference is for open-source or, if not available, at least "free for academic research" libraries. I have tried standard precision optimized implementations such as FFTW in long double, but that proved to be insufficient. An ideal solution would link to BOOST since I am using special function implementations from that library.

$\endgroup$
3
$\begingroup$

You might want to take a look at the Eigen C++ matrix class library.

http://eigen.tuxfamily.org/index.php?title=Main_Page

There is an FFT class in the unsupported section of the library but my impression is that it is relatively mature.

Here is a snippet of code using this FFT class with the BOOST multi-precision classes.

#include <vector>
#include <cmath>
#include <complex>
#include <iostream>
#include <Eigen/Core>
#include <unsupported/Eigen/FFT>

#include <boost/multiprecision/cpp_dec_float.hpp>

using boost::multiprecision::cpp_dec_float_50;

using std::cout;
using std::endl;

void twoSinTest() {
  const double pi = 2.*std::acos(0.);
#if 0
  typedef double FFTFloat;
#else
  typedef cpp_dec_float_50 FFTFloat;
#endif
  double Fs = 1000;            // Sampling frequency
  double T = 1 / Fs;           // Sampling period
  int L = 1000;               // Length of signal
  std::vector<FFTFloat> timebuf(L);
  typedef std::complex<FFTFloat> C;
  std::vector<C> freqbuf;
  double t = 0;
  for (int i = 0; i < L; i++) {
    timebuf[i] = 0.7*std::sin(2 * pi * 50 * t) + std::sin(2 * pi * 120 * t);
    t += T;
  }
  Eigen::FFT<FFTFloat> fft;
  fft.fwd(freqbuf, timebuf);
  cout << freqbuf.size() << endl;
  for (int i = 0; i < freqbuf.size(); i++) {
    const C &f = freqbuf[i];
    cout << i << " " << f << endl;
  }
} 
$\endgroup$
  • $\begingroup$ Thanks much for the code! What compiler/STL/Boost versions have you used? I am running into some template instantiation errors and I think it is cpp_dec_float_50 assignment to std::complex<cpp_dec_float_50> someplace inside FFT code. $\endgroup$ – user3605620 Apr 29 '16 at 22:19
  • $\begingroup$ I built the code above with Visual Studio Express 2013, x64. I used BOOST 1.57 and Eigen 3.2.6. $\endgroup$ – Bill Greene Apr 29 '16 at 22:37
  • $\begingroup$ Hmm, on gcc-5 (under Ubuntu) your code works with float128 bu not with ccp_dec_float50 or mpr_float_50. The issue seems to be related to stackoverflow.com/questions/21737186/… Any suggestions? $\endgroup$ – user3605620 Apr 29 '16 at 23:57
1
$\begingroup$

ARPREC (http://crd-legacy.lbl.gov/~dhbailey/mpdist/) is an arbitrary-precision C++/Fortran package and contains an FFT implementation.

Apfloat (http://www.apfloat.org/apfloat/) is another C++ arbitrary-precision library which contains FFT.

Both of the above packages have been included in the FFTW benchmark (http://www.fftw.org/speed/)

$\endgroup$
  • $\begingroup$ I had an impression that the FFT subroutine in ARPREC was not multi-precision. And it does not seem to be maintained anymore. Let me mook into Apfloat though... $\endgroup$ – user3605620 Apr 29 '16 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.