Mercurial > forge
changeset 2086:d4a591afe37e octave-forge
Update FSF address and more texinfo in preparation for inclusion in octave
author | adb014 |
---|---|
date | Thu, 27 Oct 2005 19:51:19 +0000 |
parents | 6024b57032df |
children | a553fa229880 |
files | extra/testfun/assert.m extra/testfun/demo.m extra/testfun/example.m extra/testfun/pretty.cc extra/testfun/speed.m extra/testfun/test.m |
diffstat | 6 files changed, 295 insertions(+), 130 deletions(-) [+] |
line wrap: on
line diff
--- a/extra/testfun/assert.m Wed Oct 26 22:07:36 2005 +0000 +++ b/extra/testfun/assert.m Thu Oct 27 19:51:19 2005 +0000 @@ -12,7 +12,8 @@ ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA ## -*- texinfo -*- ## @deftypefn {Function File} {} assert (@var{cond})
--- a/extra/testfun/demo.m Wed Oct 26 22:07:36 2005 +0000 +++ b/extra/testfun/demo.m Thu Oct 27 19:51:19 2005 +0000 @@ -12,7 +12,8 @@ ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA ## -*- texinfo -*- ## @deftypefn {Function File} {} demo ('@var{name}',@var{n})
--- a/extra/testfun/example.m Wed Oct 26 22:07:36 2005 +0000 +++ b/extra/testfun/example.m Thu Oct 27 19:51:19 2005 +0000 @@ -12,7 +12,8 @@ ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA ## -*- texinfo -*- ## @deftypefn {Function File} {} example ('@var{name}',@var{n})
--- a/extra/testfun/pretty.cc Wed Oct 26 22:07:36 2005 +0000 +++ b/extra/testfun/pretty.cc Thu Oct 27 19:51:19 2005 +0000 @@ -16,17 +16,22 @@ for more details. You should have received a copy of the GNU General Public License -along with this program; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA */ #include <octave/oct.h> #include <octave/oct-strstrm.h> DEFUN_DLD (pretty, args, , -"str = pretty (v)\n\ + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{str} =} pretty (@var{v})\n\ \n\ -Equivalent to x=disp(v), but disp doesn't return a value ...") +Equivalent to @code{disp(@var{v})}, but returns the output as a string\n\ +@var{str}. +\n\ +@end deftypefn") { octave_value_list retval;
--- a/extra/testfun/speed.m Wed Oct 26 22:07:36 2005 +0000 +++ b/extra/testfun/speed.m Thu Oct 27 19:51:19 2005 +0000 @@ -12,75 +12,97 @@ ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA -## speed(f, init, max_n, f2, tol, err) +## -*- texinfo -*- +## @deftypefn {Function File} {} speed(@var{f}, @var{init}, @var{max_n}, @var{f2}, @var{tol}, @var{err}) +## @deftypefnx {Function File} {@var{r} =} speed(@dots{}) ## -## Determine the execution time of an expression for various n. -## The n are log-spaced from 1 to max_n. For each n, an -## initialization expression is computed to create whatever -## data are needed for the test. +## Determine the execution time of an expression for various @var{n}. +## The @var{n} are log-spaced from 1 to @var{max_n}. For each @var{n}, +## an initialization expression is computed to create whatever data +## are needed for the test. Called without output arguments the data +## is presented graphically. Called with an output argument @var{r}, +## the speedup ratio is returned instead of displaying it graphically. +## +## @table @code +## @item @var{f} +## The expression to evaluate. +## +## @item @var{max_n} +## The maximum test length to run. Default value is 100. ## -## f is the expression to evaluate. -## max_n = 100 is the maximum test length to run. -## init = "x = randn(n, 1);" -## Initialization expression for function argument values. Use 'k' -## for the test number and 'n' for the size of the test. This should -## compute values for all variables listed in args. Note that init -## will be evaluated first for k=0, so things which are constant -## throughout the test can be computed then. -## f2 = [] -## is an alternative expression to evaluate, so the speed of the two -## can be compared -## tol = eps -## if tol is inf, then no comparison will be made between the -## results of express f and expression f2. Otherwise, expression -## f should produce a value v and expression f2 should produce -## a value v2, and these shall be compared using assert(v,v2,tol,err) +## @item @var{init} +## Initialization expression for function argument values. Use @var{k} +## for the test number and @var{n} for the size of the test. This should +## compute values for all variables listed in args. Note that init will +## be evaluated first for k=0, so things which are constant throughout +## the test can be computed then. The default value is @code{@var{x} = +## randn (@var{n}, 1);}. ## -## r = speed (...) -## Returns the average speedup ratio instead of displaying and plotting. +## @item @var{f2} +## An alternative expression to evaluate, so the speed of the two +## can be compared. Default is @code{[]}. +## +## @item @var{tol} +## If @var{tol} is @code{Inf}, then no comparison will be made between the +## results of expression @var{f} and expression @var{f2}. Otherwise, +## expression @var{f} should produce a value @var{v} and expression @var{f2} +## should produce a value @var{v2}, and these shall be compared using +## @code{assert(@var{v},@var{v2},@var{tol},@var{err}). The default is +## @code{eps}. +## @end table ## ## Some global variables are also referenced. Choose values suitable to ## your machine and your work style. -## speed_test_plot = 1 -## if true, plot a nice speed comparison graph -## speed_test_numtests = 25 -## number of vector lengths to test +## +## @table @code +## @item speed_test_plot +## If true, plot a nice speed comparison graph. Default is true. +## +## @item speed_test_numtests +## Number of vector lengths to test. The default is 25. +## @end table ## ## Some comments on the graphs. The line on the speedup ratio graph ## should be larger than 1 if your function is faster. The slope on ## the runtime graph shows you the O(f) speed characteristics. Where it ## is flat, execution time is O(1). Where it is sloping, execution time -## is O(n^m), with steeper slopes for larger n. Generally vectorizing +## is O(n^m), with steeper slopes for larger @var{n}. Generally vectorizing ## a function will not change the slope of the run-time graph, but it ## will shift it relative to the original. ## -## Example -## % If you had an original version of xcorr using for loops and -## % another version using FFT, you could compare the run speed -## % for various lags as follows, or for a fixed lag with varying -## % vector lengths as follows: +## A simple example is +## +## @example +## speed("strrep(s,x,y)", "s=blanks(n);x=' ';y='b';", 100) +## @end example ## +## A more complex example, if you had an original version of @code{xcorr} +## using for loops and another version using an FFT, you could compare the +## run speed for various lags as follows, or for a fixed lag with varying +## vector lengths as follows: +## +## @example ## speed("v=xcorr(x,n)", "x=rand(128,1);", 100, ... ## "v2=xcorr_orig(x,n)", 100*eps,'rel') ## speed("v=xcorr(x,15)", "x=rand(20+n,1);", 100, ... ## "v2=xcorr_orig(x,n)", 100*eps,'rel') -## -## % Assuming one of the two versions is in xcorr_orig, this would -## % would compare their speed and their output values. Note that the -## % FFT version is not exact, so we specify an acceptable tolerance on -## % the comparison (100*eps), and the errors should be computed -## % relatively, as abs( (x-y)./y ) rather than absolutely as abs(x-y). +## @end example ## -## Example -## speed("strrep(s,x,y)", "s=blanks(n);x=' ';y='b';", 100) +## Assuming one of the two versions is in @var{xcorr_orig}, this would +## would compare their speed and their output values. Note that the +## FFT version is not exact, so we specify an acceptable tolerance on +## the comparison @code{100*eps}, and the errors should be computed +## relatively, as @code{abs((@var{x} - @var{y})./@var{y})} rather than +## absolutely as @code{abs(@var{x} - @var{y})}. ## -## Type example('speed') to see some real examples. Note for +## Type @code{example('speed')} to see some real examples. Note for ## obscure reasons, you can't run examples 1 and 2 directly using -## demo('speed'). Instead use: -## eval(example('speed',1)) -## eval(example('speed',2)) +## @code{demo('speed')}. Instead use, @code{eval(example('speed',1))} +## and @code{eval(example('speed',2))}. +## @end deftypefn ## TODO: consider two dimensional speedup surfaces for functions like kron. function __ratio_r = speed (__f1, __init, __max_n, __f2, __tol, __err)
--- a/extra/testfun/test.m Wed Oct 26 22:07:36 2005 +0000 +++ b/extra/testfun/test.m Thu Oct 27 19:51:19 2005 +0000 @@ -12,175 +12,307 @@ ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA -## test name -## Perform tests interactively, stopping at the first error. -## Tests are from the first file matching 'name', 'name.m' -## in your loadpath. +## -*- texinfo -*- +## @deftypefn {Function File} {} test @var{name} +## @deftypefnx {Function File} {} test @var{name} quiet|normal|verbose +## @deftypefnx {Function File} {} test ('@var{name}', 'quiet|normal|verbose', @var{fid}) +## @deftypefnx {Function File} {} test ([], 'explain', @var{fid}) +## @deftypefnx {Function File} {@var{success} =} test (@dots{}) +## @deftypefnx {Function File} {[@var{n}, @var{max}] =} test (@dots{}) +## @deftypefnx {Function File} {[@var{code}, @var{idx}] =} test ('@var{name}','grabdemo') ## -## test name quiet|normal|verbose -## Perform tests interactively, stopping at the first error. -## 'quiet': Don't report all the tests as they happen, just the errors. -## 'normal': Report all tests as they happen, but don't do tests -## which require user interaction. -## 'verbose': Do tests which require user interaction. +## Perform tests from the first file in the loadpath matching @var{name}. +## @code{test} can be called as a command or as a function. Called with +## a single argument @var{name}, the tests are run interactively and stop +## after the first error is encountered. +## +## With a second argument the tests which are performed and the amount of +## output is selected. +## +## @table @asis +## @item 'quiet' +## Don't report all the tests as they happen, just the errors. +## +## @item 'normal' +## Report all tests as they happen, but don't do tests which require +## user interaction. ## -## test('name', ['quiet'|'normal'|'verbose'], fid) -## Batch processing. Write errors to already open file fid (hopefully -## then when octave crashes this file will tell you what was happening -## when it did). You can use stdout if you want to see the results as -## they happen. You can also give a file name rather than an fid, in -## which case the contents of the file will be replaced with the log -## from the current test. +## @item 'verbose' +## Do tests which require user interaction. +## @end table ## -## success = test(...) -## return true if all the tests succeeded. +## The argument @var{fid} can be used to allow batch processing. Errors +## can be written to the already open file defined by @var{fid}, and +## hopefully when octave crashes this file will tell you what was happening +## when it did. You can use @code{stdout} if you want to see the results as +## they happen. You can also give a file name rather than an @var{fid}, in +## which case the contents of the file will be replaced with the log from +## the current test. ## -## [n, max] = test(...) -## return number of success and number of tests +## Called with a single output argument @var{success}, @code{test} returns +## true is all of the tests were successful. Called with two output arguments +## @var{n} and @var{max}, the number of sucessful test and the total number +## of tests in the file @var{name} are returned. ## -## [code, idx] = test('name', 'grabdemo') -## Extract the contents of the demo blocks, but do not execute them. -## code is the concatenation of all the code blocks and -## idx is a vector of positions of the ends of the demo blocks. +## If the second argument is the string 'grabdemo', the contents of the demo +## blocks are extracted but not executed. Code for all code blocks is +## concatented and returned as @var{code} with @var{idx} being a vector of +## positions of the ends of the demo blocks. ## -## test('', 'explain', fid) -## Write an explanation of the line markers to the file fid. +## If the second argument is 'explain', then @var{name} is ignored and an +## explanation of the line markers used is written to the file @var{fid}. ## -## This function process the named script file looking for lines which -## start with "%! ". The prefix is stripped off and the rest of the -## line is processed through the octave interpreter. If the code +## @c USE THE TEXT FROM HERE TO CREATE OCTAVE MANUAL ENTRY +## @code{test} scans the named script file looking for lines which +## start with @code{%!}. The prefix is stripped off and the rest of the +## line is processed through the octave interpreter. If the code ## generates an error, then the test is said to fail. ## -## Since eval() will stop at the first error it encounters, you must +## Since @code{eval()} will stop at the first error it encounters, you must ## divide your tests up into blocks, with anything in a separate ## block evaluated separately. Blocks are introduced by the keyword -## 'test' immediately following the '%!'. For example, +## @code{test} immediately following the @code{%!}. For example, +## +## @example +## @group ## %!test error("this test fails!"); ## %!test "this test doesn't fail since it doesn't generate an error"; +## @end group +## @end example +## ## When a test fails, you will see something like: +## +## @example +## @group ## ***** test error('this test fails!') ## !!!!! test failed ## this test fails! +## @end group +## @end example ## ## Generally, to test if something works, you want to assert that it ## produces a correct value. A real test might look something like +## +## @example +## @group ## %!test -## %! A = [1, 2, 3; 4, 5, 6]; B = [1; 2]; -## %! expect = [ A ; 2*A ]; -## %! get = kron (B, A); +## %! @var{a} = [1, 2, 3; 4, 5, 6]; B = [1; 2]; +## %! expect = [ @var{a} ; 2*@var{a} ]; +## %! get = kron (@var{b}, @var{a}); ## %! if (any(size(expect) != size(get))) ## %! error ("wrong size: expected %d,%d but got %d,%d", ## %! size(expect), size(get)); ## %! elseif (any(any(expect!=get))) ## %! error ("didn't get what was expected."); ## %! endif -## To make the process easier, use the assert function. For example, -## with assert the previous test is reduced to: +## @end group +## @end example +## +## To make the process easier, use the @code{assert} function. For example, +## with @code{assert} the previous test is reduced to: +## +## @example +## @group ## %!test -## %! A = [1, 2, 3; 4, 5, 6]; B = [1; 2]; -## %! assert (kron (B, A), [ A; 2*A ]); -## Assert can accept a tolerance so that you can compare results +## %! @var{a} = [1, 2, 3; 4, 5, 6]; @var{b} = [1; 2]; +## %! assert (kron (@var{b}, @var{a}), [ @var{a}; 2*@var{a} ]); +## @end group +## @end example +## +## @code{assert} can accept a tolerance so that you can compare results ## absolutely or relatively. For example, the following all succeed: +## +## @example +## @group ## %!test assert (1+eps, 1, 2*eps) # absolute error ## %!test assert (100+100*eps, 100, -2*eps) # relative error +## @end group +## @end example +## ## You can also do the comparison yourself, but still have assert ## generate the error: +## +## @example +## @group ## %!test assert (isempty([])) ## %!test assert ([ 1,2; 3,4 ] > 0) -## Because assert is so frequently used alone in a test block, there +## @end group +## @end example +## +## Because @code{assert} is so frequently used alone in a test block, there ## is a shorthand form: -## %!assert (...) +## +## @example +## %!assert (@dots{}) +## @end example +## ## which is equivalent to: -## %!test assert (...) +## +## @example +## %!test assert (@dots{}) +## @end example ## ## Each block is evaluated in its own function environment, which means ## that variables defined in one block are not automatically shared ## with other blocks. If you do want to share variables, then you -## must declare them as shared before you use them. For example, the -## following declares the variable A, gives it an initial value (default +## must declare them as @code{shared} before you use them. For example, the +## following declares the variable @var{a}, gives it an initial value (default ## is empty), then uses it in several subsequent tests. -## %!shared A -## %! A = [1, 2, 3; 4, 5, 6]; -## %!assert (kron ([1; 2], A), [ A; 2*A ]); -## %!assert (kron ([1, 2], A), [ A, 2*A ]); -## %!assert (kron ([1,2; 3,4], A), [ A,2*A; 3*A,4*A ]); +## +## @example +## @group +## %!shared @var{a} +## %! @var{a} = [1, 2, 3; 4, 5, 6]; +## %!assert (kron ([1; 2], @var{a}), [ @var{a}; 2*@var{a} ]); +## %!assert (kron ([1, 2], @var{a}), [ @var{a}, 2*@var{a} ]); +## %!assert (kron ([1,2; 3,4], @var{a}), [ @var{a},2*@var{a}; 3*@var{a},4*@var{a} ]); +## @end group +## @end example +## ## You can share several variables at the same time: -## %!shared A, B +## +## @example +## %!shared @var{a}, @var{b} +## @end example +## ## You can also share test functions: +## +## @example +## @group ## %!shared fn -## %!function a = fn(b) -## %! a = 2*b; -## %!assert (a(2),4); +## %!function @var{a} = fn(@var{b}) +## %! @var{a} = 2*@var{b}; +## %!assert (@var{a}(2),4); +## @end group +## @end example +## ## Note that all previous variables and values are lost when a new ## shared block is declared. ## ## Error and warning blocks are like test blocks, but they only succeed ## if the code generates an error. You can check the text of the error -## is correct using an optional regular expression <pattern>. For example: +## is correct using an optional regular expression @code{<pattern>}. +## For example: +## +## @example ## %!error <passes!> error('this test passes!'); +## @end example +## ## If the code doesn't generate an error, the test fails. For example, +## +## @example ## %!error "this is an error because it succeeds."; +## @end example +## ## produces +## +## @example +## @group ## ***** error "this is an error because it succeeds."; ## !!!!! test failed: no error +## @end group +## @end example ## ## It is important to automate the tests as much as possible, however ## some tests require user interaction. These can be isolated into ## demo blocks, which if you are in batch mode, are only run when -## called with 'demo' or 'verbose'. The code is displayed before +## called with @code{demo} or @code{verbose}. The code is displayed before ## it is executed. For example, +## +## @example +## @group ## %!demo -## %! t=[0:0.01:2*pi]; x=sin(t); -## %! plot(t,x); +## %! @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t}); +## %! plot(@var{t},@var{x}); ## %! ## you should now see a sine wave in your figure window +## @end group +## @end example +## ## produces -## > t=[0:0.01:2*pi]; x=sin(t); -## > plot(t,x); +## +## @example +## @group +## > @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t}); +## > plot(@var{t},@var{x}); ## > ## you should now see a sine wave in your figure window ## Press <enter> to continue: +## @end group +## @end example +## ## Note that demo blocks cannot use any shared variables. This is so ## that they can be executed by themselves, ignoring all other tests. ## -## If you want to temporarily disable a test block, put '#' in place +## If you want to temporarily disable a test block, put @code{#} in place ## of the block type. This creates a comment block which is echoed ## in the log file, but is not executed. For example: +## +## @example +## @group ## %!#demo -## %! t=[0:0.01:2*pi]; x=sin(t); -## %! plot(t,x); +## %! @var{t}=[0:0.01:2*pi]; @var{x}=sin(@var{t}); +## %! plot(@var{t},@var{x}); ## %! ## you should now see a sine wave in your figure window +## @end group +## @end example ## ## Block type summary: -## %!test - check that entire block is correct -## %!error - check for correct error message -## %!warning - check for correct warning message -## %!demo - demo only executes in interactive mode -## %!# - comment: ignore everything within the block -## %!shared x,y,z - declares variables for use in multiple tests -## %!function - defines a function value for a shared variable -## %!assert (x, y, tol) - shorthand for %!test assert (x, y, tol) +## +## @table @code +## @item %!test +## check that entire block is correct +## @item %!error +## check for correct error message +## @item %!warning +## check for correct warning message +## @item %!demo +## demo only executes in interactive mode +## @item %!# +## comment: ignore everything within the block +## @item %!shared x,y,z +## declares variables for use in multiple tests +## @item %!function +## defines a function value for a shared variable +## @item %!assert (x, y, tol) +## shorthand for %!test assert (x, y, tol) +## @end table ## ## You can also create test scripts for builtins and your own C++ ## functions. Just put a file of the function name on your path without ## any extension and it will be picked up by the test procedure. You ## can even embed tests directly in your C++ code: +## +## @example +## @group ## #if 0 ## %!test disp('this is a test') ## #endif +## @end group +## @end example +## ## or +## +## @example +## @group ## /* ## %!test disp('this is a test') ## */ +## @end group +## @end example +## ## but then the code will have to be on the load path and the user ## will have to remember to type test('name.cc'). Conversely, you ## can separate the tests from normal octave script files by putting ## them in plain files with no extension rather than in script files. -## Don't forget to tell emacs that the plain text file you are using -## is actually octave code, using something like: -## ## -*-octave-*- +## @c DO I WANT TO INCLUDE THE EDITOR SPECIFIC STATEMENT BELOW??? +## @c Don't forget to tell emacs that the plain text file you are using +## @c is actually octave code, using something like: +## @c ## -*-octave-*- ## -## See Also: error, assert, fail, demo, example +## @end deftypefn +## @seealso{error, assert, fail, demo, example} ## TODO: * Consider using keyword fail rather then error? This allows us ## TODO: to make a functional form of error blocks, which means we @@ -202,9 +334,12 @@ if (nargin < 3) __fid = []; endif - if (nargin < 1 || nargin > 3 || !ischar(__name) || !ischar(__flag)) + if (nargin < 1 || nargin > 3 || (!ischar(__name) && !isempty(__name)) || !ischar(__flag)) usage("success = test('name', ['quiet'|'normal'|'verbose'], fid)"); endif + if (isempty(__name) && (nargin != 3 || !strcmp(__flag, "explain"))) + usage("test([], 'explain', fid)"); + endif __batch = (!isempty(__fid)); ## decide if error messages should be collected