## Copyright (C) 2020 Adam H. Aitkenhead ## ## See the file COPYRIGHT.md in the top-level directory of this ## distribution or . ## ## This file is part of Octave. ## ## Octave is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{f1}] =} freqspace (@var{n}) ## @deftypefnx {Function File} {[@var{f1, f2, f3, ...}] =} freqspace (@var{n}) ## @deftypefnx {Function File} {[@var{f1, f2, f3, ...}] =} freqspace ([@var{m, n, o, ...}]) ## @deftypefnx {Function File} {[@var{f1}] =} freqspace (@var{n, 'whole'}) ## @deftypefnx {Function File} {[@var{f1, f2}] =} freqspace (@var{[m, n], 'meshgrid'}) ## ## @code{freqspace} returns a vector @var{f1} of @var{n} evenly spaced values. ## ## If @var{n} is even, the returned vector @var{f1} contains the values: [-1 : 2/n : (n-2)/n]. ## ## If @var{n} is odd, the returned vector @var{f1} contains the values: [(1-n)/n : 2/n : (n-1)/n]. ## ## If multiple outputs @var{f1,f2,f3...} are requested for a single input @var{n}, then the returned vectors ## @var{f1,f2,f3,...} are all identical. ## ## If multiple outputs @var{f1,f2,f3...} are requested for multiple inputs [@var{m,n,o...}], then each ## returned vector @var{f1,f2,f3...} corresponds to one input @var{m,n,o...}. ## ## If the option 'whole' is applied, the returned vector @var{f1} contains the values: [0 : 2/n : 2*(n-1)/n]. ## ## If the option 'meshgrid' is applied, @code{freqspace} applies @code{meshgrid} to the outputs, ## returning @var{f1,f2,f3,...} as arrays rather than vectors. The first two dimensions of the returned ## arrays @var{f1,f2,f3,...} are ordered according to @code{meshgrid}, and not as they would be ordered ## by @code{ndgrid}. ## ## Note that [@var{m,n,o...}] must have integer values, but may be of class single or double. ## ## @seealso{meshgrid} ## @end deftypefn ## Author: Adam H. Aitkenhead function varargout = freqspace (varargin) # Check the number of input arguments if (sum (cellfun (@isnumeric, varargin))!=1) error ('freqspace: Unsupported number of input arguments') endif # Check the number of output arguments ncount = numel (varargin{1}); if (ncount>1 && nargout!=ncount) error ('freqspace: Number of outputs does not match the given inputs') endif # Check that the numeric inputs have integer values if (any (mod (varargin{1}, 1))) error ('freqspace: Numeric inputs must have integer values') endif # Check that all string input arguments are either 'whole' or 'meshgrid' if (nargin>1) && (!all (ismember (varargin(2:end), {'whole', 'meshgrid'}))) error ('freqspace: Supported string inputs are ''whole'' and ''meshgrid''') endif # Generate the outputs F1, F2... for i = 1:ncount n = varargin{1}(i); if (mod (n, 2) == 0) # n is even varargout{i} = [-1 : 2/n : (n-2)/n]; else # n is odd varargout{i} = [(1-n)/n : 2/n : (n-1)/n]; endif endfor # Duplicate the output arguments if nargout>1 and ncount==1 if (nargout>ncount) for i = 2:nargout varargout{i} = varargout{1}; endfor endif # Option: 'whole' if (nargin>1) && ... (all (cellfun (@ischar, varargin(2:end)))) && .... (any (cellfun ('strcmp', varargin(2:end), {'whole'} ))) minout = cellfun (@min, varargout); for i = 1:nargout varargout{i} = varargout{i} - minout(i); endfor endif # Option: 'meshgrid' if (nargin>1) && ... (all (cellfun (@ischar, varargin(2:end)))) && ... (any (cellfun ('strcmp', varargin(2:end), {'meshgrid'} ))) [varargout{:}] = ndgrid (varargout{:}); for i = 1:nargout varargout{i} = permute (varargout{i}, ... [2,1,3:max(3, ndims (varargout{i}))]); endfor endif endfunction %!test %! x = 2; %! [XX, YY] = freqspace (x); %! assert (numel (XX), x); %! assert (numel (YY), x); %!test %! x = 2; %! y = 3; %! [XX, YY] = freqspace ([x, y]); %! assert (numel (XX), x); %! assert (numel (YY), y); %!test %! x = 2; %! y = 3; %! [XX, YY] = freqspace ([x, y], 'meshgrid'); %! assert (size (XX), [3,2]); %! assert (size (YY), [3,2]); %!test %! x = 2; %! y = 3; %! [XX, YY] = freqspace ([x, y], 'whole'); %! assert (XX(1), 0); %! assert (YY(1), 0); %!test %! x = 2; %! y = 3; %! [XX, YY] = freqspace ([x, y], 'whole', 'meshgrid'); %! assert (size (XX), [3,2]); %! assert (size (YY), [3,2]); %! assert (XX(1), 0); %! assert (YY(1), 0); ## Test input validation %!error freqspace (2,3); %!error [XX] = freqspace ([2, 3]); %!error [XX, YY] = freqspace ([2, 3, 4]); %!error [XX, YY, ZZ] = freqspace ([2, 3]); %!error [XX] = freqspace ([2.5]) %!error [XX, YY] = freqspace ([2, 3], 'test')