Mercurial > octave
diff src/DLD-FUNCTIONS/fft.cc @ 4773:ccfbd6047a54
[project @ 2004-02-16 19:02:32 by jwe]
author | jwe |
---|---|
date | Mon, 16 Feb 2004 19:02:33 +0000 |
parents | ccfdb55c8156 |
children | 3dfdf6f36854 |
line wrap: on
line diff
--- a/src/DLD-FUNCTIONS/fft.cc Mon Feb 16 17:57:34 2004 +0000 +++ b/src/DLD-FUNCTIONS/fft.cc Mon Feb 16 19:02:33 2004 +0000 @@ -1,5 +1,6 @@ /* +Copyright (C) 2004 David Bateman Copyright (C) 1996, 1997 John W. Eaton This file is part of Octave. @@ -32,96 +33,169 @@ #include "oct-obj.h" #include "utils.h" -// This function should be merged with Fifft. +#if defined (HAVE_FFTW3) +#define FFTSRC "@sc{Fftw}" +#define WISDOM ", fft_wisdom" +#else +#define FFTSRC "@sc{Fftpack}" +#define WISDOM +#endif -DEFUN_DLD (fft, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} fft (@var{a}, @var{n})\n\ -Compute the FFT of @var{a} using subroutines from @sc{Fftpack}. If @var{a}\n\ -is a matrix, @code{fft} computes the FFT for each column of @var{a}.\n\ -\n\ -If called with two arguments, @var{n} is expected to be an integer\n\ -specifying the number of elements of @var{a} to use. If @var{a} is a\n\ -matrix, @var{n} specifies the number of rows of @var{a} to use. If\n\ -@var{n} is larger than the size of @var{a}, @var{a} is resized and\n\ -padded with zeros.\n\ -@end deftypefn") +static octave_value +do_fft (const octave_value_list &args, const char *fcn, int type) { octave_value retval; int nargin = args.length (); - if (nargin < 1 || nargin > 2) + if (nargin < 1 || nargin > 3) { - print_usage ("fft"); + print_usage (fcn); return retval; } octave_value arg = args(0); - - int n_points = arg.rows (); - if (n_points == 1) - n_points = arg.columns (); + dim_vector dims = arg.dims (); + int n_points = -1; + int dim = -1; + + if (nargin > 1) + { + if (! args(1).is_empty ()) + { + double dval = args(1).double_value (); + if (xisnan (dval)) + error ("%s: NaN is invalid as the N_POINTS", fcn); + else + { + n_points = NINT (dval); + if (n_points < 0) + error ("%s: number of points must be greater than zero", fcn); + } + } + } - if (nargin == 2) + if (error_state) + return retval; + + if (nargin > 2) { - double dval = args(1).double_value (); + double dval = args(2).double_value (); if (xisnan (dval)) - error ("fft: NaN is invalid as the N_POINTS"); + error ("%s: NaN is invalid as the N_POINTS", fcn); + else if (dval < 1 || dval > dims.length ()) + error ("%s: invalid dimension along which to perform fft", fcn); else - n_points = NINT (dval); + dim = NINT (dval) - 1; } if (error_state) return retval; - if (n_points < 0) - { - error ("fft: number of points must be greater than zero"); + for (int i = 0; i < dims.length (); i++) + if (dims(i) < 0) return retval; - } - int arg_is_empty = empty_arg ("fft", arg.rows (), arg.columns ()); + if (dim < 0) + for (int i = 0; i < dims.length (); i++) + if ( dims(i) > 1) + { + dim = i; + break; + } - if (arg_is_empty < 0) - return retval; - else if (arg_is_empty || n_points == 0) + if (n_points < 0) + n_points = dims (dim); + else + dims (dim) = n_points; + + if (dims.all_zero () || n_points == 0) return octave_value (Matrix ()); if (arg.is_real_type ()) { - Matrix m = arg.matrix_value (); + NDArray nda = arg.array_value (); if (! error_state) { - if (m.rows () == 1) - m.resize (1, n_points, 0.0); - else - m.resize (n_points, m.columns (), 0.0); - retval = m.fourier (); + nda.resize (dims, 0.0); + retval = (type != 0 ? nda.ifourier (dim) : nda.fourier (dim)); } } else if (arg.is_complex_type ()) { - ComplexMatrix m = arg.complex_matrix_value (); + ComplexNDArray cnda = arg.complex_array_value (); if (! error_state) { - if (m.rows () == 1) - m.resize (1, n_points, 0.0); - else - m.resize (n_points, m.columns (), 0.0); - retval = m.fourier (); + cnda.resize (dims, 0.0); + retval = (type != 0 ? cnda.ifourier (dim) : cnda.fourier (dim)); } } else { - gripe_wrong_type_arg ("fft", arg); + gripe_wrong_type_arg (fcn, arg); } return retval; } + +DEFUN_DLD (fft, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} fft (@var{a}, @var{n}, @var{dim})\n\ +Compute the FFT of @var{a} using subroutines from\n" +FFTSRC +". The FFT is calculated along the first non-singleton dimension of the\n\ +array. Thus if @var{a} is a matrix, @code{fft (@var{a})} computes the\n\ +FFT for each column of @var{a}.\n\ +\n\ +If called with two arguments, @var{n} is expected to be an integer\n\ +specifying the number of elements of @var{a} to use, or an empty\n\ +matrix to specify that its value should be ignored. If @var{n} is\n\ +larger than the dimension along which the FFT is calculated, then\n\ +@var{a} is resized and padded with zeros. Otherwise, if@var{n} is\n\ +smaller than the dimension along which the FFT is calculated, then\n\ +@var{a} is truncated.\n\ +\n\ +If called with three agruments, @var{dim} is an integer specifying the\n\ +dimension of the matrix along which the FFT is performed\n\ +@end deftypefn\n\ +@seealso {ifft, fft2, fftn" +WISDOM +"}") +{ + return do_fft(args, "fft", 0); +} + + +DEFUN_DLD (ifft, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} ifft (@var{a}, @var{n}, @var{dim})\n\ +Compute the inverse FFT of @var{a} using subroutines from\n" +FFTSRC +". The inverse FFT is calculated along the first non-singleton dimension\n\ +of the array. Thus if @var{a} is a matrix, @code{fft (@var{a})} computes\n\ +the inverse FFT for each column of @var{a}.\n\ +\n\ +If called with two arguments, @var{n} is expected to be an integer\n\ +specifying the number of elements of @var{a} to use, or an empty\n\ +matrix to specify that its value should be ignored. If @var{n} is\n\ +larger than the dimension along which the inverse FFT is calculated, then\n\ +@var{a} is resized and padded with zeros. Otherwise, if@var{n} is\n\ +smaller than the dimension along which the inverse FFT is calculated,\n\ +then @var{a} is truncated.\n\ +\n\ +If called with three agruments, @var{dim} is an integer specifying the\n\ +dimension of the matrix along which the inverse FFT is performed\n\ +@end deftypefn\n\ +@seealso {fft, ifft2, ifftn" +WISDOM +"}") +{ + return do_fft(args, "ifft", 1); +} + /* ;;; Local Variables: *** ;;; mode: C++ ***