changeset 28456:53d8e7ca99c5 stable

revive legacy vectorize function for strings and function handles * scripts/legacy/__vectorize__.m, scripts/legacy/vectorize.m: New functions. * @inline/vectorize.m: Call __vectorize__ to do the transformation. * scripts/legacy/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Thu, 11 Jun 2020 16:34:34 -0400
parents 925c169a4958
children 41c5019f5dbf ef8cf8dda0ba
files scripts/legacy/@inline/vectorize.m scripts/legacy/__vectorize__.m scripts/legacy/module.mk scripts/legacy/vectorize.m
diffstat 4 files changed, 152 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/legacy/@inline/vectorize.m	Thu Jun 11 16:33:17 2020 -0400
+++ b/scripts/legacy/@inline/vectorize.m	Thu Jun 11 16:34:34 2020 -0400
@@ -31,32 +31,6 @@
     print_usage ();
   endif
 
-  new_expr = "";
-
-  expr = obj.expr;
-  len = length (expr);
-  i = 1;
-
-  while (i <= len)
-    c = expr(i);
-
-    if (c == "*" || c == "/" || c == "\\" || c == "^")
-      if (i > 1 && expr(i-1) != ".")
-        new_expr(end+1) = ".";
-      endif
-
-      ## Special case for ** operator.
-      if (c == '*' && i < (len - 1) && expr(i+1) == '*')
-        new_expr(end+1) = "*";
-        i++;
-      endif
-    endif
-
-    new_expr(end+1) = c;
-    i++;
-
-  endwhile
-
-  fcn = inline (new_expr);
+  fcn = inline (__vectorize__ (obj.expr));
 
 endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/legacy/__vectorize__.m	Thu Jun 11 16:34:34 2020 -0400
@@ -0,0 +1,58 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## 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
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn {} {} __vectorize__ (@var{expr})
+## Undocumented internal function.
+## @end deftypefn
+
+function new_expr = __vectorize__ (expr);
+
+  new_expr = "";
+
+  len = length (expr);
+  i = 1;
+
+  while (i <= len)
+    c = expr(i);
+
+    if (c == "*" || c == "/" || c == "\\" || c == "^")
+      if (i > 1 && expr(i-1) != ".")
+        new_expr(end+1) = ".";
+      endif
+
+      ## Special case for ** operator.
+      if (c == '*' && i < (len - 1) && expr(i+1) == '*')
+        new_expr(end+1) = "*";
+        i++;
+      endif
+    endif
+
+    new_expr(end+1) = c;
+    i++;
+
+  endwhile
+
+endfunction
--- a/scripts/legacy/module.mk	Thu Jun 11 16:33:17 2020 -0400
+++ b/scripts/legacy/module.mk	Thu Jun 11 16:34:34 2020 -0400
@@ -1,6 +1,7 @@
 FCN_FILE_DIRS += %reldir%
 
 %canon_reldir%_FCN_FILES = \
+  %reldir%/__vectorize__.m \
   %reldir%/findstr.m \
   %reldir%/flipdim.m \
   %reldir%/genvarname.m \
@@ -10,7 +11,8 @@
   %reldir%/setstr.m \
   %reldir%/strmatch.m \
   %reldir%/strread.m \
-  %reldir%/textread.m
+  %reldir%/textread.m \
+  %reldir%/vectorize.m
 
 ## include %reldir%/@inline/module.mk
 ## The include above fails because Automake cannot process the '@' character.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/legacy/vectorize.m	Thu Jun 11 16:34:34 2020 -0400
@@ -0,0 +1,90 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## 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
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn {} {} vectorize (@var{fun})
+## Create a vectorized version of the anonymous function or expression
+## @var{fun} by replacing all occurrences of @code{*}, @code{/}, etc.,
+## with @code{.*}, @code{./}, etc.
+##
+## Note that the transformation is extremely simplistic.  Use of this
+## function is strongly discouraged.  It may be removed from a future
+## version of Octave.
+## @end deftypefn
+
+## The following function was translated directly from the original C++
+## version.  Yes, it will be slow, but its use is strongly discouraged
+## anyway, and most expressions will probably be short.  It may also be
+## buggy.  Well, don't use this function!
+
+function retval = vectorize (fun)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (isa (fun, "function_handle"))
+    finfo = functions (fun);
+    if (! strcmp (finfo.type, "anonymous"))
+      error ("vectorize: FUN must be a string or anonymous function handle");
+    endif
+    expr = finfo.function;
+    idx = index (expr, ")");
+    args = expr(1:idx);
+    expr = expr(idx+1:end);
+    new_expr = __vectorize__ (expr);
+    retval = str2func ([args, new_expr]);
+  elseif (ischar (fun))
+    retval = __vectorize__ (fun);
+  else
+    error ("vectorize: FUN must be a string or anonymous function handle");
+  endif
+endfunction
+
+%!assert (vectorize ("x.^2 + 1"), "x.^2 + 1")
+%!test
+%! fh = @(x) x.^2 + 1;
+%! finfo = functions (vectorize (fh));
+%! assert (finfo.function, "@(x) x .^ 2 + 1");
+
+%!assert (vectorize ("1e-3*y + 2e4*z"), "1e-3.*y + 2e4.*z")
+%!test
+%! fh = @(x, y, z) 1e-3*y + 2e4*z;
+%! finfo = functions (vectorize (fh));
+%! assert (finfo.function, "@(x, y, z) 1e-3 .* y + 2e4 .* z");
+
+%!assert (vectorize ("2**x^5"), "2.**x.^5")
+## Note that ** is transformed to ^ by the code that prints the parse
+## tree.  I don't care too much about that...
+%!test
+%! fh = @(x) 2**x^5;
+%! finfo = functions (vectorize (fh));
+%! assert (finfo.function, "@(x) 2 .^ x .^ 5");
+
+## Test input validation
+%!error vectorize ()
+%!error vectorize (1, 2)
+%!error <FUN must be a string or anonymous function handle> vectorize (1)
+