# HG changeset patch # User Arun Giridhar # Date 1669196963 18000 # Node ID 54d6adbabdb7c106c0997fcd50b077577c730723 # Parent f7c6c93366ac6727562f669ba7c16ab193da1203# Parent 9ee8943cad01c2fb7145fbb7d8054094584f58f7 maint: Merge stable to default diff -r f7c6c93366ac -r 54d6adbabdb7 doc/interpreter/doccheck/README --- a/doc/interpreter/doccheck/README Wed Nov 23 04:48:28 2022 -0500 +++ b/doc/interpreter/doccheck/README Wed Nov 23 04:49:23 2022 -0500 @@ -57,17 +57,22 @@ When there is no source file comment, the source file is the .txi source. Make corrections to the source files, *not* arith.texi which is derived. + + There are generally three choices for resolving a reported misspelling: + + 1. The word is misspelled and should be corrected in the source. + 2. The word should not be checked for spelling (for example, it might be + a proper name such as "Lanczos"). Use the @nospell{...} macro around + the word in the source (See Special Cases below). + 3. The word is valid, but Octave-specific (for example, a function name + such as "datenum"). These words should be added to Octave's exception + dictionary (see Special Cases below). .... make # propagate changes to arith.texi repeat spellcheck until the words that remain are not misspellings. +Special Cases -Any words remaining after all misspellings have been corrected are -Octave-specific spellings and should be added to the Octave private dictionary. - -doccheck/add_to_aspell_dict misspellings - Words which are misspellings, but which can't be changed in the original source, should be marked with the @nospell{WORD} macro. This will cause aspell to ignore this particular instance of the word. @@ -80,6 +85,13 @@ aspell will no longer report any misspellings for linalg.texi. +Any words remaining after all misspellings have been corrected are +Octave-specific spellings and should be added to the Octave private dictionary. +The script invocation to add words to the dictionary is: + +doccheck/add_to_aspell_dict file_of_misspellings + + GRAMMAR: To be added @@ -87,7 +99,7 @@ UNDOCUMENTED FUNCTIONS: From the top-level , type 'make doc/interpreter/undocumented_list'. -This will produce an "undocumented_list" file with any undocumented functions. +This will produce the file "undocumented_list" with any undocumented functions. Functions which don't require an @DOCSTRING reference can be added to the list of exceptions at the bottom of the mk_undocumented_list script. This is often diff -r f7c6c93366ac -r 54d6adbabdb7 etc/RELEASE_CHECKLIST.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etc/RELEASE_CHECKLIST.md Wed Nov 23 04:49:23 2022 -0500 @@ -0,0 +1,140 @@ +# `VERSION`.1 Release Checklist # + +**Timeline** (tentative) + +* YYYY-MM-DD 🚀 Release Kick-off ⚽ (default branch merged to stable) +* YYYY-MM-DD 🛠️ 1st release candidate **`VERSION`.0.90** on +* YYYY-MM-DD 🏁 Final Release 🎉 **`VERSION`.1.0** on + +Please use ` ` to mark items below as done. + +## 🚀 Kick-off ⚽ ## + +------------------------------------------------------------ + +### ⚙️ Update gnulib to latest version ### + +Completion Date: + +**Must occur first** as it could resolve existing, or create new, bug reports. You should run `./bootstrap` in the source tree after updating to the new gnulib version. + +### 📢 Call for bug reports ### + +Completion Date: + +* Put out a general call for reports on [Octave Discourse](https://octave.discourse.group/) for all outstanding unreported known bugs. +* Create Savannah tag `VERSION.0.90` on bug tracker for 1st release candidate. +* Mark items that should be fixed for the release with this tag. +* Bug overview at . + +### 📢 Call for translations ### + +Completion Date: + +* Call for updates ([Octave Discourse](https://octave.discourse.group/)) that might change GUI strings. +* String freeze date: +* Update language translation files (`*.ts`) using scripts from Torsten. +* Create bug report on Savannah as a centralized location for uploading files and tracking status of translations. +* Call for translations of GUI strings on [Octave Discourse Maintainers](https://octave.discourse.group/c/maintainers/7), CC-ing the translators (see [list of translators](https://hg.savannah.gnu.org/hgweb/octave/file/tip/libgui/languages/translators)). +* Collect translation files on Savannah bug report and push to Mercurial. + +### ⚖️ GPL License activities ### + +Completion Date: + +* Update copyright statements for all source controlled files. +* Update dates in any other locations (launch message, citation, MXE files, etc.). +* Add any new contributors to `doc/interpreter/contributors.in` who wish to be mentioned (don't add them without permission). + +### ✅ Style-check code base ### + +Completion Date: + +This will produce lots of whitespace changes, but no behavior changes. **Must occur after patches have been added**, since whitespace changes can prevent patches from applying. + +* [m-file style check](https://wiki.octave.org/Octave_style_guide) +* [C++ style check](https://wiki.octave.org/C%2B%2B_style_guide) + +### 📖 Review documentation ### + +Completion Date: + +* Grammar check documentation (See `doc/interpreter/doccheck/README`). +* Spell check documentation (`make spellcheck`). +* Verify no functions missing from manual (`make doc/interpreter/undocumented_list`). +* Verify deprecated functions removed from "see also" links. +* Verify all formats (Info, HTML, PDF) build correctly. +* Review `etc/NEWS.VERSION.md` for any features which should be announced. +* Review `__unimplemented__.m` for the latest changes to [Octave Forge](https://wiki.octave.org/Octave_Forge) packages and new Matlab functions. +* Update major version number in "`@subtitle Edition XXX`" in `octave.texi`. +* Update `installer-files/README.html` in MXE Octave with version highlights. + +## 🔃 Repeat until all bugs are resolved ## + +------------------------------------------------------------ + +Completion Date of first iteration: + +### ⚠️ Current state at Savannah ### + +Bug overview at . + +### ✅ `make check` ### + +* Verify `make check` is passing on all [buildbot combinations of OS and compilers](http://buildbot.octave.org:8010/#/waterfall) and [GitHub CI runners](https://github.com/gnu-octave/octave/actions). Also check [test suite runs on "freshly brewed Octave for Windows"](https://github.com/gnu-octave/octave-buildbot/actions) (Kai's buildbots on octave.space). +* Use software tools to check quality of Octave code. + * Check for memory leaks by compiling with `-fsanitize=undefined`, `--enable-address-sanitizer-flags`. + * Update static code analysis results. See [PVS static analyzer - 5.0 Release](https://wiki.octave.org/PVS_static_analyzer_-_5.0_Release). + * Use other tools such as `cppcheck`, etc. +* Start discussion on [Octave Discourse Maintainers](https://octave.discourse.group/c/maintainers/8) about which failing tests that must be fixed and which can be declared **WON'T FIX**. + +### 🛠️ Create new release candidate ### + +* Ensure correct version information. +* Create hg tag in repository with release candidate version number. +* Verify `make distcheck` passes. +* Verify `make dist` works. +* Create [Windows Installer](https://wiki.octave.org/Windows_Installer). +* Upload release candidates. +* Check [Windows Installer](https://wiki.octave.org/Windows_Installer) (executable and zip formats) against false positive detection at [virustotal.com](https://virustotal.com/). +* Add release candidate version to Savannah bug tracker. +* Announce release candidate to [Octave Discourse](https://octave.discourse.group/). + +## 🏁 Final Release 🎉 ## + +------------------------------------------------------------ + +### 📃 Update version information ### + +Completion Date: + +* Ensure correct version information. +* Create hg tag in repository with release version number. +* Update `etc/NEWS.VERSION.md` (final release date). +* Update `CITATION` (version, year, URL). +* Update `etc/icons/org.octave.Octave.appdata.xml` (version number and release date). +* Update Savannah bug tracker version info. +* Update Savannah bug tracker: **OPEN** bugs marked as **WON'T FIX** should be marked as **CONFIRMED** (or more appropriate) for the final release. +* Remove release candidate versions from Savannah. + +### 📢 Announce final release ### + +Completion Date: + +* Octave mailing-lists +* Octave web site () +* Steps documented in this [changeset](https://hg.octave.org/web-octave/rev/fe59d0118a2b). +* Upload documentation (manual HTML + PDF `octave.org/doc` and version in `octave.org/.htaccess`, Doxygen `octave.org/doxygen`) +* This wiki +* Template:Release = 7.3.0 +* Template:Release Date = November 2, 2022 +* Template:Release Year = 2022 + +### ☑️ Post-Release ### + +Completion Date: + +* Merge default onto stable to become the current stable release. +* Ensure correct version information. +* Remove all deprecated functions (either tagged with `OCTAVE_DEPRECATED` in C++ or in the directory `scripts/deprecated` for m-files) scheduled for deletion in "default" branch. Check file `etc/NEWS.VERSION-2.md` for list of features that have been deprecated. +* Create new `etc/NEWS.VERSION+1.md` file by copying `etc/NEWS.VERSION.md` and then removing text so that it is a template file with headings only. diff -r f7c6c93366ac -r 54d6adbabdb7 scripts/statistics/mean.m --- a/scripts/statistics/mean.m Wed Nov 23 04:48:28 2022 -0500 +++ b/scripts/statistics/mean.m Wed Nov 23 04:49:23 2022 -0500 @@ -25,16 +25,15 @@ ## -*- texinfo -*- ## @deftypefn {} {@var{y} =} mean (@var{x}) -## @deftypefnx {} {@var{y} =} mean (@var{x}, "all") +## @deftypefnx {} {@var{y} =} mean (@var{x}, 'all') ## @deftypefnx {} {@var{y} =} mean (@var{x}, @var{dim}) -## @deftypefnx {} {@var{y} =} mean (@var{x}, @var{vecdim}) -## @deftypefnx {} {@var{y} =} mean (@dots{}, @var{outtype}) -## @deftypefnx {} {@var{y} =} mean (@dots{}, @var{nanflag}) +## @deftypefnx {} {@var{y} =} mean (@dots{}, '@var{outtype}') +## @deftypefnx {} {@var{y} =} mean (@dots{}, '@var{nanflag}') ## Compute the mean of the elements of @var{x}. ## ## @itemize ## @item -## If @var{x} is a vector, then @code{mean(@var{x})} returns the +## If @var{x} is a vector, then @code{mean (@var{x})} returns the ## mean of the elements in @var{x} defined as ## @tex ## $$ {\rm mean}(x) = \bar{x} = {1\over N} \sum_{i=1}^N x_i $$ @@ -48,49 +47,53 @@ ## @end example ## ## @noindent -## where @math{N} is the length of the @var{x} vector. +## where @math{N} is the number of elements in the @var{x} vector. ## ## @end ifnottex ## ## @item -## If @var{x} is a matrix, then @code{mean(@var{x})} returns a row vector -## with the mean of each columns in @var{x}. +## If @var{x} is a matrix, then @code{mean} returns a row vector with the mean +## of each column in @var{x}. ## ## @item -## If @var{x} is a multidimensional array, then @code{mean(@var{x})} -## operates along the first nonsingleton dimension of @var{x}. +## If @var{x} is a multi-dimensional array, then @code{mean} operates along the +## first non-singleton dimension of @var{x}. ## @end itemize ## -## @code{mean(@var{x}, "all")} returns the mean of all the elements in @var{x}. +## The optional input @var{dim} forces @code{mean} to operate over the +## specified dimension(s). @var{dim} can either be a scalar dimension or a +## vector of non-repeating dimensions. Dimensions must be positive integers, +## and the mean is calculated over the array slice defined by @var{dim}. ## -## @code{mean(@var{x}, @var{dim})} returns the mean along the -## operating dimension @var{dim} of @var{x}. +## Specifying dimension @qcode{"all"} will force @code{mean} to operate on all +## elements of @var{x}, and is equivalent to @code{mean (@var{x}(:))}. +## +## The optional input @var{outtype} specifies the data type that is returned. +## Valid values are: ## -## @code{mean(@var{x}, @var{vecdim})} returns the mean over the -## dimensions specified in the vector @var{vecdim}. For example, if @var{x} -## is a 2-by-3-by-4 array, then @code{mean(@var{x}, [1 2])} returns a 1-by-4 -## array. Each element of the output array is the mean of the elements on -## the corresponding page of @var{x}. NOTE! @var{vecdim} MUST index at least -## N-2 dimensions of @var{x}, where @code{N = length (size (@var{x}))} and -## N < 8. If @var{vecdim} indexes all dimensions of @var{x}, then it is -## equivalent to @code{mean(@var{x}, "all")}. +## @table @asis +## @item @qcode{'default'} : Output is of type double, unless the input is +## single in which case the output is of type single. +## +## @item @qcode{'double'} : Output is of type double. ## -## @code{mean(@dots{}, @var{outtype})} returns the mean with a specified data -## type, using any of the input arguments in the previous syntaxes. -## @var{outtype} can be "default", "double", or "native". +## @item @qcode{'native'} : Output is of the same type as the input +## (@code{class (@var{x})}), unless the input is logical in which case the +## output is of type double. ## -## @code{mean(@dots{}, @var{nanflag})} specifies whether to exclude NaN values -## from the calculation, using any of the input argument combinations in -## previous syntaxes. By default, NaN values are included in the calculation -## (@var{nanflag} has the value "includenan"). To exclude NaN values, set the -## value of @var{nanflag} to "omitnan". +## @end table +## +## The optional input @var{nanflag} specifies whether to include/exclude NaN +## values from the calculation. By default, NaN values are included in the +## calculation (@var{nanflag} has the value @qcode{'includenan'}). To exclude +## NaN values, set the value of @var{nanflag} to @qcode{'omitnan'}. ## ## @seealso{median, mode} ## @end deftypefn function y = mean (x, varargin) - if (nargin < 1 || nargin > 4 || any (cellfun (@isnumeric, varargin(2:end)))) + if (nargin < 1 || nargin > 4 || ! all (cellfun (@ischar, varargin(2:end)))) print_usage (); endif @@ -99,15 +102,15 @@ omitnan = false; outtype = "default"; - for i = 1:length (varargin) + for i = 1:numel (varargin) if (ischar (varargin{i})) switch (varargin{i}) case "all" all_flag = true; + case "includenan" + omitnan = false; case "omitnan" omitnan = true; - case "includenan" - omitnan = false; case {"default", "double", "native"} outtype = varargin{i}; otherwise @@ -117,35 +120,35 @@ endfor varargin(cellfun (@ischar, varargin)) = []; - if (((length (varargin) == 1) && ! (isnumeric (varargin{1}))) ... - || (length (varargin) > 1)) + if (((numel (varargin) == 1) && ! (isnumeric (varargin{1}))) ... + || (numel (varargin) > 1)) print_usage (); endif if (! (isnumeric (x) || islogical (x))) - error ("mean: X must be either a numeric or boolean vector or matrix"); + error ("mean: X must be either a numeric or logical vector or matrix"); endif - if (length (varargin) == 0) + if (numel (varargin) == 0) ## Single numeric input argument, no dimensions given. if (all_flag) - n = length (x(:)); + n = numel (x(:)); if (omitnan) - n = length (x(! isnan (x))); - x(isnan (x)) = 0; + idx = isnan (x); + n -= sum (idx(:)); + x(idx) = 0; endif y = sum (x(:), 1) ./ n; else sz = size (x); - dim = find (sz > 1, 1); - if length (dim) == 0 - dim = 1; - endif + ## Find the first non-singleton dimension. + (dim = find (sz != 1, 1)) || (dim = 1); n = size (x, dim); if (omitnan) - n = sum (! isnan (x), dim); - x(isnan (x)) = 0; + idx = isnan (x); + n = sum (! idx, dim); + x(idx) = 0; endif y = sum (x, dim) ./ n; endif @@ -153,77 +156,79 @@ else ## Two numeric input arguments, dimensions given. Note scalar is vector! - vecdim = varargin{1}; - if (! (isvector (vecdim) && all (vecdim)) || any (rem (vecdim, 1))) - error ("mean: Dimension must be a positive integer scalar or vector"); + dim = varargin{1}; + if (! (isvector (dim) && all (dim)) || any (rem (dim, 1))) + error ("mean: DIM must be a positive integer scalar or vector"); endif - if (isscalar (vecdim)) + if (isscalar (dim)) - n = size (x, vecdim); + n = size (x, dim); if (omitnan) - n = sum (! isnan (x), vecdim); - x(isnan (x)) = 0; + idx = isnan (x); + n = sum (! idx, dim); + x(idx) = 0; endif - y = sum (x, vecdim) ./ n; + y = sum (x, dim) ./ n; else sz = size (x); - ndims = length (sz); + ndims = numel (sz); misdim = [1:ndims]; ## keep remaining dimensions - for i = 1:length (vecdim) - misdim(misdim == vecdim(i)) = []; + for i = 1:numel (dim) + misdim(misdim == dim(i)) = []; endfor - switch (length (misdim)) + switch (numel (misdim)) ## if all dimensions are given, compute x(:) case 0 - n = length (x(:)); + n = numel (x(:)); if (omitnan) - n = length (x(! isnan (x))); - x(isnan (x)) = 0; + idx = isnan (x); + n -= sum (idx(:)); + x(idx) = 0; endif y = sum (x(:), 1) ./ n; ## for 1 dimension left, return column vector case 1 - x = permute (x, [misdim, vecdim]); + x = permute (x, [misdim, dim]); for i = 1:size (x, 1) x_vec = x(i,:,:,:,:,:,:)(:); if (omitnan) x_vec = x_vec(! isnan (x_vec)); endif - y(i) = sum (x_vec, 1) ./ length (x_vec); + y(i) = sum (x_vec, 1) ./ numel (x_vec); endfor ## for 2 dimensions left, return matrix case 2 - x = permute (x, [misdim, vecdim]); + x = permute (x, [misdim, dim]); for i = 1:size (x, 1) for j = 1:size (x, 2) x_vec = x(i,j,:,:,:,:,:)(:); if (omitnan) x_vec = x_vec(! isnan (x_vec)); endif - y(i,j) = sum (x_vec, 1) ./ length (x_vec); + y(i,j) = sum (x_vec, 1) ./ numel (x_vec); endfor endfor - ## for more that 2 dimensions left, print usage + ## for more than 2 dimensions left, throw error otherwise - error ("vecdim must index at least N-2 dimensions of X"); + error ("DIM must index at least N-2 dimensions of X"); endswitch endif endif - ## Convert output as requested + ## Convert output if requested switch (outtype) case "default" - ## do nothing, the operators already do the right thing + ## do nothing, the operators already do the right thing. case "double" y = double (y); case "native" @@ -231,6 +236,8 @@ y = cast (y, class (x)); endif otherwise + ## FIXME: This is unreachable code. Valid values already + ## checked in input validation. error ("mean: OUTTYPE '%s' not recognized", outtype); endswitch @@ -251,21 +258,6 @@ %!assert (mean (single ([1 0 1 1])), single (0.75)) %!assert (mean ([1 2], 3), [1 2]) -## Test input validation -%!error mean () -%!error mean (1, 2, 3) -%!error mean (1, 2, 3, 4) -%!error mean (1, "all", 3) -%!error mean (1, "b") -%!error mean (1, 1, "foo") -%!error mean ({1:5}) -%!error mean ("char") -%!error mean (1, ones (2,2)) -%!error mean (1, 1.5) -%!error mean (1, 0) -%!error ... -%! mean (repmat ([1:20;6:25], [5 2 6 3 5]), [1 2]) - ## Test outtype option %!test %! in = [1 2 3]; @@ -324,7 +316,7 @@ %! assert (mean ([true false NaN], 2, "omitnan"), 0.5); %! assert (mean ([true false NaN], 2, "omitnan", "native"), 0.5); -## Test dimension indexing with vecdim in n-dimensional arrays +## Test dimension indexing with vecdim in N-dimensional arrays %!test %! x = repmat ([1:20;6:25], [5 2 6 3]); %! assert (size (mean (x, [3 2])), [10 3]); @@ -333,7 +325,7 @@ %! assert (size (mean (x, [1 4 3])), [1 40]); %! assert (size (mean (x, [1 2 3 4])), [1 1]); -## Test results with vecdim in n-dimensional arrays and "omitnan" +## Test results with vecdim in N-dimensional arrays and "omitnan" %!test %! x = repmat ([1:20;6:25], [5 2 6 3]); %! m = repmat ([10.5;15.5], [5,3]); @@ -343,3 +335,19 @@ %! assert (mean (x, [3 2]), m, 4e-14); %! m(2,3) = 15.52301255230125; %! assert (mean (x, [3 2], "omitnan"), m, 4e-14); + +## Test input validation +%!error mean () +%!error mean (1, 2, 3) +%!error mean (1, 2, 3, 4, 5) +%!error mean (1, "all", 3) +%!error mean (1, "b") +%!error mean (1, 1, "foo") +%!error mean ({1:5}) +%!error mean ("char") +%!error mean (1, ones (2,2)) +%!error mean (1, 1.5) +%!error mean (1, 0) +%!error +%! mean (repmat ([1:20;6:25], [5 2 6 3 5]), [1 2]) +