6
$\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$

2 Answers 2

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$
3
  • $\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$ Apr 29, 2016 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$ Apr 29, 2016 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$ Apr 29, 2016 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$
1
  • $\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$ Apr 29, 2016 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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