# HG changeset patch # User Rik # Date 1382227370 25200 # Node ID 6516fc672fbb07a6866373ca2d0e7d0940791d02 # Parent 10d3bd4ec98148b6f14ec7cddddc8af3d820c721 maint: Re-categorize some functions between general/ and miscellaneous/ dirs. * scripts/general/bincoeff.m: Moved from miscellaneous directory. * scripts/miscellaneous/colon.m, scripts/miscellaneous/genvarname.m: Moved from general directory. * scripts/general/module.mk, scripts/miscellaneous/module.mk: Update build system. diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/general/bincoeff.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/general/bincoeff.m Sat Oct 19 17:02:50 2013 -0700 @@ -0,0 +1,120 @@ +## Copyright (C) 1995-2012 Kurt Hornik +## +## 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 {Mapping Function} {} bincoeff (@var{n}, @var{k}) +## Return the binomial coefficient of @var{n} and @var{k}, defined as +## @tex +## $$ +## {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!} +## $$ +## @end tex +## @ifnottex +## +## @example +## @group +## / \ +## | n | n (n-1) (n-2) @dots{} (n-k+1) +## | | = ------------------------- +## | k | k! +## \ / +## @end group +## @end example +## +## @end ifnottex +## For example: +## +## @example +## @group +## bincoeff (5, 2) +## @result{} 10 +## @end group +## @end example +## +## In most cases, the @code{nchoosek} function is faster for small +## scalar integer arguments. It also warns about loss of precision for +## big arguments. +## +## @seealso{nchoosek} +## @end deftypefn + +## Author: KH +## Created: 8 October 1994 +## Adapted-By: jwe + +function b = bincoeff (n, k) + + if (nargin != 2) + print_usage (); + endif + + [retval, n, k] = common_size (n, k); + if (retval > 0) + error ("bincoeff: N and K must be of common size or scalars"); + endif + + if (iscomplex (n) || iscomplex (k)) + error ("bincoeff: N and K must not be complex"); + endif + + b = zeros (size (n)); + + ok = (k >= 0) & (k == fix (k)) & (! isnan (n)); + b(! ok) = NaN; + + n_int = (n == fix (n)); + idx = n_int & (n < 0) & ok; + b(idx) = (-1) .^ k(idx) .* exp (gammaln (abs (n(idx)) + k(idx)) + - gammaln (k(idx) + 1) + - gammaln (abs (n(idx)))); + + idx = (n >= k) & ok; + b(idx) = exp (gammaln (n(idx) + 1) + - gammaln (k(idx) + 1) + - gammaln (n(idx) - k(idx) + 1)); + + idx = (! n_int) & (n < k) & ok; + b(idx) = (1/pi) * exp (gammaln (n(idx) + 1) + - gammaln (k(idx) + 1) + + gammaln (k(idx) - n(idx)) + + log (sin (pi * (n(idx) - k(idx) + 1)))); + + ## Clean up rounding errors. + b(n_int) = round (b(n_int)); + + idx = ! n_int; + b(idx) = real (b(idx)); + +endfunction + + +%!assert (bincoeff (4, 2), 6) +%!assert (bincoeff (2, 4), 0) +%!assert (bincoeff (-4, 2), 10) +%!assert (bincoeff (5, 2), 10) +%!assert (bincoeff (50, 6), 15890700) +%!assert (bincoeff (0.4, 2), -.12, 8*eps) + +%!assert (bincoeff ([4 NaN 4], [-1, 2, 2.5]), NaN (1, 3)) + +%% Test input validation +%!error bincoeff () +%!error bincoeff (1, 2, 3) +%!error bincoeff (ones (3),ones (2)) +%!error bincoeff (ones (2),ones (3)) + diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/general/colon.m --- a/scripts/general/colon.m Sat Oct 19 12:19:31 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -## Copyright (C) 2008-2012 David Bateman -## -## 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{r} =} colon (@var{a}, @var{b}) -## @deftypefnx {Function File} {@var{r} =} colon (@var{a}, @var{b}, @var{c}) -## Method of a class to construct a range with the @code{:} operator. For -## example: -## -## @example -## @group -## a = myclass (@dots{}); -## b = myclass (@dots{}); -## c = a : b -## @end group -## @end example -## -## @seealso{class, subsref, subsasgn} -## @end deftypefn - -function r = colon (varargin) - if (nargin != 0) - error ('colon: not defined for class "%s"', class (varargin{1})); - endif -endfunction - - -%!error colon (1) - -## FIXME -- what does colon () mean since it doesn't set a return value? - diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/general/genvarname.m --- a/scripts/general/genvarname.m Sat Oct 19 12:19:31 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -## Copyright (C) 2008-2012 Bill Denney, Robert Platt -## -## 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{varname} =} genvarname (@var{str}) -## @deftypefnx {Function File} {@var{varname} =} genvarname (@var{str}, @var{exclusions}) -## Create unique variable(s) from @var{str}. If @var{exclusions} is -## given, then the variable(s) will be unique to each other and to -## @var{exclusions} (@var{exclusions} may be either a string or a cellstr). -## -## If @var{str} is a cellstr, then a unique variable is created for each -## cell in @var{str}. -## -## @example -## @group -## x = 3.141; -## genvarname ("x", who ()) -## @result{} x1 -## @end group -## @end example -## -## If @var{wanted} is a cell array, genvarname will make sure the returned -## strings are distinct: -## -## @example -## @group -## genvarname (@{"foo", "foo"@}) -## @result{} -## @{ -## [1,1] = foo -## [1,2] = foo1 -## @} -## @end group -## @end example -## -## Note that the result is a char array/cell array of strings, not the -## variables themselves. To define a variable, @code{eval()} can be -## used. The following trivial example sets @code{x} to @code{42}. -## -## @example -## @group -## name = genvarname ("x"); -## eval ([name " = 42"]); -## @result{} x = 42 -## @end group -## @end example -## -## Also, this can be useful for creating unique struct field names. -## -## @example -## @group -## x = struct (); -## for i = 1:3 -## x.(genvarname ("a", fieldnames (x))) = i; -## endfor -## @result{} x = -## @{ -## a = 1 -## a1 = 2 -## a2 = 3 -## @} -## @end group -## @end example -## -## Since variable names may only contain letters, digits and underscores, -## genvarname replaces any sequence of disallowed characters with -## an underscore. Also, variables may not begin with a digit; in this -## case an underscore is added before the variable name. -## -## Variable names beginning and ending with two underscores @qcode{"__"} are -## valid but they are used internally by octave and should generally be -## avoided, therefore genvarname will not generate such names. -## -## genvarname will also make sure that returned names do not clash with -## keywords such as @qcode{"for"} and @qcode{"if"}. A number will be -## appended if necessary. Note, however, that this does @strong{not} include -## function names, such as @qcode{"sin"}. Such names should be included in -## @var{avoid} if necessary. -## @seealso{isvarname, exist, tmpnam, eval} -## @end deftypefn - -## Authors: Rob Platt -## Bill Denney - -function varname = genvarname (str, exclusions) - - strinput = ischar (str); - ## Process the inputs - if (nargin < 2) - exclusions = {}; - elseif (ischar (exclusions)) - if (rows (exclusions) != 1) - error ("genvarname: if more than one exclusion is given, it must be a cellstr"); - endif - exclusions = {exclusions}; - elseif (! iscellstr (exclusions)) - error ("genvarname: EXCLUSIONS must be a string or a cellstr"); - endif - if (ischar (str)) - if (rows (str) != 1) - error ("genvarname: if more than one STR is given, it must be a cellstr"); - endif - str = {str}; - elseif (! iscellstr (str)) - error ("genvarname: STR must be a string or a cellstr"); - endif - - validchars = ["A":"Z", "a":"z", "0":"9", "_"]; - - varname = cell (size (str)); - for i = 1:numel (str) - ## Perform any modifications to the varname to make sure that it is - ## a valid variable name. - - ## remove invalid characters - str{i}(! ismember (str{i}, validchars)) = "_"; - ## do not use keywords - if (iskeyword (str{i})) - str{i} = ["_" str{i}]; - endif - ## double underscores at the beginning and end are reserved variables - underscores = (str{i} == "_"); - if (any (underscores)) - firstnon = find (!underscores, 1); - lastnon = find (!underscores, 1, "last"); - str{i}([1:firstnon-2, lastnon+2:end]) = []; - endif - ## The variable cannot be empty - if (isempty (str{i})) - str{i} = "x"; - endif - ## it cannot start with a number - if (ismember (str{i}(1), "0":"9")) - str{i} = ["_" str{i}]; - endif - - ## make sure that the variable is unique relative to other variables - ## and the exclusions list - excluded = any (strcmp (str{i}, exclusions)); - if (excluded && ismember (str{i}(end), "0":"9")) - ## if it is not unique and ends with a digit, add an underscore to - ## make the variable name more readable ("x1_1" instead of "x11") - str{i}(end+1) = "_"; - endif - varname(i) = str(i); - idx = 0; - while (excluded) - idx++; - varname{i} = sprintf ("%s%d", str{i}, idx); - excluded = any (strcmp (varname{i}, exclusions)); - endwhile - exclusions(end+1) = varname(i); - endfor - - if (strinput) - varname = varname{1}; - endif - -endfunction - - -## a single argument -%!assert (genvarname ("a"), "a") -## a single argument with a non-conflicting exception -%!assert (genvarname ("a", "b"), "a") -## a single argument with a conflicting exception -%!assert (genvarname ("a", "a"), "a1") -## a single argument as a cell -%!assert (genvarname ({"a"}), {"a"}) -%!assert (genvarname ({"a"}, "b"), {"a"}) -%!assert (genvarname ({"a"}, {"b"}), {"a"}) -%!assert (genvarname ({"a"}, "a"), {"a1"}) -%!assert (genvarname ({"a"}, {"a"}), {"a1"}) -## Test different arguments -## orientation -%!assert (genvarname ({"a" "b"}), {"a" "b"}) -%!assert (genvarname ({"a";"b"}), {"a";"b"}) -%!assert (genvarname ({"a" "a"}), {"a" "a1"}) -%!assert (genvarname ({"a" "b";"c" "d"}), {"a" "b";"c" "d"}) -%!assert (genvarname ({"a" "a" "a";"a" "a" "a"}), {"a" "a2" "a4";"a1" "a3" "a5"}) -## more than one repetition -%!assert (genvarname ({"a" "a" "a"}), {"a" "a1" "a2"}) -%!assert (genvarname ({"a" "a" "a"}, {"a" "a1" "a2"}), {"a3" "a4" "a5"}) -## more than one repetition not in order -%!assert (genvarname ({"a" "b" "a" "b" "a"}), {"a" "b" "a1" "b1" "a2"}) -## Variable name munging -%!assert (genvarname ("__x__"), "_x_") -%!assert (genvarname ("123456789"), "_123456789") -%!assert (genvarname ("_$1__"), "_1_") -%!assert (genvarname ("__foo__", "_foo_"), "_foo_1") -%!assert (genvarname ("1million_and1", "_1million_and1"), "_1million_and1_1") -%!assert (genvarname ({"", "", ""}), {"x", "x1", "x2"}) -%!assert (genvarname ("if"), "_if") -%!assert (genvarname ({"if", "if", "if"}), {"_if", "_if1", "_if2"}) - diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/general/module.mk --- a/scripts/general/module.mk Sat Oct 19 12:19:31 2013 -0700 +++ b/scripts/general/module.mk Sat Oct 19 17:02:50 2013 -0700 @@ -8,6 +8,7 @@ general/accumarray.m \ general/accumdim.m \ general/bicubic.m \ + general/bincoeff.m \ general/bitcmp.m \ general/bitget.m \ general/bitset.m \ @@ -18,7 +19,6 @@ general/celldisp.m \ general/chop.m \ general/circshift.m \ - general/colon.m \ general/common_size.m \ general/cplxpair.m \ general/cumtrapz.m \ @@ -32,7 +32,6 @@ general/flipdim.m \ general/fliplr.m \ general/flipud.m \ - general/genvarname.m \ general/gradient.m \ general/idivide.m \ general/int2str.m \ diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/miscellaneous/bincoeff.m --- a/scripts/miscellaneous/bincoeff.m Sat Oct 19 12:19:31 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -## Copyright (C) 1995-2012 Kurt Hornik -## -## 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 {Mapping Function} {} bincoeff (@var{n}, @var{k}) -## Return the binomial coefficient of @var{n} and @var{k}, defined as -## @tex -## $$ -## {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!} -## $$ -## @end tex -## @ifnottex -## -## @example -## @group -## / \ -## | n | n (n-1) (n-2) @dots{} (n-k+1) -## | | = ------------------------- -## | k | k! -## \ / -## @end group -## @end example -## -## @end ifnottex -## For example: -## -## @example -## @group -## bincoeff (5, 2) -## @result{} 10 -## @end group -## @end example -## -## In most cases, the @code{nchoosek} function is faster for small -## scalar integer arguments. It also warns about loss of precision for -## big arguments. -## -## @seealso{nchoosek} -## @end deftypefn - -## Author: KH -## Created: 8 October 1994 -## Adapted-By: jwe - -function b = bincoeff (n, k) - - if (nargin != 2) - print_usage (); - endif - - [retval, n, k] = common_size (n, k); - if (retval > 0) - error ("bincoeff: N and K must be of common size or scalars"); - endif - - if (iscomplex (n) || iscomplex (k)) - error ("bincoeff: N and K must not be complex"); - endif - - b = zeros (size (n)); - - ok = (k >= 0) & (k == fix (k)) & (! isnan (n)); - b(! ok) = NaN; - - n_int = (n == fix (n)); - idx = n_int & (n < 0) & ok; - b(idx) = (-1) .^ k(idx) .* exp (gammaln (abs (n(idx)) + k(idx)) - - gammaln (k(idx) + 1) - - gammaln (abs (n(idx)))); - - idx = (n >= k) & ok; - b(idx) = exp (gammaln (n(idx) + 1) - - gammaln (k(idx) + 1) - - gammaln (n(idx) - k(idx) + 1)); - - idx = (! n_int) & (n < k) & ok; - b(idx) = (1/pi) * exp (gammaln (n(idx) + 1) - - gammaln (k(idx) + 1) - + gammaln (k(idx) - n(idx)) - + log (sin (pi * (n(idx) - k(idx) + 1)))); - - ## Clean up rounding errors. - b(n_int) = round (b(n_int)); - - idx = ! n_int; - b(idx) = real (b(idx)); - -endfunction - - -%!assert (bincoeff (4, 2), 6) -%!assert (bincoeff (2, 4), 0) -%!assert (bincoeff (-4, 2), 10) -%!assert (bincoeff (5, 2), 10) -%!assert (bincoeff (50, 6), 15890700) -%!assert (bincoeff (0.4, 2), -.12, 8*eps) - -%!assert (bincoeff ([4 NaN 4], [-1, 2, 2.5]), NaN (1, 3)) - -%% Test input validation -%!error bincoeff () -%!error bincoeff (1, 2, 3) -%!error bincoeff (ones (3),ones (2)) -%!error bincoeff (ones (2),ones (3)) - diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/miscellaneous/colon.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/miscellaneous/colon.m Sat Oct 19 17:02:50 2013 -0700 @@ -0,0 +1,46 @@ +## Copyright (C) 2008-2012 David Bateman +## +## 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{r} =} colon (@var{a}, @var{b}) +## @deftypefnx {Function File} {@var{r} =} colon (@var{a}, @var{b}, @var{c}) +## Method of a class to construct a range with the @code{:} operator. For +## example: +## +## @example +## @group +## a = myclass (@dots{}); +## b = myclass (@dots{}); +## c = a : b +## @end group +## @end example +## +## @seealso{class, subsref, subsasgn} +## @end deftypefn + +function r = colon (varargin) + if (nargin != 0) + error ('colon: not defined for class "%s"', class (varargin{1})); + endif +endfunction + + +%!error colon (1) + +## FIXME -- what does colon () mean since it doesn't set a return value? + diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/miscellaneous/genvarname.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/miscellaneous/genvarname.m Sat Oct 19 17:02:50 2013 -0700 @@ -0,0 +1,210 @@ +## Copyright (C) 2008-2012 Bill Denney, Robert Platt +## +## 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{varname} =} genvarname (@var{str}) +## @deftypefnx {Function File} {@var{varname} =} genvarname (@var{str}, @var{exclusions}) +## Create unique variable(s) from @var{str}. If @var{exclusions} is +## given, then the variable(s) will be unique to each other and to +## @var{exclusions} (@var{exclusions} may be either a string or a cellstr). +## +## If @var{str} is a cellstr, then a unique variable is created for each +## cell in @var{str}. +## +## @example +## @group +## x = 3.141; +## genvarname ("x", who ()) +## @result{} x1 +## @end group +## @end example +## +## If @var{wanted} is a cell array, genvarname will make sure the returned +## strings are distinct: +## +## @example +## @group +## genvarname (@{"foo", "foo"@}) +## @result{} +## @{ +## [1,1] = foo +## [1,2] = foo1 +## @} +## @end group +## @end example +## +## Note that the result is a char array/cell array of strings, not the +## variables themselves. To define a variable, @code{eval()} can be +## used. The following trivial example sets @code{x} to @code{42}. +## +## @example +## @group +## name = genvarname ("x"); +## eval ([name " = 42"]); +## @result{} x = 42 +## @end group +## @end example +## +## Also, this can be useful for creating unique struct field names. +## +## @example +## @group +## x = struct (); +## for i = 1:3 +## x.(genvarname ("a", fieldnames (x))) = i; +## endfor +## @result{} x = +## @{ +## a = 1 +## a1 = 2 +## a2 = 3 +## @} +## @end group +## @end example +## +## Since variable names may only contain letters, digits and underscores, +## genvarname replaces any sequence of disallowed characters with +## an underscore. Also, variables may not begin with a digit; in this +## case an underscore is added before the variable name. +## +## Variable names beginning and ending with two underscores @qcode{"__"} are +## valid but they are used internally by octave and should generally be +## avoided, therefore genvarname will not generate such names. +## +## genvarname will also make sure that returned names do not clash with +## keywords such as @qcode{"for"} and @qcode{"if"}. A number will be +## appended if necessary. Note, however, that this does @strong{not} include +## function names, such as @qcode{"sin"}. Such names should be included in +## @var{avoid} if necessary. +## @seealso{isvarname, exist, tmpnam, eval} +## @end deftypefn + +## Authors: Rob Platt +## Bill Denney + +function varname = genvarname (str, exclusions) + + strinput = ischar (str); + ## Process the inputs + if (nargin < 2) + exclusions = {}; + elseif (ischar (exclusions)) + if (rows (exclusions) != 1) + error ("genvarname: if more than one exclusion is given, it must be a cellstr"); + endif + exclusions = {exclusions}; + elseif (! iscellstr (exclusions)) + error ("genvarname: EXCLUSIONS must be a string or a cellstr"); + endif + if (ischar (str)) + if (rows (str) != 1) + error ("genvarname: if more than one STR is given, it must be a cellstr"); + endif + str = {str}; + elseif (! iscellstr (str)) + error ("genvarname: STR must be a string or a cellstr"); + endif + + validchars = ["A":"Z", "a":"z", "0":"9", "_"]; + + varname = cell (size (str)); + for i = 1:numel (str) + ## Perform any modifications to the varname to make sure that it is + ## a valid variable name. + + ## remove invalid characters + str{i}(! ismember (str{i}, validchars)) = "_"; + ## do not use keywords + if (iskeyword (str{i})) + str{i} = ["_" str{i}]; + endif + ## double underscores at the beginning and end are reserved variables + underscores = (str{i} == "_"); + if (any (underscores)) + firstnon = find (!underscores, 1); + lastnon = find (!underscores, 1, "last"); + str{i}([1:firstnon-2, lastnon+2:end]) = []; + endif + ## The variable cannot be empty + if (isempty (str{i})) + str{i} = "x"; + endif + ## it cannot start with a number + if (ismember (str{i}(1), "0":"9")) + str{i} = ["_" str{i}]; + endif + + ## make sure that the variable is unique relative to other variables + ## and the exclusions list + excluded = any (strcmp (str{i}, exclusions)); + if (excluded && ismember (str{i}(end), "0":"9")) + ## if it is not unique and ends with a digit, add an underscore to + ## make the variable name more readable ("x1_1" instead of "x11") + str{i}(end+1) = "_"; + endif + varname(i) = str(i); + idx = 0; + while (excluded) + idx++; + varname{i} = sprintf ("%s%d", str{i}, idx); + excluded = any (strcmp (varname{i}, exclusions)); + endwhile + exclusions(end+1) = varname(i); + endfor + + if (strinput) + varname = varname{1}; + endif + +endfunction + + +## a single argument +%!assert (genvarname ("a"), "a") +## a single argument with a non-conflicting exception +%!assert (genvarname ("a", "b"), "a") +## a single argument with a conflicting exception +%!assert (genvarname ("a", "a"), "a1") +## a single argument as a cell +%!assert (genvarname ({"a"}), {"a"}) +%!assert (genvarname ({"a"}, "b"), {"a"}) +%!assert (genvarname ({"a"}, {"b"}), {"a"}) +%!assert (genvarname ({"a"}, "a"), {"a1"}) +%!assert (genvarname ({"a"}, {"a"}), {"a1"}) +## Test different arguments +## orientation +%!assert (genvarname ({"a" "b"}), {"a" "b"}) +%!assert (genvarname ({"a";"b"}), {"a";"b"}) +%!assert (genvarname ({"a" "a"}), {"a" "a1"}) +%!assert (genvarname ({"a" "b";"c" "d"}), {"a" "b";"c" "d"}) +%!assert (genvarname ({"a" "a" "a";"a" "a" "a"}), {"a" "a2" "a4";"a1" "a3" "a5"}) +## more than one repetition +%!assert (genvarname ({"a" "a" "a"}), {"a" "a1" "a2"}) +%!assert (genvarname ({"a" "a" "a"}, {"a" "a1" "a2"}), {"a3" "a4" "a5"}) +## more than one repetition not in order +%!assert (genvarname ({"a" "b" "a" "b" "a"}), {"a" "b" "a1" "b1" "a2"}) +## Variable name munging +%!assert (genvarname ("__x__"), "_x_") +%!assert (genvarname ("123456789"), "_123456789") +%!assert (genvarname ("_$1__"), "_1_") +%!assert (genvarname ("__foo__", "_foo_"), "_foo_1") +%!assert (genvarname ("1million_and1", "_1million_and1"), "_1million_and1_1") +%!assert (genvarname ({"", "", ""}), {"x", "x1", "x2"}) +%!assert (genvarname ("if"), "_if") +%!assert (genvarname ({"if", "if", "if"}), {"_if", "_if1", "_if2"}) + diff -r 10d3bd4ec981 -r 6516fc672fbb scripts/miscellaneous/module.mk --- a/scripts/miscellaneous/module.mk Sat Oct 19 12:19:31 2013 -0700 +++ b/scripts/miscellaneous/module.mk Sat Oct 19 17:02:50 2013 -0700 @@ -6,11 +6,11 @@ miscellaneous_FCN_FILES = \ miscellaneous/ans.m \ - miscellaneous/bincoeff.m \ miscellaneous/bug_report.m \ miscellaneous/bunzip2.m \ miscellaneous/bzip2.m \ miscellaneous/cast.m \ + miscellaneous/colon.m \ miscellaneous/citation.m \ miscellaneous/comma.m \ miscellaneous/compare_versions.m \ @@ -28,6 +28,7 @@ miscellaneous/fileattrib.m \ miscellaneous/fileparts.m \ miscellaneous/fullfile.m \ + miscellaneous/genvarname.m \ miscellaneous/getappdata.m \ miscellaneous/getfield.m \ miscellaneous/gunzip.m \