fft2.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1997-2012 David Bateman
00004 Copyright (C) 1996-1997 John W. Eaton
00005 
00006 This file is part of Octave.
00007 
00008 Octave is free software; you can redistribute it and/or modify it
00009 under the terms of the GNU General Public License as published by the
00010 Free Software Foundation; either version 3 of the License, or (at your
00011 option) any later version.
00012 
00013 Octave is distributed in the hope that it will be useful, but WITHOUT
00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Octave; see the file COPYING.  If not, see
00020 <http://www.gnu.org/licenses/>.
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 // This function should be merged with Fifft.
00037 
00038 #if defined (HAVE_FFTW)
00039 #define FFTSRC "@sc{fftw}"
00040 #else
00041 #define FFTSRC "@sc{fftpack}"
00042 #endif
00043 
00044 static octave_value
00045 do_fft2 (const octave_value_list &args, const char *fcn, int type)
00046 {
00047   octave_value retval;
00048 
00049   int nargin = args.length ();
00050 
00051   if (nargin < 1 || nargin > 3)
00052     {
00053       print_usage ();
00054       return retval;
00055     }
00056 
00057   octave_value arg = args(0);
00058   dim_vector dims = arg.dims ();
00059   octave_idx_type n_rows = -1;
00060 
00061   if (nargin > 1)
00062     {
00063       double dval = args(1).double_value ();
00064       if (xisnan (dval))
00065         error ("%s: number of rows (N) cannot be NaN", fcn);
00066       else
00067         {
00068           n_rows = NINTbig (dval);
00069           if (n_rows < 0)
00070             error ("%s: number of rows (N) must be greater than zero", fcn);
00071         }
00072     }
00073 
00074   if (error_state)
00075     return retval;
00076 
00077   octave_idx_type n_cols = -1;
00078   if (nargin > 2)
00079     {
00080       double dval = args(2).double_value ();
00081       if (xisnan (dval))
00082         error ("%s: number of columns (M) cannot be NaN", fcn);
00083       else
00084         {
00085           n_cols = NINTbig (dval);
00086           if (n_cols < 0)
00087             error ("%s: number of columns (M) must be greater than zero", fcn);
00088         }
00089     }
00090 
00091   if (error_state)
00092     return retval;
00093 
00094   for (int i = 0; i < dims.length (); i++)
00095     if (dims(i) < 0)
00096       return retval;
00097 
00098   if (n_rows < 0)
00099     n_rows = dims (0);
00100   else
00101     dims (0) = n_rows;
00102 
00103   if (n_cols < 0)
00104     n_cols = dims (1);
00105   else
00106     dims (1) = n_cols;
00107 
00108   if (dims.all_zero () || n_rows == 0 || n_cols == 0)
00109     {
00110       if (arg.is_single_type ())
00111         return octave_value (FloatMatrix ());
00112       else
00113         return octave_value (Matrix ());
00114     }
00115 
00116   if (arg.is_single_type ())
00117     {
00118       if (arg.is_real_type ())
00119         {
00120           FloatNDArray nda = arg.float_array_value ();
00121 
00122           if (! error_state)
00123             {
00124               nda.resize (dims, 0.0);
00125               retval = (type != 0 ? nda.ifourier2d () : nda.fourier2d ());
00126             }
00127         }
00128       else
00129         {
00130           FloatComplexNDArray cnda = arg.float_complex_array_value ();
00131 
00132           if (! error_state)
00133             {
00134               cnda.resize (dims, 0.0);
00135               retval = (type != 0 ? cnda.ifourier2d () : cnda.fourier2d ());
00136             }
00137         }
00138     }
00139   else
00140     {
00141       if (arg.is_real_type ())
00142         {
00143           NDArray nda = arg.array_value ();
00144 
00145           if (! error_state)
00146             {
00147               nda.resize (dims, 0.0);
00148               retval = (type != 0 ? nda.ifourier2d () : nda.fourier2d ());
00149             }
00150         }
00151       else if (arg.is_complex_type ())
00152         {
00153           ComplexNDArray cnda = arg.complex_array_value ();
00154 
00155           if (! error_state)
00156             {
00157               cnda.resize (dims, 0.0);
00158               retval = (type != 0 ? cnda.ifourier2d () : cnda.fourier2d ());
00159             }
00160         }
00161       else
00162         {
00163           gripe_wrong_type_arg (fcn, arg);
00164         }
00165     }
00166 
00167   return retval;
00168 }
00169 
00170 DEFUN_DLD (fft2, args, ,
00171   "-*- texinfo -*-\n\
00172 @deftypefn  {Loadable Function} {} fft2 (@var{A})\n\
00173 @deftypefnx {Loadable Function} {} fft2 (@var{A}, @var{m}, @var{n})\n\
00174 Compute the two-dimensional discrete Fourier transform of @var{A} using\n\
00175 a Fast Fourier Transform (FFT) algorithm.\n\
00176 \n\
00177 The optional arguments @var{m} and @var{n} may be used specify the\n\
00178 number of rows and columns of @var{A} to use.  If either of these is\n\
00179 larger than the size of @var{A}, @var{A} is resized and padded with\n\
00180 zeros.\n\
00181 \n\
00182 If @var{A} is a multi-dimensional matrix, each two-dimensional sub-matrix\n\
00183 of @var{A} is treated separately.\n\
00184 @seealso {ifft2, fft, fftn, fftw}\n\
00185 @end deftypefn")
00186 {
00187   return do_fft2 (args, "fft2", 0);
00188 }
00189 
00190 
00191 DEFUN_DLD (ifft2, args, ,
00192   "-*- texinfo -*-\n\
00193 @deftypefn  {Loadable Function} {} ifft2 (@var{A})\n\
00194 @deftypefnx {Loadable Function} {} ifft2 (@var{A}, @var{m}, @var{n})\n\
00195 Compute the inverse two-dimensional discrete Fourier transform of @var{A}\n\
00196 using a Fast Fourier Transform (FFT) algorithm.\n\
00197 \n\
00198 The optional arguments @var{m} and @var{n} may be used specify the\n\
00199 number of rows and columns of @var{A} to use.  If either of these is\n\
00200 larger than the size of @var{A}, @var{A} is resized and padded with\n\
00201 zeros.\n\
00202 \n\
00203 If @var{A} is a multi-dimensional matrix, each two-dimensional sub-matrix\n\
00204 of @var{A} is treated separately\n\
00205 @seealso {fft2, ifft, ifftn, fftw}\n\
00206 @end deftypefn")
00207 {
00208   return do_fft2 (args, "ifft2", 1);
00209 }
00210 
00211 /*
00212 
00213 %% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
00214 %%         Comalco Research and Technology
00215 %%         02 May 2000
00216 %!test
00217 %! M=16;
00218 %! N=8;
00219 %!
00220 %! m=5;
00221 %! n=3;
00222 %!
00223 %! x = 2*pi*(0:1:M-1)/M;
00224 %! y = 2*pi*(0:1:N-1)/N;
00225 %! sx = cos(m*x);
00226 %! sy = sin(n*y);
00227 %! s=kron(sx',sy);
00228 %! S = fft2(s);
00229 %! answer = kron(fft(sx)',fft(sy));
00230 %! assert(S, answer, 4*M*N*eps);
00231 
00232 %% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
00233 %%         Comalco Research and Technology
00234 %%         02 May 2000
00235 %!test
00236 %! M=12;
00237 %! N=7;
00238 %!
00239 %! m=3;
00240 %! n=2;
00241 %!
00242 %! x = 2*pi*(0:1:M-1)/M;
00243 %! y = 2*pi*(0:1:N-1)/N;
00244 %!
00245 %! sx = cos(m*x);
00246 %! sy = cos(n*y);
00247 %!
00248 %! S = kron(fft(sx)',fft(sy));
00249 %! answer=kron(sx',sy);
00250 %! s = ifft2(S);
00251 %!
00252 %! assert(s, answer, 30*eps);
00253 
00254 
00255 %% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
00256 %%         Comalco Research and Technology
00257 %%         02 May 2000
00258 %!test
00259 %! M=16;
00260 %! N=8;
00261 %!
00262 %! m=5;
00263 %! n=3;
00264 %!
00265 %! x = 2*pi*(0:1:M-1)/M;
00266 %! y = 2*pi*(0:1:N-1)/N;
00267 %! sx = single(cos(m*x));
00268 %! sy = single(sin(n*y));
00269 %! s=kron(sx',sy);
00270 %! S = fft2(s);
00271 %! answer = kron(fft(sx)',fft(sy));
00272 %! assert(S, answer, 4*M*N*eps('single'));
00273 
00274 %% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
00275 %%         Comalco Research and Technology
00276 %%         02 May 2000
00277 %!test
00278 %! M=12;
00279 %! N=7;
00280 %!
00281 %! m=3;
00282 %! n=2;
00283 %!
00284 %! x = single(2*pi*(0:1:M-1)/M);
00285 %! y = single(2*pi*(0:1:N-1)/N);
00286 %!
00287 %! sx = cos(m*x);
00288 %! sy = cos(n*y);
00289 %!
00290 %! S = kron(fft(sx)',fft(sy));
00291 %! answer=kron(sx',sy);
00292 %! s = ifft2(S);
00293 %!
00294 %! assert(s, answer, 30*eps('single'));
00295 
00296 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines