Mercurial > hg > octave-lyh
view liboctave/oct-fftw.cc @ 3928:e8627dc4bdf2
[project @ 2002-05-03 19:56:01 by jwe]
author | jwe |
---|---|
date | Fri, 03 May 2002 19:56:02 +0000 |
parents | 24bf1bcbba8a |
children | ccfbd6047a54 |
line wrap: on
line source
/* This file is part of Octave. Octave 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 2, or (at your option) any later version. Octave 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 Octave; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #ifdef HAVE_FFTW #include "oct-fftw.h" #include "lo-error.h" // Helper class to create and cache fftw plans for both 1d and 2d. This // implementation uses FFTW_ESTIMATE to create the plans, which in theory // is suboptimal, but provides quite reasonable performance. Future // enhancement will be to add a dynamically loadable interface ("fftw") // to manipulate fftw wisdom so that users may choose the appropriate // planner. class octave_fftw_planner { public: octave_fftw_planner (); fftw_plan create_plan (fftw_direction, size_t); fftwnd_plan create_plan2d (fftw_direction, size_t, size_t); private: int plan_flags; fftw_plan plan[2]; fftwnd_plan plan2d[2]; size_t n[2]; size_t n2d[2][2]; }; octave_fftw_planner::octave_fftw_planner () { plan_flags = FFTW_ESTIMATE; plan[0] = plan[1] = 0; plan2d[0] = plan2d[1] = 0; n[0] = n[1] = 0; n2d[0][0] = n2d[0][1] = n2d[1][0] = n2d[1][1] = 0; } fftw_plan octave_fftw_planner::create_plan (fftw_direction dir, size_t npts) { size_t which = (dir == FFTW_FORWARD) ? 0 : 1; fftw_plan *cur_plan_p = &plan[which]; bool create_new_plan = false; if (plan[which] == 0 || n[which] != npts) { create_new_plan = true; n[which] = npts; } if (create_new_plan) { if (*cur_plan_p) fftw_destroy_plan (*cur_plan_p); *cur_plan_p = fftw_create_plan (npts, dir, plan_flags); if (*cur_plan_p == 0) (*current_liboctave_error_handler) ("Error creating fftw plan"); } return *cur_plan_p; } fftwnd_plan octave_fftw_planner::create_plan2d (fftw_direction dir, size_t nrows, size_t ncols) { size_t which = (dir == FFTW_FORWARD) ? 0 : 1; fftwnd_plan *cur_plan_p = &plan2d[which]; bool create_new_plan = false; if (plan2d[which] == 0 || n2d[which][0] != nrows || n2d[which][1] != ncols) { create_new_plan = true; n2d[which][0] = nrows; n2d[which][1] = ncols; } if (create_new_plan) { if (*cur_plan_p) fftwnd_destroy_plan (*cur_plan_p); *cur_plan_p = fftw2d_create_plan (nrows, ncols, dir, plan_flags | FFTW_IN_PLACE); if (*cur_plan_p == 0) (*current_liboctave_error_handler) ("Error creating 2d fftw plan"); } return *cur_plan_p; } static octave_fftw_planner fftw_planner; int octave_fftw::fft (const Complex *in, Complex *out, size_t npts) { fftw_one (fftw_planner.create_plan (FFTW_FORWARD, npts), reinterpret_cast<fftw_complex *> (const_cast<Complex *> (in)), reinterpret_cast<fftw_complex *> (out)); return 0; } int octave_fftw::ifft (const Complex *in, Complex *out, size_t npts) { fftw_one (fftw_planner.create_plan (FFTW_BACKWARD, npts), reinterpret_cast<fftw_complex *> (const_cast<Complex *> (in)), reinterpret_cast<fftw_complex *> (out)); const Complex scale = npts; for (size_t i = 0; i < npts; i++) out[i] /= scale; return 0; } int octave_fftw::fft2d (Complex *inout, size_t nr, size_t nc) { fftwnd_one (fftw_planner.create_plan2d (FFTW_FORWARD, nr, nc), reinterpret_cast<fftw_complex *> (inout), 0); return 0; } int octave_fftw::ifft2d (Complex *inout, size_t nr, size_t nc) { fftwnd_one (fftw_planner.create_plan2d (FFTW_BACKWARD, nr, nc), reinterpret_cast<fftw_complex *> (inout), 0); const size_t npts = nr * nc; const Complex scale = npts; for (size_t i = 0; i < npts; i++) inout[i] /= scale; return 0; } #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */