//
// 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 "fft_sin.h"
#include "tridiag_ldlt.h"
#include "row_col.h"
template <typename T>
std::valarray<T> fish2d_fft(size_t m, const std::valarray<T>& b) {
  using namespace std;
  valarray<T> tilde_b(b.size()), tilde_u(b.size()), u(b.size());
  col_type col(m-1);
  for (size_t j = 0; j < m-1; j++) {
    valarray<T> bj = b[col(j)];
    tilde_b[col(j)] = (2./m)*fft_sin(bj);
  }
  row_type row(m-1);
  const T pi = acos(T(-1));
  for (size_t k = 0; k < m-1; k++) {
    tridiag<T> poisson_1d (m-1, 4 - 2*cos((k+1)*pi/m), -1);
    tridiag_ldlt<T> factorized_1d (poisson_1d);
    tilde_u[row(k)] = factorized_1d.solve (tilde_b [row(k)]);
  }
  for (size_t j = 0; j < m-1; j++) {
    valarray<T> tilde_uj = tilde_u[col(j)];
    u[col(j)] = fft_sin(tilde_uj);
  }
  return u;
}
