Mercurial > hg > octave-nkf
diff scripts/plot/fplot.m @ 6781:3058060c560f
[project @ 2007-07-19 08:07:31 by dbateman]
author | dbateman |
---|---|
date | Thu, 19 Jul 2007 08:07:32 +0000 |
parents | 3f4ccca05612 |
children | 76e3d985ae56 |
line wrap: on
line diff
--- a/scripts/plot/fplot.m +++ b/scripts/plot/fplot.m @@ -19,50 +19,99 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} fplot (@var{fn}, @var{limits}) +## @deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{tol}) ## @deftypefnx {Function File} {} fplot (@var{fn}, @var{limits}, @var{n}) +## @deftypefnx {Function File} {} fplot (@dots{}, @var{LineSpec}) ## Plot a function @var{fn}, within the defined limits. @var{fn} ## an be either a string, a function handle or an inline function. ## The limits of the plot are given by @var{limits} of the form ## @code{[@var{xlo}, @var{xhi}]} or @code{[@var{xlo}, @var{xhi}, -## @var{ylo}, @var{yhi}]}. @var{n} is the number of points to use and -## defaults to 100. +## @var{ylo}, @var{yhi}]}. @var{tol} is the default tolerance to use for the +## plot, and if @var{tol} is an integer it is assumed that it defines the +## number points to use in the plot. The @var{LineSpec} is passed to the plot +## command. ## ## @example ## fplot ("cos", [0, 2*pi]) ## fplot ("[cos(x), sin(x)]", [0, 2*pi]) ## @end example +## @seealso{plot} ## @end deftypefn -function fplot (fn, limits, n) +function fplot (fn, limits, n, linespec) if (nargin < 2 || nargin > 3) print_usage (); endif if (nargin < 3) - n = 100; + n = 0.002; endif - x = linspace (limits(1), limits(2), n)'; + have_linespec = true; + if (nargin < 4) + have_linespec = false; + endif - nam = fn; + if (ischar (n)) + have_linespec = true; + linespec = n; + n = 0.002; + endif + if (strcmp (typeinfo (fn), "inline function")) fn = vectorize (fn); - y = fn (x); nam = formula (fn); elseif (isa (fn, "function_handle")) - y = fn (x); nam = func2str (fn); elseif (all (isalnum (fn))) - y = feval (fn, x); + nam = fn; else - finl = vectorize (inline (fn)); - y = finl (x); + fn = vectorize (inline (fn)); + nam = formula (fn); + endif + + if (floor(n) != n) + tol = n; + x0 = linspace (limits(1), limits(2), 3)'; + y0 = feval (fn, x0); + err0 = Inf; + n = 5; + x = linspace (limits(1), limits(2), n)'; + y = feval (fn, x); + + while (n < 2 .^ 20) + y00 = interp1 (x0, y0, x, "linear"); + err = 0.5 * max (abs ((y00 - y) ./ (y00 + y))(:)); + if (err == err0 || 0.5 * max (abs ((y00 - y) ./ (y00 + y))(:)) < tol) + break; + endif + x0 = x; + y0 = y; + err0 = err; + n = 2 * (n - 1) + 1; + x = linspace (limits(1), limits(2), n)'; + y = feval (fn, x); + endwhile + else + x = linspace (limits(1), limits(2), n)'; + y = feval (fn, x); endif if (length (limits) > 2) axis (limits); endif - plot (x, y, [";", nam, ";"]); - + if (have_linespec) + plot (x, y, linespec); + else + plot (x, y); + endif + if (isvector(y)) + legend (nam); + else + for i=1:columns(y) + nams{i} = sprintf ("%s(:,%i)", nam, i); + endfor + legend (nams{:}); + endif endfunction