00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include "lo-mappers.h"
00029
00030 #include "defun-dld.h"
00031 #include "error.h"
00032 #include "gripes.h"
00033 #include "oct-obj.h"
00034 #include "utils.h"
00035
00036 #if defined (HAVE_FFTW)
00037 #define FFTSRC "@sc{fftw}"
00038 #else
00039 #define FFTSRC "@sc{fftpack}"
00040 #endif
00041
00042 static octave_value
00043 do_fft (const octave_value_list &args, const char *fcn, int type)
00044 {
00045 octave_value retval;
00046
00047 int nargin = args.length ();
00048
00049 if (nargin < 1 || nargin > 3)
00050 {
00051 print_usage ();
00052 return retval;
00053 }
00054
00055 octave_value arg = args(0);
00056 dim_vector dims = arg.dims ();
00057 octave_idx_type n_points = -1;
00058 int dim = -1;
00059
00060 if (nargin > 1)
00061 {
00062 if (! args(1).is_empty ())
00063 {
00064 double dval = args(1).double_value ();
00065 if (xisnan (dval))
00066 error ("%s: number of points (N) cannot be NaN", fcn);
00067 else
00068 {
00069 n_points = NINTbig (dval);
00070 if (n_points < 0)
00071 error ("%s: number of points (N) must be greater than zero", fcn);
00072 }
00073 }
00074 }
00075
00076 if (error_state)
00077 return retval;
00078
00079 if (nargin > 2)
00080 {
00081 double dval = args(2).double_value ();
00082 if (xisnan (dval))
00083 error ("%s: DIM cannot be NaN", fcn);
00084 else if (dval < 1 || dval > dims.length ())
00085 error ("%s: DIM must be a valid dimension along which to perform FFT", fcn);
00086 else
00087
00088 dim = NINT (dval) - 1;
00089 }
00090
00091 if (error_state)
00092 return retval;
00093
00094 for (octave_idx_type i = 0; i < dims.length (); i++)
00095 if (dims(i) < 0)
00096 return retval;
00097
00098 if (dim < 0)
00099 {
00100 for (octave_idx_type i = 0; i < dims.length (); i++)
00101 if (dims(i) > 1)
00102 {
00103 dim = i;
00104 break;
00105 }
00106
00107
00108 if (dim < 0)
00109 dim = 1;
00110 }
00111
00112 if (n_points < 0)
00113 n_points = dims (dim);
00114 else
00115 dims (dim) = n_points;
00116
00117 if (dims.any_zero () || n_points == 0)
00118 {
00119 if (arg.is_single_type ())
00120 return octave_value (FloatNDArray (dims));
00121 else
00122 return octave_value (NDArray (dims));
00123 }
00124
00125 if (arg.is_single_type ())
00126 {
00127 if (arg.is_real_type ())
00128 {
00129 FloatNDArray nda = arg.float_array_value ();
00130
00131 if (! error_state)
00132 {
00133 nda.resize (dims, 0.0);
00134 retval = (type != 0 ? nda.ifourier (dim) : nda.fourier (dim));
00135 }
00136 }
00137 else
00138 {
00139 FloatComplexNDArray cnda = arg.float_complex_array_value ();
00140
00141 if (! error_state)
00142 {
00143 cnda.resize (dims, 0.0);
00144 retval = (type != 0 ? cnda.ifourier (dim) : cnda.fourier (dim));
00145 }
00146 }
00147 }
00148 else
00149 {
00150 if (arg.is_real_type ())
00151 {
00152 NDArray nda = arg.array_value ();
00153
00154 if (! error_state)
00155 {
00156 nda.resize (dims, 0.0);
00157 retval = (type != 0 ? nda.ifourier (dim) : nda.fourier (dim));
00158 }
00159 }
00160 else if (arg.is_complex_type ())
00161 {
00162 ComplexNDArray cnda = arg.complex_array_value ();
00163
00164 if (! error_state)
00165 {
00166 cnda.resize (dims, 0.0);
00167 retval = (type != 0 ? cnda.ifourier (dim) : cnda.fourier (dim));
00168 }
00169 }
00170 else
00171 {
00172 gripe_wrong_type_arg (fcn, arg);
00173 }
00174 }
00175
00176 return retval;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 DEFUN_DLD (fft, args, ,
00202 "-*- texinfo -*-\n\
00203 @deftypefn {Loadable Function} {} fft (@var{x})\n\
00204 @deftypefnx {Loadable Function} {} fft (@var{x}, @var{n})\n\
00205 @deftypefnx {Loadable Function} {} fft (@var{x}, @var{n}, @var{dim})\n\
00206 Compute the discrete Fourier transform of @var{A} using\n\
00207 a Fast Fourier Transform (FFT) algorithm.\n\
00208 \n\
00209 The FFT is calculated along the first non-singleton dimension of the\n\
00210 array. Thus if @var{x} is a matrix, @code{fft (@var{x})} computes the\n\
00211 FFT for each column of @var{x}.\n\
00212 \n\
00213 If called with two arguments, @var{n} is expected to be an integer\n\
00214 specifying the number of elements of @var{x} to use, or an empty\n\
00215 matrix to specify that its value should be ignored. If @var{n} is\n\
00216 larger than the dimension along which the FFT is calculated, then\n\
00217 @var{x} is resized and padded with zeros. Otherwise, if @var{n} is\n\
00218 smaller than the dimension along which the FFT is calculated, then\n\
00219 @var{x} is truncated.\n\
00220 \n\
00221 If called with three arguments, @var{dim} is an integer specifying the\n\
00222 dimension of the matrix along which the FFT is performed\n\
00223 @seealso{ifft, fft2, fftn, fftw}\n\
00224 @end deftypefn")
00225 {
00226 return do_fft (args, "fft", 0);
00227 }
00228
00229
00230 DEFUN_DLD (ifft, args, ,
00231 "-*- texinfo -*-\n\
00232 @deftypefn {Loadable Function} {} ifft (@var{x})\n\
00233 @deftypefnx {Loadable Function} {} ifft (@var{x}, @var{n})\n\
00234 @deftypefnx {Loadable Function} {} ifft (@var{x}, @var{n}, @var{dim})\n\
00235 Compute the inverse discrete Fourier transform of @var{A}\n\
00236 using a Fast Fourier Transform (FFT) algorithm.\n\
00237 \n\
00238 The inverse FFT is calculated along the first non-singleton dimension\n\
00239 of the array. Thus if @var{x} is a matrix, @code{fft (@var{x})} computes\n\
00240 the inverse FFT for each column of @var{x}.\n\
00241 \n\
00242 If called with two arguments, @var{n} is expected to be an integer\n\
00243 specifying the number of elements of @var{x} to use, or an empty\n\
00244 matrix to specify that its value should be ignored. If @var{n} is\n\
00245 larger than the dimension along which the inverse FFT is calculated, then\n\
00246 @var{x} is resized and padded with zeros. Otherwise, if @var{n} is\n\
00247 smaller than the dimension along which the inverse FFT is calculated,\n\
00248 then @var{x} is truncated.\n\
00249 \n\
00250 If called with three arguments, @var{dim} is an integer specifying the\n\
00251 dimension of the matrix along which the inverse FFT is performed\n\
00252 @seealso{fft, ifft2, ifftn, fftw}\n\
00253 @end deftypefn")
00254 {
00255 return do_fft (args, "ifft", 1);
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322