7

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.

user3605620
  • 226
  • 1
  • 2
  • 7

2 Answers2

3

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;
  }
} 
Bill Greene
  • 6,064
  • 1
  • 16
  • 24
  • 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. – user3605620 Apr 29 '16 at 22:19
  • I built the code above with Visual Studio Express 2013, x64. I used BOOST 1.57 and Eigen 3.2.6. – Bill Greene Apr 29 '16 at 22:37
  • 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 http://stackoverflow.com/questions/21737186/how-to-use-complex-numbers-with-boostmultiprecisionmpfr?rq=1 Any suggestions? – user3605620 Apr 29 '16 at 23:57
1

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/)

gpavanb
  • 572
  • 2
  • 15
  • 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... – user3605620 Apr 29 '16 at 08:05