//
// This file is part of the book "Language C++ et calcul scientifique"
//
// Copyright (C) 2005-2012 Pierre Saramito <Pierre.Saramito@imag.fr>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include <valarray>
template <typename T>
void fft (const T& w,
  const std::valarray<T>& f, std::valarray<T>& F)
{
  size_t n = f.size();
  if (n == 0) return;
  if (n == 1) { F[0] = f[0]; return; }
  size_t m = n/2;
  std::valarray<T> f0(m), f1(m), F0(m), F1(m);
  for (size_t k = 0; k < m; k++) {
    f0[k] = f[2*k];
    f1[k] = f[2*k+1];
  }
  fft (w*w, f0, F0);
  fft (w*w, f1, F1);
  T wk = 1;
  for (size_t k = 0; k < m; k++) {
    F[k]   = 0.5*(F0[k] + wk*F1[k]);
    F[m+k] = 0.5*(F0[k] - wk*F1[k]);
    wk     = w*wk;
  }
}
