GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fft2.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "lo-mappers.h"
31 
32 #include "defun.h"
33 #include "error.h"
34 #include "errwarn.h"
35 #include "ovl.h"
36 #include "utils.h"
37 
39 
40 // This function should be merged with Fifft.
41 
42 static octave_value
43 do_fft2 (const octave_value_list& args, const char *fcn, int type)
44 {
45  int nargin = args.length ();
46 
47  if (nargin < 1 || nargin > 3)
48  print_usage ();
49 
50  octave_value retval;
51  octave_value arg = args(0);
52  dim_vector dims = arg.dims ();
53  octave_idx_type n_rows = -1;
54 
55  if (nargin > 1)
56  {
57  double dval = args(1).double_value ();
58  if (math::isnan (dval))
59  error ("%s: number of rows (N) cannot be NaN", fcn);
60 
61  n_rows = math::nint_big (dval);
62  if (n_rows < 0)
63  error ("%s: number of rows (N) must be greater than zero", fcn);
64  }
65 
66  octave_idx_type n_cols = -1;
67  if (nargin > 2)
68  {
69  double dval = args(2).double_value ();
70  if (math::isnan (dval))
71  error ("%s: number of columns (M) cannot be NaN", fcn);
72 
73  n_cols = math::nint_big (dval);
74  if (n_cols < 0)
75  error ("%s: number of columns (M) must be greater than zero", fcn);
76  }
77 
78  for (int i = 0; i < dims.ndims (); i++)
79  if (dims(i) < 0)
80  return retval;
81 
82  if (n_rows < 0)
83  n_rows = dims(0);
84  else
85  dims(0) = n_rows;
86 
87  if (n_cols < 0)
88  n_cols = dims(1);
89  else
90  dims(1) = n_cols;
91 
92  if (dims.all_zero () || n_rows == 0 || n_cols == 0)
93  {
94  if (arg.is_single_type ())
95  return octave_value (FloatMatrix ());
96  else
97  return octave_value (Matrix ());
98  }
99 
100  if (arg.is_single_type ())
101  {
102  if (arg.isreal ())
103  {
104  FloatNDArray nda = arg.float_array_value ();
105 
106  nda.resize (dims, 0.0);
107  retval = (type != 0 ? nda.ifourier2d () : nda.fourier2d ());
108  }
109  else
110  {
112 
113  cnda.resize (dims, 0.0);
114  retval = (type != 0 ? cnda.ifourier2d () : cnda.fourier2d ());
115  }
116  }
117  else
118  {
119  if (arg.isreal ())
120  {
121  NDArray nda = arg.array_value ();
122 
123  nda.resize (dims, 0.0);
124  retval = (type != 0 ? nda.ifourier2d () : nda.fourier2d ());
125  }
126  else if (arg.iscomplex ())
127  {
128  ComplexNDArray cnda = arg.complex_array_value ();
129 
130  cnda.resize (dims, 0.0);
131  retval = (type != 0 ? cnda.ifourier2d () : cnda.fourier2d ());
132  }
133  else
134  err_wrong_type_arg (fcn, arg);
135  }
136 
137  return retval;
138 }
139 
140 DEFUN (fft2, args, ,
141  doc: /* -*- texinfo -*-
142 @deftypefn {} {@var{B} =} fft2 (@var{A})
143 @deftypefnx {} {@var{B} =} fft2 (@var{A}, @var{m}, @var{n})
144 Compute the two-dimensional discrete Fourier transform of @var{A} using
145 a Fast Fourier Transform (FFT) algorithm.
146 
147 The optional arguments @var{m} and @var{n} may be used specify the number of
148 rows and columns of @var{A} to use. If either of these is larger than the
149 size of @var{A}, @var{A} is resized and padded with zeros.
150 
151 If @var{A} is a multi-dimensional matrix, each two-dimensional sub-matrix
152 of @var{A} is treated separately.
153 @seealso{ifft2, fft, fftn, fftw}
154 @end deftypefn */)
155 {
156  return do_fft2 (args, "fft2", 0);
157 }
158 
159 
160 DEFUN (ifft2, args, ,
161  doc: /* -*- texinfo -*-
162 @deftypefn {} {@var{A} =} ifft2 (@var{B})
163 @deftypefnx {} {@var{A} =} ifft2 (@var{B}, @var{m}, @var{n})
164 Compute the inverse two-dimensional discrete Fourier transform of @var{B}
165 using a Fast Fourier Transform (FFT) algorithm.
166 
167 The optional arguments @var{m} and @var{n} may be used specify the number of
168 rows and columns of @var{B} to use. If either of these is larger than the
169 size of @var{B}, @var{B} is resized and padded with zeros.
170 
171 If @var{B} is a multi-dimensional matrix, each two-dimensional sub-matrix
172 of @var{B} is treated separately.
173 @seealso{fft2, ifft, ifftn, fftw}
174 @end deftypefn */)
175 {
176  return do_fft2 (args, "ifft2", 1);
177 }
178 
179 /*
180 ## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
181 ## Comalco Research and Technology
182 ## 02 May 2000
183 %!testif HAVE_FFTW
184 %! M = 16;
185 %! N = 8;
186 %!
187 %! m = 5;
188 %! n = 3;
189 %!
190 %! x = 2*pi*(0:1:M-1)/M;
191 %! y = 2*pi*(0:1:N-1)/N;
192 %! sx = cos (m*x);
193 %! sy = sin (n*y);
194 %! s = kron (sx',sy);
195 %! S = fft2 (s);
196 %! answer = kron (fft (sx)', fft (sy));
197 %! assert (S, answer, 4*M*N*eps);
198 
199 ## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
200 ## Comalco Research and Technology
201 ## 02 May 2000
202 %!testif HAVE_FFTW
203 %! M = 12;
204 %! N = 7;
205 %!
206 %! m = 3;
207 %! n = 2;
208 %!
209 %! x = 2*pi*(0:1:M-1)/M;
210 %! y = 2*pi*(0:1:N-1)/N;
211 %!
212 %! sx = cos (m*x);
213 %! sy = cos (n*y);
214 %!
215 %! S = kron (fft (sx)', fft (sy));
216 %! answer = kron (sx', sy);
217 %! s = ifft2 (S);
218 %!
219 %! assert (s, answer, 30*eps);
220 
221 ## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
222 ## Comalco Research and Technology
223 ## 02 May 2000
224 %!testif HAVE_FFTW
225 %! M = 16;
226 %! N = 8;
227 %!
228 %! m = 5;
229 %! n = 3;
230 %!
231 %! x = 2*pi*(0:1:M-1)/M;
232 %! y = 2*pi*(0:1:N-1)/N;
233 %! sx = single (cos (m*x));
234 %! sy = single (sin (n*y));
235 %! s = kron (sx', sy);
236 %! S = fft2 (s);
237 %! answer = kron (fft (sx)', fft (sy));
238 %! assert (S, answer, 4*M*N* eps ("single"));
239 
240 ## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
241 ## Comalco Research and Technology
242 ## 02 May 2000
243 %!testif HAVE_FFTW
244 %! M = 12;
245 %! N = 7;
246 %!
247 %! m = 3;
248 %! n = 2;
249 %!
250 %! x = single (2*pi*(0:1:M-1)/M);
251 %! y = single (2*pi*(0:1:N-1)/N);
252 %!
253 %! sx = cos (m*x);
254 %! sy = cos (n*y);
255 %!
256 %! S = kron (fft (sx)', fft (sy));
257 %! answer = kron (sx', sy);
258 %! s = ifft2 (S);
259 %!
260 %! assert (s, answer, 30* eps ("single"));
261 */
262 
263 OCTAVE_END_NAMESPACE(octave)
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array-base.cc:1023
ComplexNDArray ifourier2d() const
Definition: CNDArray.cc:140
ComplexNDArray fourier2d() const
Definition: CNDArray.cc:120
FloatComplexNDArray fourier2d() const
Definition: fCNDArray.cc:120
FloatComplexNDArray ifourier2d() const
Definition: fCNDArray.cc:140
FloatComplexNDArray ifourier2d() const
Definition: fNDArray.cc:139
FloatComplexNDArray fourier2d() const
Definition: fNDArray.cc:119
Definition: dMatrix.h:42
ComplexNDArray fourier2d() const
Definition: dNDArray.cc:161
ComplexNDArray ifourier2d() const
Definition: dNDArray.cc:181
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
octave_idx_type ndims() const
Number of dimensions.
Definition: dim-vector.h:257
bool all_zero() const
Definition: dim-vector.h:300
octave_idx_type length() const
Definition: ovl.h:113
bool isreal() const
Definition: ov.h:738
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:878
bool is_single_type() const
Definition: ov.h:698
bool iscomplex() const
Definition: ov.h:741
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:859
FloatComplexNDArray float_complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:882
FloatNDArray float_array_value(bool frc_str_conv=false) const
Definition: ov.h:862
dim_vector dims() const
Definition: ov.h:541
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void() error(const char *fmt,...)
Definition: error.cc:988
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:166
octave_idx_type nint_big(double x)
Definition: lo-mappers.cc:188
bool isnan(bool)
Definition: lo-mappers.h:178
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))