fftn.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2004-2012 David Bateman
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "lo-mappers.h"
00028 
00029 #include "defun-dld.h"
00030 #include "error.h"
00031 #include "gripes.h"
00032 #include "oct-obj.h"
00033 #include "utils.h"
00034 
00035 // This function should be merged with Fifft.
00036 
00037 #if defined (HAVE_FFTW)
00038 #define FFTSRC "@sc{fftw}"
00039 #else
00040 #define FFTSRC "@sc{fftpack}"
00041 #endif
00042 
00043 static octave_value
00044 do_fftn (const octave_value_list &args, const char *fcn, int type)
00045 {
00046   octave_value retval;
00047 
00048   int nargin = args.length ();
00049 
00050   if (nargin < 1 || nargin > 2)
00051     {
00052       print_usage ();
00053       return retval;
00054     }
00055 
00056   octave_value arg = args(0);
00057   dim_vector dims = arg.dims ();
00058 
00059   for (int i = 0; i < dims.length (); i++)
00060     if (dims(i) < 0)
00061       return retval;
00062 
00063   if (nargin > 1)
00064     {
00065       Matrix val = args(1).matrix_value ();
00066       if (val.rows () > val.columns ())
00067         val = val.transpose ();
00068 
00069       if (error_state || val.columns () != dims.length () || val.rows () != 1)
00070         error ("%s: SIZE must be a vector of length dim", fcn);
00071       else
00072         {
00073           for (int i = 0; i < dims.length (); i++)
00074             {
00075               if (xisnan (val(i,0)))
00076                 error ("%s: SIZE has invalid NaN entries", fcn);
00077               else if (NINTbig (val(i,0)) < 0)
00078                 error ("%s: all dimensions in SIZE must be greater than zero", fcn);
00079               else
00080                 {
00081                   dims(i) = NINTbig(val(i,0));
00082                 }
00083             }
00084         }
00085     }
00086 
00087   if (error_state)
00088     return retval;
00089 
00090   if (dims.all_zero ())
00091     {
00092       if (arg.is_single_type ())
00093         return octave_value (FloatMatrix ());
00094       else
00095         return octave_value (Matrix ());
00096     }
00097 
00098   if (arg.is_single_type ())
00099     {
00100       if (arg.is_real_type ())
00101         {
00102           FloatNDArray nda = arg.float_array_value ();
00103 
00104           if (! error_state)
00105             {
00106               nda.resize (dims, 0.0);
00107               retval = (type != 0 ? nda.ifourierNd () : nda.fourierNd ());
00108             }
00109         }
00110       else
00111         {
00112           FloatComplexNDArray cnda = arg.float_complex_array_value ();
00113 
00114           if (! error_state)
00115             {
00116               cnda.resize (dims, 0.0);
00117               retval = (type != 0 ? cnda.ifourierNd () : cnda.fourierNd ());
00118             }
00119         }
00120     }
00121   else
00122     {
00123       if (arg.is_real_type ())
00124         {
00125           NDArray nda = arg.array_value ();
00126 
00127           if (! error_state)
00128             {
00129               nda.resize (dims, 0.0);
00130               retval = (type != 0 ? nda.ifourierNd () : nda.fourierNd ());
00131             }
00132         }
00133       else if (arg.is_complex_type ())
00134         {
00135           ComplexNDArray cnda = arg.complex_array_value ();
00136 
00137           if (! error_state)
00138             {
00139               cnda.resize (dims, 0.0);
00140               retval = (type != 0 ? cnda.ifourierNd () : cnda.fourierNd ());
00141             }
00142         }
00143       else
00144         {
00145           gripe_wrong_type_arg (fcn, arg);
00146         }
00147     }
00148 
00149   return retval;
00150 }
00151 
00152 DEFUN_DLD (fftn, args, ,
00153   "-*- texinfo -*-\n\
00154 @deftypefn  {Loadable Function} {} fftn (@var{A})\n\
00155 @deftypefnx {Loadable Function} {} fftn (@var{A}, @var{size})\n\
00156 Compute the N-dimensional discrete Fourier transform of @var{A} using\n\
00157 a Fast Fourier Transform (FFT) algorithm.\n\
00158 \n\
00159 The optional vector argument @var{size} may be used specify the\n\
00160 dimensions of the array to be used.  If an element of @var{size} is\n\
00161 smaller than the corresponding dimension of @var{A}, then the dimension of\n\
00162 @var{A} is truncated prior to performing the FFT@.  Otherwise, if an element\n\
00163 of @var{size} is larger than the corresponding dimension then @var{A}\n\
00164 is resized and padded with zeros.\n\
00165 @seealso{ifftn, fft, fft2, fftw}\n\
00166 @end deftypefn")
00167 {
00168   return do_fftn (args, "fftn", 0);
00169 }
00170 
00171 DEFUN_DLD (ifftn, args, ,
00172   "-*- texinfo -*-\n\
00173 @deftypefn  {Loadable Function} {} ifftn (@var{A})\n\
00174 @deftypefnx {Loadable Function} {} ifftn (@var{A}, @var{size})\n\
00175 Compute the inverse N-dimensional discrete Fourier transform of @var{A}\n\
00176 using a Fast Fourier Transform (FFT) algorithm.\n\
00177 \n\
00178 The optional vector argument @var{size} may be used specify the\n\
00179 dimensions of the array to be used.  If an element of @var{size} is\n\
00180 smaller than the corresponding dimension of @var{A}, then the dimension of\n\
00181 @var{A} is truncated prior to performing the inverse FFT@.  Otherwise, if an\n\
00182 element of @var{size} is larger than the corresponding dimension then @var{A}\n\
00183 is resized and padded with zeros.\n\
00184 @seealso{fftn, ifft, ifft2, fftw}\n\
00185 @end deftypefn")
00186 {
00187   return do_fftn (args, "ifftn", 1);
00188 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines