Mercurial > octave-nkf
diff src/DLD-FUNCTIONS/fftw_wisdom.cc @ 4776:adf8d68d7143 ss-2-1-54
[project @ 2004-02-16 20:32:20 by jwe]
author | jwe |
---|---|
date | Mon, 16 Feb 2004 20:32:20 +0000 |
parents | |
children | 02c748eb2ddc |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/DLD-FUNCTIONS/fftw_wisdom.cc Mon Feb 16 20:32:20 2004 +0000 @@ -0,0 +1,198 @@ +/* + +Copyright (C) 2004 David Bateman + +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 + +#if defined (HAVE_FFTW3) +#include <fftw3.h> +#endif + +#include "defaults.h" +#include "defun-dld.h" +#include "error.h" +#include "file-ops.h" +#include "gripes.h" +#include "lo-mappers.h" +#include "lo-sstream.h" +#include "oct-env.h" +#include "oct-obj.h" +#include "sighandlers.h" +#include "utils.h" + +DEFUN_DLD (fftw_wisdom, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} fftw_wisdom (@var{file}, @var{ow})\n\ +@deftypefnx {Loadable Function} {} fftw_wisdom (@var{n})\n\ +\n\ +This function is used to manipulate the FFTW wisdom data. It can\n\ +be used to load previously stored wisdom from a file, create wisdom\n\ +needed by Octave and to save the current wisdom to a file. Wisdom\n\ +data can be used to significantly accelerate the calculation of the FFTs,\n\ +but is only profitable if the same FFT is called many times due to the\n\ +overhead in calculating the wisdom data.\n\ +\n\ +Called with a single string argument, @code{fftw_wisdom (@var{file})}\n\ +will load the wisdom data found in @var{file}. If @var{file} does\n\ +not exist, then the current wisdom used by FFTW is saved to this\n\ +file. If the flag @var{ow} is non-zero, then even if @var{file}\n\ +exists, it will be overwritten.\n\ +\n\ +It is assumed that each row of @var{n} represents the size of a FFT for\n\ +which it is desired to pre-calculate the wisdom needed to accelerate it.\n\ +Any value of the matrix that is less than 1, is assumed to indicate an\n\ +absent dimension. That is\n\ +\n\ +@example\n\ +fftw_wisdom ([102, 0, 0; 103, 103, 0; 102, 103, 105]);\n\ +a = fft (rand (1,102));\n\ +b = fft (rand (103,103));\n\ +c = fftn (rand ([102, 103, 105]));\n\ +@end example\n\ +\n\ +calculates the wisdom necessary to accelerate the 103, 102x102 and\n\ +the 102x103x105 FFTs. Note that calculated wisdom will be lost when\n\ +when restarting Octave. However, if it is saved as discussed above, it\n\ +can be reloaded. Also, any system-wide wisdom file that has been found\n\ +will also be used. Saved wisdom files should not be used on different\n\ +platforms since they will not be efficient and the point of calculating\n\ +the wisdom is lost.\n\ +\n\ +Note that the program @code{fftw-wisdom} supplied with FFTW can equally\n\ +be used to create a file containing wisdom that can be imported into\n\ +Octave.\n\ +@end deftypefn\n\ +@seealso {fft, ifft, fft2, ifft2, fftn, ifftn}") +{ + octave_value retval; + +#if defined (HAVE_FFTW3) + + int nargin = args.length(); + + if (nargin < 1 || nargin > 2) + { + print_usage ("fftw_wisdom"); + return retval; + } + + if (args(0).is_string ()) + { + bool overwrite = false; + + if (nargin != 1) + { + double dval = args (1).double_value (); + if (NINT (dval) != 0) + overwrite = true; + } + + std::string wisdom = octave_env::make_absolute + (Vload_path_dir_path.find_first_of (args(0).string_value ().c_str ()), + octave_env::getcwd ()); + + if (wisdom.empty () || overwrite) + { + FILE *ofile = fopen (wisdom.c_str (), "wb"); + fftw_export_wisdom_to_file (ofile); + fclose (ofile); + } + else + { + FILE *ifile = fopen (wisdom.c_str (), "r"); + if (! fftw_import_wisdom_from_file (ifile)) + error ("fftw_wisdom: can not import wisdom from file"); + fclose (ifile); + } + + } + else + { + Matrix m = args (0).matrix_value (); + + if (error_state) + { + error ("fftw_wisdom: argument must be a matrix or a string"); + return retval; + } + + std::string name = file_ops::tempnam ("", "oct-"); + + if (name.empty ()) + { + error ("fftw_wisdom: can not open temporary file"); + return retval; + } + + OSSTREAM cmd_buf; + cmd_buf << Vfftw_wisdom_prog << " -n -o \"" << name << "\""; + + for (int k = 0; k < m.rows (); k++) + { + bool first = true; + + cmd_buf << " "; + + // Note reversal of dimensions for column major storage in FFTW + for (int j = m.columns()-1; j >= 0; j--) + if (NINT(m(k,j)) > 0) + { + if (first) + first = false; + else + cmd_buf << "x"; + cmd_buf << NINT(m(k,j)) ; + } + } + + cmd_buf << OSSTREAM_ENDS; + + volatile octave_interrupt_handler old_interrupt_handler + = octave_ignore_interrupts (); + + int status = system (OSSTREAM_C_STR (cmd_buf)); + + OSSTREAM_FREEZE (cmd_buf); + + octave_set_interrupt_handler (old_interrupt_handler); + + if (WIFEXITED (status)) + { + FILE *ifile = fopen (name.c_str (), "r"); + if (! fftw_import_wisdom_from_file (ifile)) + error ("fftw_wisdom: can not import wisdom from temporary file"); + fclose (ifile); + } + else + error ("fftw_wisdom: error running %s", Vfftw_wisdom_prog.c_str ()); + + } + +#else + + error ("fftw_wisdom: this copy of Octave was not configured to use FFTW3"); + +#endif + + return retval; +}