######################################################################## ## ## Copyright (C) 1998-2021 The Octave Project Developers ## ## 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 {} {@var{m} =} meansqr (@var{x}) ## @deftypefnx {} {[@var{m}, @var{n}] =} meansqr (@var{x}) ## ## Square each element of the array or cell input @var{x} and return the mean of ## the result as a scalar output @var{m}. @var{x} may consist of numeric, char, ## logical, or complex values, and cells may contain mixed types. Non-finite ## (Inf, NaN, NA) values are ignored for the calculation. If requested, the ## optional output argument @var{n} will contain the number of finite elements ## in @var{x} used to calculate @var{m}. ## ## @example ## @group ## a = [1 2 Inf 3]; ## [m, n] = meansqr (@var{a}) ## @result{} ## m = ## 4.6667 ## n = ## 3 ## @end group ## @end example ## @seealso{mean, meanabs, meansq, sumsqr, sumabs} ## @end deftypefn function [m, n] = meansqr (x) if ((nargin != 1) || (!any (nargout == [0 1 2]))) print_usage (); endif if (isnumeric (x) || islogical (x) || ischar (x)) ## square first to convert any char to numeric, output column vector x = x(:).^2; elseif strcmp (class (x), "cell") ## input validation: check contents after cell flattened ## output 1 column cell array with 1 column array cell contents to avoid ## problems with mismatched cell content sizes x = flatten_to_column_cell (x); ##check flattened content types if ! all(cellfun (@(C) isnumeric (C) || islogical (C) || ischar (C), x)) bad_cells = ! cellfun (@(C) isnumeric (C) || islogical (C) || ischar (C), x); bad_class = find (bad_cells, 1, "first"); error ("meansqr: MEANSQR not defined for cell arrays containing type %s", class (x{bad_class})); endif ## convert any chars to numeric with @power, then revert to array. x = cell2mat (cellfun (@power, x, {2}, "UniformOutput", false)); else error ("meansqr: MEANSQR not defined for type %s", class (x)); endif ## convert to single column input and exclude non-finite (NaN,Inf, NA) x = x(isfinite (x)); n = numel (x); if n == 0 m = 0; else m = mean (x); endif endfunction function C = flatten_to_column_cell (C) ## recursively flatten cell of any depth into a n x 1 cell array. if iscell (C) C = cellfun (@flatten_to_column_cell, C, 'UniformOutput', false); C = vertcat (C{:}); else C = {C(:)}; endif endfunction %!assert (meansqr (2), 4) %!assert (class (meansqr (single (2))), "single") %!assert (class (meansqr ({single(2)})), "single") %!assert (meansqr (2+3i), -5+12i) %!assert (meansqr ([1, 2, 4]), 7) %!assert (meansqr ([1, 2, 4]'), 7) %!assert (meansqr (magic (2)), 7.5, 10*eps) %!assert (meansqr ({magic(2)}), 7.5, 10*eps) %!assert (meansqr ('foo'), 11682) %!assert (meansqr (cat (3, magic(2), magic(2))), 7.5, 10*eps) %!assert (meansqr ([1+i, 2-i; 3+2i, 4-2i]), 5-1.5i, 10*eps) %!assert (meansqr ({[1+i, 2-i; 3+2i, 4-2i]}), 5-1.5i, 10*eps) ##test mixed inputs %!assert (meansqr ([{[{1}, {2}]},{[3; 4]'}]), 7.5, 10*eps) %!assert (meansqr ({1, 2, [3, 4]', 'test'}), 6296) %!assert (meansqr ([{1}, {[{2, {[3, 4], [5, 6]}, 7}]}]), 20) ## test nonfinite inputs %!assert (meansqr ([]), 0) %!assert (meansqr (Inf), 0) %!assert (meansqr ([Inf, NA, NaN]), 0) %!assert (meansqr ([Inf, NA, NaN, 1]), 1) %!test %! a = [{'a'}, {[{2, 7}]}, Inf]; %! [m, n] = meansqr (a); %! assert (m, 3154) %! assert (n, 3) ## Test input validation %!error meansqr () %!error meansqr (1, 2) %!error [a, b, c] = meansqr (1, 2) %!error meansqr (struct("a",1)) %!error meansqr ({1, struct("a",1)})