changeset 21831:1077f09a0cfd

fplot.m: Handle input functions which do not respect input data orientation (bug #48034). * fplot.m: If number of outputs is equal to number of inputs, but orientation is incorrect, then set fcn_transpose mode. In this mode, always transpose results of function evaluation. Add new BIST tests.
author Rik <rik@octave.org>
date Mon, 06 Jun 2016 15:53:45 -0700
parents cbd8cf0a8a5c
children 7fe10fcd8370
files scripts/plot/draw/fplot.m
diffstat 1 files changed, 34 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/plot/draw/fplot.m	Mon Jun 06 11:22:17 2016 -0700
+++ b/scripts/plot/draw/fplot.m	Mon Jun 06 15:53:45 2016 -0700
@@ -138,15 +138,23 @@
     y = feval (fn, x);
   endif
 
-  if (rows (x0) != rows (y0))
+  if (rows (x0) == rows (y0))
+    fcn_transpose = false;
+  elseif (rows (x0) == columns (y0))
+    fcn_transpose = true;
+    y0 = y0.';
+    y = y.';
+  elseif (isscalar (y0))
     ## FN is a constant value function
     y0 = repmat (y0, size (x0));
     y = repmat (y, size (x));
+  else
+    error ("fplot: invalid function FN (# of outputs not equal to inputs)");
   endif
 
   err0 = Inf;
 
-  ## FIXME: This algorithm should really use adaptive scaling as the
+  ## FIXME: This algorithm should really use adaptive scaling as
   ##        the numerical quadrature algorithms do so that extra points are
   ##        used where they are needed and not spread evenly over the entire
   ##        x-range.  Try any function with a discontinuity, such as
@@ -169,6 +177,9 @@
     n = 2 * (n - 1) + 1;
     x = linspace (limits(1), limits(2), n)';
     y = feval (fn, x);
+    if (fcn_transpose)
+      y = y.';
+    endif
   endwhile
 
   if (nargout == 2)
@@ -205,17 +216,33 @@
 
 %!demo
 %! clf;
-%! %% sinc function
 %! fh = @(x) sin (pi*x) ./ (pi*x);
 %! fplot (fh, [-5, 5]);
-%! title ('fplot() sinc function');
+%! title ('fplot() sinc function (possible division by 0, near 0)');
 
 %!test
+%! ## Multi-valued function
 %! [x, y] = fplot ("[cos(x), sin(x)]", [0, 2*pi]);
 %! assert (columns (y) == 2);
 %! assert (rows (x) == rows (y));
 %! assert (y, [cos(x), sin(x)], -2e-3);
 
+%!test
+%! ## Function requiring transpose
+%! fn = @(x) 2 * x(:).';
+%! [x, y] = fplot (fn, [-1, 1]);
+%! assert (columns (y) == 1);
+%! assert (rows (x) == rows (y));
+%! assert (y, 2*x);
+
+%!test
+%! ## Constant value function
+%! fn = @(x) 5;
+%! [x, y] = fplot (fn, [-1, 1]);
+%! assert (columns (y) == 1);
+%! assert (rows (x) == rows (y));
+%! assert (y, repmat ([5], size (x)));
+
 ## Test input validation
 %!error fplot (1)
 %!error fplot (1,2,3,4,5,6)
@@ -224,4 +251,7 @@
 %!error <LIMITS must be a real vector with 2 or 4> fplot (@cos, [1])
 %!error <LIMITS must be a real vector with 2 or 4> fplot (@cos, [1 2 3])
 %!error <bad input in position 3> fplot (@cos,[-1,1], {1})
+%!error <invalid function FN>
+%! fn = @(x) [x;x];
+%! fplot (fn, [-1,1]);