Mercurial > hg > octave-lojdl
changeset 14052:024a050fc147
maint: periodic merge of stable to default
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 14 Dec 2011 17:54:15 -0500 |
parents | 29e9eb59f917 (current diff) f07f7dd0d4df (diff) |
children | 88029530ffbc |
files | |
diffstat | 49 files changed, 694 insertions(+), 396 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac +++ b/configure.ac @@ -649,7 +649,7 @@ OCTAVE_CHECK_LIBRARY(qhull, QHull, [Qhull library not found -- this will result in loss of functionality of some geometry functions.], - [qhull/qhull_a.h], [qh_qhull], [], [], + [qhull/libqhull.h libqhull.h qhull/qhull.h qhull.h], [qh_qhull], [], [], [warn_qhull= OCTAVE_CHECK_QHULL_VERSION OCTAVE_CHECK_QHULL_OK([TEXINFO_QHULL="@set HAVE_QHULL"
--- a/doc/interpreter/basics.txi +++ b/doc/interpreter/basics.txi @@ -1059,7 +1059,7 @@ lines "@code{disp(2);}" and "@code{disp(1);}" won't be executed. The block comment markers must appear alone as the only characters on a line -(excepting whitespace) in order to to be parsed correctly. +(excepting whitespace) in order to be parsed correctly. @node Comments and the Help System @subsection Comments and the Help System
--- a/doc/interpreter/container.txi +++ b/doc/interpreter/container.txi @@ -374,7 +374,8 @@ Besides the index operator ".", Octave can use dynamic naming "(var)" or the @code{struct} function to create structures. Dynamic naming uses the string -value of a variable as the field name. For example, +value of a variable as the field name. For example: + @example @group a = "field2";
--- a/doc/interpreter/contrib.txi +++ b/doc/interpreter/contrib.txi @@ -71,7 +71,7 @@ @end example You may want to get familiar with Mercurial queues to manage your -changesets. Here is a slightly more complex example using Mercurial +changesets. Here is a slightly more complex example using Mercurial queues, where work on two unrelated changesets is done in parallel and one of the changesets is updated after discussion on the maintainers mailing list: @@ -154,7 +154,7 @@ look for methods before constructors * symtab.cc (symbol_table::fcn_info::fcn_info_rep::find): -Look for class methods before constructors, contrary to Matlab +Look for class methods before constructors, contrary to @sc{matlab} documentation. * test/ctor-vs-method: New directory of test classes.
--- a/doc/interpreter/debug.txi +++ b/doc/interpreter/debug.txi @@ -190,11 +190,11 @@ @cindex profiler @cindex code profiling -Octave supports profiling of code execution on a per-function level. If +Octave supports profiling of code execution on a per-function level. If profiling is enabled, each call to a function (supporting built-ins, operators, functions in oct- and mex-files, user-defined functions in Octave code and anonymous functions) is recorded while running Octave -code. After that, this data can aid in analyzing the code behavior, and +code. After that, this data can aid in analyzing the code behavior, and is in particular helpful for finding ``hot spots'' in the code which use up a lot of computation time and are the best targets to spend optimization efforts on. @@ -207,7 +207,7 @@ @DOCSTRING(profile) An easy way to get an overview over the collected data is -@code{profshow}. This function takes the profiler data returned by +@code{profshow}. This function takes the profiler data returned by @code{profile} as input and prints a flat profile, for instance: @example @@ -223,7 +223,7 @@ This shows that most of the run time was spent executing the function @samp{myfib}, and some minor proportion evaluating the listed binary -operators. Furthermore, it is shown how often the function was called +operators. Furthermore, it is shown how often the function was called and the profiler also records that it is recursive. @DOCSTRING(profshow) @@ -233,12 +233,11 @@ @node Profiler Example @section Profiler Example -Below, we will give a short example of a profiler session. See also +Below, we will give a short example of a profiler session. See also @ref{Profiling} for the documentation of the profiler functions in -detail. Consider the code: +detail. Consider the code: @example -@group global N A; N = 300; @@ -274,7 +273,6 @@ fib = bar (N - 1) + bar (N - 2); endif endfunction -@end group @end example If we execute the two main functions, we get: @@ -291,7 +289,7 @@ But this does not give much information about where this time is spent; for instance, whether the single call to @code{expm} is more expensive -or the recursive time-stepping itself. To get a more detailed picture, +or the recursive time-stepping itself. To get a more detailed picture, we can use the profiler. @example @@ -326,29 +324,29 @@ The entries are the individual functions which have been executed (only the 10 most important ones), together with some information for each of -them. The entries like @samp{binary *} denote operators, while other -entries are ordinary functions. They include both built-ins like -@code{expm} and our own routines (for instance @code{timesteps}). From +them. The entries like @samp{binary *} denote operators, while other +entries are ordinary functions. They include both built-ins like +@code{expm} and our own routines (for instance @code{timesteps}). From this profile, we can immediately deduce that @code{expm} uses up the largest proportion of the processing time, even though it is only called -once. The second expensive operation is the matrix-vector product in the -routine @code{timesteps}. @footnote{We only know it is the binary +once. The second expensive operation is the matrix-vector product in the +routine @code{timesteps}. @footnote{We only know it is the binary multiplication operator, but fortunately this operator appears only at one place in the code and thus we know which occurrence takes so much -time. If there were multiple places, we would have to use the +time. If there were multiple places, we would have to use the hierarchical profile to find out the exact place which uses up the time which is not covered in this example.} Timing, however, is not the only information available from the profile. The attribute column shows us that @code{timesteps} calls itself -recursively. This may not be that remarkable in this example (since it's -clear anyway), but could be helpful in a more complex setting. As to the +recursively. This may not be that remarkable in this example (since it's +clear anyway), but could be helpful in a more complex setting. As to the question of why is there a @samp{binary \} in the output, we can easily -shed some light on that too. Note that @code{data} is a structure array +shed some light on that too. Note that @code{data} is a structure array (@ref{Structure Arrays}) which contains the field @code{FunctionTable}. -This stores the raw data for the profile shown. The number in the first +This stores the raw data for the profile shown. The number in the first column of the table gives the index under which the shown function can -be found there. Looking up @code{data.FunctionTable(41)} gives: +be found there. Looking up @code{data.FunctionTable(41)} gives: @example @group @@ -364,13 +362,13 @@ @end example Here we see the information from the table again, but have additional -fields @code{Parents} and @code{Children}. Those are both arrays, which +fields @code{Parents} and @code{Children}. Those are both arrays, which contain the indices of functions which have directly called the function in question (which is entry 7, @code{expm}, in this case) or been called -by it (no functions). Hence, the backslash operator has been used +by it (no functions). Hence, the backslash operator has been used internally by @code{expm}. -Now let's take a look at @code{bar}. For this, we start a fresh +Now let's take a look at @code{bar}. For this, we start a fresh profiling session (@code{profile on} does this; the old data is removed before the profiler is restarted): @@ -387,6 +385,7 @@ This gives: @example +@group # Function Attr Time (s) Calls ------------------------------------------------------- 1 bar R 2.091 13529 @@ -398,14 +397,15 @@ 6 nargin 0.000 1 7 binary != 0.000 1 9 __profiler_enable__ 0.000 1 +@end group @end example -Unsurprisingly, @code{bar} is also recursive. It has been called 13,529 +Unsurprisingly, @code{bar} is also recursive. It has been called 13,529 times in the course of recursively calculating the Fibonacci number in a suboptimal way, and most of the time was spent in @code{bar} itself. Finally, let's say we want to profile the execution of both @code{foo} -and @code{bar} together. Since we already have the run-time data +and @code{bar} together. Since we already have the run-time data collected for @code{bar}, we can restart the profiler without clearing the existing data and collect the missing statistics about @code{foo}. This is done by:
--- a/doc/interpreter/expr.txi +++ b/doc/interpreter/expr.txi @@ -55,28 +55,38 @@ Indices may be scalars, vectors, ranges, or the special operator @samp{:}, which may be used to select entire rows or columns. -Vectors are indexed using a single index expression. Matrices may be -indexed using one or two indices. When using a single index -expression, the elements of the matrix are taken in column-first order; -the dimensions of the output match those of the index expression. For -example, +Vectors are indexed using a single index expression. Matrices (2-D) +and higher multi-dimensional arrays are indexed using either one index +or @math{N} indices where @math{N} is the dimension of the array. +When using a single index expression to index 2-D or higher data the +elements of the array are taken in column-first order (like Fortran). + +The output from indexing assumes the dimensions of the index +expression. For example: @example @group -a(2) # a scalar -a(1:2) # a row vector -a([1; 2]) # a column vector +a(2) # result is a scalar +a(1:2) # result is a row vector +a([1; 2]) # result is a column vector @end group @end example As a special case, when a colon is used as a single index, the output -is a column vector containing all the elements of the vector or matrix. -For example: +is a column vector containing all the elements of the vector or +matrix. For example: @example -a(:) # a column vector +@group +a(:) # result is a column vector +a(:)' # result is a row vector +@end group @end example +The above two code idioms are often used in place of @code{reshape} +when a simple vector, rather than an arbitrarily sized array, is +needed. + Given the matrix @example @@ -84,32 +94,89 @@ @end example @noindent -all of the following expressions are equivalent +all of the following expressions are equivalent and select the first +row of the matrix. @example @group -a(1, [1, 2]) -a(1, 1:2) -a(1, :) +a(1, [1, 2]) # row 1, columns 1 and 2 +a(1, 1:2) # row 1, columns in range 1-2 +a(1, :) # row 1, all columns +@end group +@end example + +@cindex @code{end}, indexing +@cindex :end + +In index expressions the keyword @code{end} automatically refers to +the last entry for a particular dimension. This magic index can also +be used in ranges and typically eliminates the needs to call +@code{size} or @code{length} to gather array bounds before indexing. +For example: + +@example +@group +a = [1, 2, 3, 4]; + +a(1:end/2) # first half of a => [1, 2] +a(end + 1) = 5; # append element +a(end) = []; # delete element +a(1:2:end) # odd elements of a => [1, 3] +a(2:2:end) # even elements of a => [2, 4] +a(end:-1:1) # reversal of a => [4, 3, 2 , 1] @end group @end example -@noindent -and select the first row of the matrix. +@menu +* Advanced Indexing:: +@end menu + +@node Advanced Indexing +@subsection Advanced Indexing + +An array with @samp{n} dimensions can be indexed using @samp{m} +indices. More generally, the set of index tuples determining the +result is formed by the Cartesian product of the index vectors (or +ranges or scalars). + +For the ordinary and most common case, @w{@code{m == n}}, and each +index corresponds to its respective dimension. If @w{@code{m < n}} +and every index is less than the size of the array in the +@math{i^{th}} dimension, @code{m(i) < n(i)}, then the index expression +is padded with trailing singleton dimensions (@code{[ones (m-n, 1)]}). +If @w{@code{m < n}} but one of the indices @code{m(i)} is outside the +size of the current array, then the last @w{@code{n-m+1}} dimensions +are folded into a single dimension with an extent equal to the product +of extents of the original dimensions. This is easiest to understand +with an example. -In general, an array with @samp{n} dimensions can be indexed using @samp{m} -indices. If @code{n == m}, each index corresponds to its respective dimension. -The set of index tuples determining the result is formed by the Cartesian -product of the index vectors (or ranges or scalars). If @code{n < m}, then the -array is padded by trailing singleton dimensions. If @code{n > m}, the last -@code{n-m+1} dimensions are folded into a single dimension with extent equal to -product of extents of the original dimensions. +@example +a = reshape (1:8, 2, 2, 2) # Create 3-D array +a = + +ans(:,:,1) = + + 1 3 + 2 4 + +ans(:,:,2) = + + 5 7 + 6 8 -@c FIXED -- sections on variable prefer_zero_one_indexing were removed +a(2,1,2); # Case (m == n): ans = 6 +a(2,1); # Case (m < n), idx within array: + # equivalent to a(2,1,1), ans = 2 +a(2,4); # Case (m < n), idx outside array: + # Dimension 2 & 3 folded into new dimension of size 2x2 = 4 + # Select 2nd row, 4th element of [2, 4, 6, 8], ans = 8 +@end example -Indexing a scalar with a vector of ones can be used to create a -vector the same size as the index vector, with each element equal to -the value of the original scalar. For example, the following statements +One advanced use of indexing is to create arrays filled with a single +value. This can be done by using an index of ones on a scalar value. +The result is an object with the dimensions of the index expression +and every element equal to the original scalar. For example, the +following statements @example @group @@ -121,8 +188,8 @@ @noindent produce a vector whose four elements are all equal to 13. -Similarly, indexing a scalar with two vectors of ones can be used to -create a matrix. For example the following statements +Similarly, by indexing a scalar with two vectors of ones it is +possible to create a matrix. The following statements @example @group @@ -132,20 +199,35 @@ @end example @noindent -create a 2 by 3 matrix with all elements equal to 13. +create a 2x3 matrix with all elements equal to 13. The last example could also be written as @example @group -13 (ones (2, 3)) +13(ones (2, 3)) @end group @end example -It should be, noted that @code{ones (1, n)} (a row vector of ones) results in a -range (with zero increment), and is therefore more efficient when used in index -expression than other forms of @dfn{ones}. In particular, when @samp{r} is a -row vector, the expressions +It is more efficient to use indexing rather than the code construction +@code{scalar * ones (N, M, @dots{})} because it avoids the unnecessary +multiplication operation. Moreover, multiplication may not be +defined for the object to be replicated whereas indexing an array is +always defined. The following code shows how to create a 2x3 cell +array from a base unit which is not itself a scalar. + +@example +@group +@{"Hello"@}(ones (2, 3)) +@end group +@end example + +It should be, noted that @code{ones (1, n)} (a row vector of ones) +results in a range (with zero increment). A range is stored +internally as a starting value, increment, end value, and total number +of values; hence, it is more efficient for storage than a vector or +matrix of ones whenever the number of elements is greater than 4. In +particular, when @samp{r} is a row vector, the expressions @example r(ones (1, n), :) @@ -156,17 +238,22 @@ @end example @noindent -will produce identical results, but the first one will be significantly -faster, at least for @samp{r} and @samp{n} large enough. The reason is that -in the first case the index is kept in a compressed form, which allows Octave -to choose a more efficient algorithm to handle the expression. +will produce identical results, but the first one will be +significantly faster, at least for @samp{r} and @samp{n} large enough. +In the first case the index is held in compressed form as a range +which allows Octave to choose a more efficient algorithm to handle the +expression. -In general, for an user unaware of these subtleties, it is best to use -the function @dfn{repmat} for spreading arrays into bigger ones. +A general recommendation, for a user unaware of these subtleties, is +to use the function @code{repmat} for replicating smaller arrays into +bigger ones. -It is also possible to create a matrix with different values. The -following example creates a 10 dimensional row vector @math{a} containing -the values +A second use of indexing is to speed up code. Indexing is a fast +operation and judicious use of it can reduce the requirement for +looping over individual array elements which is a slow operation. + +Consider the following example which creates a 10-element row vector +@math{a} containing the values @tex $a_i = \sqrt{i}$. @end tex @@ -183,20 +270,22 @@ @end example @noindent -Note that it is quite inefficient to create a vector using a loop like -the one shown in the example above. In this particular case, it would -have been much more efficient to use the expression +It is quite inefficient to create a vector using a loop like this. In +this case, it would have been much more efficient to use the +expression @example a = sqrt (1:10); @end example @noindent -thus avoiding the loop entirely. In cases where a loop is still -required, or a number of values must be combined to form a larger -matrix, it is generally much faster to set the size of the matrix first, -and then insert elements using indexing commands. For example, given a -matrix @code{a}, +which avoids the loop entirely. + +In cases where a loop cannot be avoided, or a number of values must be +combined to form a larger matrix, it is generally faster to set the +size of the matrix first (pre-allocate storage), and then insert +elements using indexing commands. For example, given a matrix +@code{a}, @example @group @@ -221,8 +310,8 @@ @end example @noindent -particularly for large matrices because Octave does not have to -repeatedly resize the result. +because Octave does not have to repeatedly resize the intermediate +result. @DOCSTRING(sub2ind)
--- a/doc/interpreter/func.txi +++ b/doc/interpreter/func.txi @@ -290,8 +290,8 @@ values distinct names. It is possible to use the @code{nthargout} function to obtain only some -of the return values or several at once in a cell array. @ref{Cell Array -Objects} +of the return values or several at once in a cell array. +@ref{Cell Array Objects} @DOCSTRING(nthargout)
--- a/doc/interpreter/install.txi +++ b/doc/interpreter/install.txi @@ -82,7 +82,7 @@ @item --disable-docs Disable building all forms of the documentation (Info, PDF, HTML). The default is to build documentation, but your system will need functioning -Texinfo and Tex installs for this to succeed. +Texinfo and @TeX{} installs for this to succeed. @item --enable-float-truncate This option allows for truncation of intermediate floating point results
--- a/doc/interpreter/intro.txi +++ b/doc/interpreter/intro.txi @@ -562,7 +562,9 @@ Here is a description of an imaginary function @code{foo}: -@deftypefn {Function} {} foo (@var{x}, @var{y}, @dots{}) +@deftypefn {Function} {} foo (@var{x}) +@deftypefnx {Function} {} foo (@var{x}, @var{y}) +@deftypefnx {Function} {} foo (@var{x}, @var{y}, @dots{}) The function @code{foo} subtracts @var{x} from @var{y}, then adds the remaining arguments to the result. If @var{y} is not supplied, then the number 19 is used by default.
--- a/doc/interpreter/io.txi +++ b/doc/interpreter/io.txi @@ -582,7 +582,7 @@ @item @samp{%x}, @samp{%X} Print an integer as an unsigned hexadecimal number. @samp{%x} uses -lower-case letters and @samp{%X} uses upper-case. @xref{Integer +lowercase letters and @samp{%X} uses uppercase. @xref{Integer Conversions}, for details. @item @samp{%f} @@ -591,13 +591,13 @@ @item @samp{%e}, @samp{%E} Print a floating-point number in exponential notation. @samp{%e} uses -lower-case letters and @samp{%E} uses upper-case. @xref{Floating-Point +lowercase letters and @samp{%E} uses uppercase. @xref{Floating-Point Conversions}, for details. @item @samp{%g}, @samp{%G} Print a floating-point number in either normal (fixed-point) or exponential notation, whichever is more appropriate for its magnitude. -@samp{%g} uses lower-case letters and @samp{%G} uses upper-case. +@samp{%g} uses lowercase letters and @samp{%G} uses uppercase. @xref{Floating-Point Conversions}, for details. @item @samp{%c}
--- a/doc/interpreter/octave.texi +++ b/doc/interpreter/octave.texi @@ -383,6 +383,10 @@ * Increment Ops:: * Operator Precedence:: +Index Expressions + +* Advanced Indexing:: + Calling Functions * Call by Value::
--- a/doc/interpreter/package.txi +++ b/doc/interpreter/package.txi @@ -206,7 +206,7 @@ @item package/NEWS This is an optional file describing all user-visible changes worth -mentioning. As this file increases on size, old entries can be moved +mentioning. As this file increases on size, old entries can be moved into @file{package/ONEWS}. @item package/ONEWS
--- a/doc/interpreter/testfun.txi +++ b/doc/interpreter/testfun.txi @@ -34,20 +34,20 @@ @DOCSTRING(test) -@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 +@code{test} scans the named script file looking for lines which start +with the identifier @samp{%!}. 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 @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 -@code{test} immediately following the @code{%!}. For example: +@code{test} immediately following @samp{%!}. For example: @example @group - %!test error ("this test fails!"); - %!test "test doesn't fail. it doesn't generate an error"; +%!test error ("this test fails!"); +%!test "test doesn't fail. it doesn't generate an error"; @end group @end example @@ -55,9 +55,9 @@ @example @group - ***** test error ('this test fails!') - !!!!! test failed - this test fails! + ***** test error ("this test fails!") +!!!!! test failed +this test fails! @end group @end example @@ -66,16 +66,16 @@ @example @group - %!test - %! @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 +%!test +%! @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 @end group @end example @@ -84,9 +84,9 @@ @example @group - %!test - %! @var{a} = [1, 2, 3; 4, 5, 6]; @var{b} = [1; 2]; - %! assert (kron (@var{b}, @var{a}), [ @var{a}; 2*@var{a} ]); +%!test +%! @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 @@ -95,8 +95,8 @@ @example @group - %!test assert (1+eps, 1, 2*eps) # absolute error - %!test assert (100+100*eps, 100, -2*eps) # relative error +%!test assert (1+eps, 1, 2*eps) # absolute error +%!test assert (100+100*eps, 100, -2*eps) # relative error @end group @end example @@ -105,8 +105,8 @@ @example @group - %!test assert (isempty([])) - %!test assert ([ 1,2; 3,4 ] > 0) +%!test assert (isempty ([])) +%!test assert ([1, 2; 3, 4] > 0) @end group @end example @@ -114,16 +114,32 @@ is a shorthand form: @example - %!assert (@dots{}) +%!assert (@dots{}) @end example @noindent which is equivalent to: @example - %!test assert (@dots{}) +%!test assert (@dots{}) @end example +Occasionally a block of tests will depend on having optional +functionality in Octave. Before testing such blocks the availability of +the required functionality must be checked. A @code{%!testif HAVE_XXX} +block will only be run if Octave was compiled with functionality +@samp{HAVE_XXX}. For example, the sparse single value decomposition, +@code{svds()}, depends on having the @sc{arpack} library. All of the tests +for @code{svds} begin with + +@example +%!testif HAVE_ARPACK +@end example + +@noindent +Review @file{config.h} or @code{octave_config_info ("DEFS")} to see some +of the possible values to check. + Sometimes during development there is a test that should work but is known to fail. You still want to leave the test in because when the final code is ready the test should pass, but you may not be able to @@ -132,45 +148,49 @@ @example @group - %!xtest assert (1==0) - %!xtest fail ('success=1','error')) +%!xtest assert (1==0) +%!xtest fail ("success=1", "error") @end group @end example -Another use of @code{xtest} is for statistical tests which should -pass most of the time but are known to fail occasionally. +@noindent +In this case, the test will run and any failure will be reported. +However, testing is not aborted and subsequent test blocks will be +processed normally. Another use of @code{xtest} is for statistical +tests which should pass most of the time but are known to fail +occasionally. 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 @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. +is empty), and then uses it in several subsequent tests. @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} ]); +%!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: @example - %!shared @var{a}, @var{b} +%!shared @var{a}, @var{b} @end example You can also share test functions: @example @group - %!function @var{a} = fn (@var{b}) - %! @var{a} = 2*@var{b}; - %!endfunction - %!assert (@var{fn}(2), 4); +%!function @var{a} = fn (@var{b}) +%! @var{a} = 2*@var{b}; +%!endfunction +%!assert (fn(2), 4); @end group @end example @@ -183,13 +203,13 @@ For example: @example - %!error <passes!> error('this test passes!'); +%!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."; +%!error "this is an error because it succeeds."; @end example @noindent @@ -197,23 +217,23 @@ @example @group - ***** error "this is an error because it succeeds."; - !!!!! test failed: no error + ***** 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 @code{demo} or @code{verbose}. The code is displayed before -it is executed. For example, +called with @code{demo} or the @code{verbose} option to @code{test}. +The code is displayed before it is executed. For example, @example @group - %!demo - %! @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 +%!demo +%! @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 @@ -222,10 +242,12 @@ @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: +funcname example 1: + @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 @@ -234,23 +256,29 @@ 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: +in the log file but not executed. For example: @example @group - %!#demo - %! @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 +%!#demo +%! @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: +@subsubheading Block type summary: @table @code @item %!test check that entire block is correct +@item %!testif HAVE_XXX +check block only if Octave was compiled with feature HAVE_XXX. + +@item %!xtest +check block, report a test failure but do not abort testing. + @item %!error check for correct error message @@ -277,15 +305,16 @@ @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: +functions. To do so put a file with the bare function name (no .m +extension) in a directory in the load path and it will be discovered by +the @code{test} function. Alternatively, you can embed tests directly in your +C++ code: @example @group - #if 0 - %!test disp('this is a test') - #endif +#if 0 +%!test disp ("this is a test") +#endif @end group @end example @@ -294,21 +323,16 @@ @example @group - /* - %!test disp('this is a test') - */ +/* +%!test disp ("this is a test") +*/ @end group @end example @noindent -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. -@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-*- +However, in this case the raw source code will need to be on the load +path and the user will have to remember to type +@code{test ("funcname.cc")}. @DOCSTRING(assert) @@ -319,10 +343,10 @@ @DOCSTRING(demo) +@DOCSTRING(example) + @DOCSTRING(rundemos) @DOCSTRING(runtests) -@DOCSTRING(example) - @DOCSTRING(speed)
--- a/m4/acinclude.m4 +++ b/m4/acinclude.m4 @@ -936,7 +936,28 @@ [AC_CACHE_CHECK([for qh_version in $QHULL_LIBS], octave_cv_lib_qhull_version, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include <qhull/qhull_a.h> +#include <stdio.h> +#if defined (HAVE_QHULL_LIBQHULL_H) || defined (HAVE_QHULL_QHULL_H) +# if defined (HAVE_QHULL_LIBQHULL_H) +# include <qhull/libqhull.h> +# else +# include <qhull/qhull.h> +# endif +# include <qhull/qset.h> +# include <qhull/geom.h> +# include <qhull/poly.h> +# include <qhull/io.h> +#elif defined (HAVE_LIBQHULL_H) || defined (HAVE_QHULL_H) +# if defined (HAVE_LIBQHULL_H) +# include <libqhull.h> +# else +# include <qhull.h> +# endif +# include <qset.h> +# include <geom.h> +# include <poly.h> +# include <io.h> +#endif ]], [[ const char *tmp = qh_version; ]])], [octave_cv_lib_qhull_version=yes], [octave_cv_lib_qhull_version=no])]) @@ -953,7 +974,27 @@ octave_cv_lib_qhull_ok, [ AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> -#include <qhull/qhull.h> +#if defined (HAVE_QHULL_LIBQHULL_H) || defined (HAVE_QHULL_QHULL_H) +# if defined (HAVE_QHULL_LIBQHULL_H) +# include <qhull/libqhull.h> +# else +# include <qhull/qhull.h> +# endif +# include <qhull/qset.h> +# include <qhull/geom.h> +# include <qhull/poly.h> +# include <qhull/io.h> +#elif defined (HAVE_LIBQHULL_H) || defined (HAVE_QHULL_H) +# if defined (HAVE_LIBQHULL_H) +# include <libqhull.h> +# else +# include <qhull.h> +# endif +# include <qset.h> +# include <geom.h> +# include <poly.h> +# include <io.h> +#endif #ifdef NEED_QHULL_VERSION char *qh_version = "version"; #endif
--- a/scripts/general/iscolumn.m +++ b/scripts/general/iscolumn.m @@ -35,26 +35,22 @@ endfunction -%!assert(iscolumn ([1, 2, 3]), false); -%!assert(iscolumn ([1; 2; 3])); -%!assert(iscolumn (1)); -%!assert(iscolumn ([]), false); -%!assert(iscolumn ([1, 2; 3, 4]), false); -%!test -%! warning ("off", "Octave:str-to-num"); -%! assert((iscolumn ("t"))); -%!test -%! warning ("off", "Octave:str-to-num"); -%! assert(!(iscolumn ("test"))); +%!assert (iscolumn ([1, 2, 3]), false) +%!assert (iscolumn ([1; 2; 3])) +%!assert (iscolumn (1)) +%!assert (iscolumn ([]), false) +%!assert (iscolumn ([1, 2; 3, 4]), false) -%!assert(!(iscolumn (["test"; "ing"]))); +%!assert (iscolumn ("t")) +%!assert (iscolumn ("test"), false) +%!assert (iscolumn (["test"; "ing"]), false) %!test %! s.a = 1; -%! assert((iscolumn (s))); +%! assert (iscolumn (s)); %% Test input validation -%!error iscolumn (); -%!error iscolumn ([1, 2], 2); +%!error iscolumn () +%!error iscolumn ([1, 2], 2)
--- a/scripts/general/isrow.m +++ b/scripts/general/isrow.m @@ -35,26 +35,22 @@ endfunction -%!assert(isrow ([1, 2, 3])); -%!assert(isrow ([1; 2; 3]), false); -%!assert(isrow (1)); -%!assert(isrow ([]), false); -%!assert(isrow ([1, 2; 3, 4]), false); -%!test -%! warning ("off", "Octave:str-to-num"); -%! assert((isrow ("t"))); -%!test -%! warning ("off", "Octave:str-to-num"); -%! assert((isrow ("test"))); +%!assert (isrow ([1, 2, 3])) +%!assert (isrow ([1; 2; 3]), false) +%!assert (isrow (1)) +%!assert (isrow ([]), false) +%!assert (isrow ([1, 2; 3, 4]), false) -%!assert(!(isrow (["test"; "ing"]))); +%!assert (isrow ("t")) +%!assert (isrow ("test")) +%!assert (isrow (["test"; "ing"]), false) %!test %! s.a = 1; -%! assert((isrow (s))); +%! assert (isrow (s)); %% Test input validation -%!error isrow (); -%!error isrow ([1, 2], 2); +%!error isrow () +%!error isrow ([1, 2], 2)
--- a/scripts/general/isscalar.m +++ b/scripts/general/isscalar.m @@ -34,23 +34,21 @@ endfunction -%!assert(isscalar (1)); -%!assert(!(isscalar ([1, 2]))); -%!assert(!(isscalar ([]))); -%!assert(!(isscalar ([1, 2; 3, 4]))); -%!test -%! warning ("off", "Octave:str-to-num"); -%! assert((isscalar ("t"))); +%!assert (isscalar (1)) +%!assert (isscalar ([1, 2]), false) +%!assert (isscalar ([]), false) +%!assert (isscalar ([1, 2; 3, 4]), false) -%!assert(!(isscalar ("test"))); -%!assert(!(isscalar (["test"; "ing"]))); +%!assert (isscalar ("t")) +%!assert (isscalar ("test"), false) +%!assert (isscalar (["test"; "ing"]), false) %!test %! s.a = 1; -%! assert((isscalar (s))); +%! assert (isscalar (s)); %% Test input validation -%!error isscalar (); -%!error isscalar (1, 2); +%!error isscalar () +%!error isscalar (1, 2)
--- a/scripts/general/isvector.m +++ b/scripts/general/isvector.m @@ -37,26 +37,21 @@ endfunction -%!assert(isvector (1)); -%!assert(isvector ([1; 2; 3])); -%!assert(!(isvector ([]))); -%!assert(!(isvector ([1, 2; 3, 4]))); -%!test -%! warning ("off", "Octave:str-to-num"); -%! assert((isvector ("t"))); +%!assert (isvector (1)) +%!assert (isvector ([1; 2; 3])) +%!assert (isvector ([]), false) +%!assert (isvector ([1, 2; 3, 4]), false) -%!test -%! warning ("off", "Octave:str-to-num"); -%! assert((isvector ("test"))); - -%!assert(!(isvector (["test"; "ing"]))); +%!assert (isvector ("t")) +%!assert (isvector ("test")) +%!assert (isvector (["test"; "ing"]), false) %!test %! s.a = 1; -%! assert((isvector (s))); +%! assert (isvector (s)); %% Test input validation -%!error isvector (); -%!error isvector ([1, 2], 2); +%!error isvector () +%!error isvector ([1, 2], 2)
--- a/scripts/general/polyarea.m +++ b/scripts/general/polyarea.m @@ -20,7 +20,7 @@ ## @deftypefn {Function File} {} polyarea (@var{x}, @var{y}) ## @deftypefnx {Function File} {} polyarea (@var{x}, @var{y}, @var{dim}) ## -## Determines area of a polygon by triangle method. The variables +## Determine area of a polygon by triangle method. The variables ## @var{x} and @var{y} define the vertex pairs, and must therefore have ## the same shape. They can be either vectors or arrays. If they are ## arrays then the columns of @var{x} and @var{y} are treated separately
--- a/scripts/miscellaneous/debug.m +++ b/scripts/miscellaneous/debug.m @@ -18,13 +18,12 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} debug () -## Summary of the debugging commands. The debugging commands that are -## available in Octave are +## Summary of debugging commands. For more information on each command +## and available options use @code{help CMD}. +## +## The debugging commands available in Octave are ## ## @table @code -## @item keyboard -## Force entry into debug mode. -## ## @item dbstop ## Add a breakpoint. ## @@ -34,51 +33,57 @@ ## @item dbstatus ## List all breakpoints. ## +## @item dbwhere +## Report the current file and line number where execution is stopped. +## +## @item dbtype +## List the function where execution is currently stopped, enumerating +## the line numbers. +## +## @item dbstep +## @itemx dbnext +## Execute one or more lines of code and re-enter debug mode. +## ## @item dbcont -## Continue execution from the debug prompt. +## Continue normal code execution from the debug prompt. +## +## @item dbquit +## Quit debugging mode immediately and return to the main prompt. ## ## @item dbstack ## Print a backtrace of the execution stack. ## -## @item dbstep -## Execute one or more lines and re-enter debug mode -## -## @item dbtype -## List the function where execution is currently stopped, enumerating -## the lines. -## ## @item dbup -## The workspace up the execution stack. +## Move up the execution stack. ## ## @item dbdown -## The workspace down the execution stack. +## Move down the execution stack. ## -## @item dbquit -## Quit debugging mode and return to the main prompt. +## @item keyboard +## Force entry into debug mode from an m-file. ## ## @item debug_on_error -## Function to query or set whether to enter debug mode in case Octave -## encounters an error. +## Configure whether Octave enters debug mode when it encounters an error. ## ## @item debug_on_warning -## Function to query or set whether to enter debug mode in case Octave -## encounters a warning. +## Configure whether Octave enters debug mode when it encounters a warning. ## ## @item debug_on_interrupt -## Function to query or set whether to enter debug mode in case Octave -## encounters an interupt. +## Configure whether Octave enters debug mode when it encounters an interrupt. ## +## @item isdebugmode +## Return true if in debug mode. ## @end table ## ## @noindent -## when Octave encounters a breakpoint or other reason to enter debug +## When Octave encounters a breakpoint, or other reason to enter debug ## mode, the prompt changes to @code{"debug>"}. The workspace of the function ## where the breakpoint was encountered becomes available and any Octave -## command that works within that workspace may be executed. +## command that is valid in that workspace context may be executed. ## -## @seealso{dbstop, dbclear, dbstatus, dbcont, dbstack, dbstep, dbtype, -## dbup, dbdown, dbquit, debug_on_error, debug_on_warning, -## debug_on_interrupt} +## @seealso{dbstop, dbclear, dbstatus, dbwhere, dbtype, dbcont, dbquit, +## dbstack, dbup, dbdown, keyboard, debug_on_error, debug_on_warning, +## debug_on_interrupt, isdebugmode} ## @end deftypefn function debug ()
--- a/scripts/plot/ezcontour.m +++ b/scripts/plot/ezcontour.m @@ -23,7 +23,7 @@ ## @deftypefnx {Function File} {} ezcontour (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezcontour (@dots{}) ## -## Plots the contour lines of a function. @var{f} is a string, inline function +## Plot the contour lines of a function. @var{f} is a string, inline function ## or function handle with two arguments defining the function. By default the ## plot is over the domain @code{-2*pi < @var{x} < 2*pi} and @code{-2*pi < ## @var{y} < 2*pi} with 60 points in each dimension.
--- a/scripts/plot/ezcontourf.m +++ b/scripts/plot/ezcontourf.m @@ -23,7 +23,7 @@ ## @deftypefnx {Function File} {} ezcontourf (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezcontourf (@dots{}) ## -## Plots the filled contour lines of a function. @var{f} is a string, inline +## Plot the filled contour lines of a function. @var{f} is a string, inline ## function or function handle with two arguments defining the function. By ## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and ## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension.
--- a/scripts/plot/ezmesh.m +++ b/scripts/plot/ezmesh.m @@ -25,7 +25,7 @@ ## @deftypefnx {Function File} {} ezmesh (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezmesh (@dots{}) ## -## Plots the mesh defined by a function. @var{f} is a string, inline +## Plot the mesh defined by a function. @var{f} is a string, inline ## function or function handle with two arguments defining the function. By ## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and ## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension.
--- a/scripts/plot/ezmeshc.m +++ b/scripts/plot/ezmeshc.m @@ -25,7 +25,7 @@ ## @deftypefnx {Function File} {} ezmeshc (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezmeshc (@dots{}) ## -## Plots the mesh and contour lines defined by a function. @var{f} is a string, +## Plot the mesh and contour lines defined by a function. @var{f} is a string, ## inline function or function handle with two arguments defining the function. ## By default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and ## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension.
--- a/scripts/plot/ezplot.m +++ b/scripts/plot/ezplot.m @@ -24,7 +24,7 @@ ## @deftypefnx {Function File} {} ezplot (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezplot (@dots{}) ## -## Plots in two-dimensions the curve defined by @var{f}. The function +## Plot the curve defined by @var{f} in two dimensions. The function ## @var{f} may be a string, inline function or function handle and can ## have either one or two variables. If @var{f} has one variable, then ## the function is plotted over the domain @code{-2*pi < @var{x} < 2*pi}
--- a/scripts/plot/ezplot3.m +++ b/scripts/plot/ezplot3.m @@ -23,7 +23,7 @@ ## @deftypefnx {Function File} {} ezplot3 (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezplot3 (@dots{}) ## -## Plots in three-dimensions the curve defined parametrically. +## Plot a parametrically defined curve in three dimensions. ## @var{fx}, @var{fy}, and @var{fz} are strings, inline functions ## or function handles with one arguments defining the function. By ## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi}
--- a/scripts/plot/ezpolar.m +++ b/scripts/plot/ezpolar.m @@ -23,7 +23,7 @@ ## @deftypefnx {Function File} {} ezpolar (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezpolar (@dots{}) ## -## Plots in polar plot defined by a function. The function @var{f} is either +## Plot a function in polar coordinates. The function @var{f} is either ## a string, inline function or function handle with one arguments defining ## the function. By default the plot is over the domain @code{0 < @var{x} < ## 2*pi} with 60 points.
--- a/scripts/plot/ezsurf.m +++ b/scripts/plot/ezsurf.m @@ -25,7 +25,7 @@ ## @deftypefnx {Function File} {} ezsurf (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezsurf (@dots{}) ## -## Plots the surface defined by a function. @var{f} is a string, inline +## Plot the surface defined by a function. @var{f} is a string, inline ## function or function handle with two arguments defining the function. By ## default the plot is over the domain @code{-2*pi < @var{x} < 2*pi} and ## @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension.
--- a/scripts/plot/ezsurfc.m +++ b/scripts/plot/ezsurfc.m @@ -25,7 +25,7 @@ ## @deftypefnx {Function File} {} ezsurfc (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} ezsurfc (@dots{}) ## -## Plots the surface and contour lines defined by a function. @var{f} is a +## Plot the surface and contour lines defined by a function. @var{f} is a ## string, inline function or function handle with two arguments defining the ## function. By default the plot is over the domain @code{-2*pi < @var{x} < ## 2*pi} and @code{-2*pi < @var{y} < 2*pi} with 60 points in each dimension.
--- a/scripts/plot/graphics_toolkit.m +++ b/scripts/plot/graphics_toolkit.m @@ -35,8 +35,11 @@ print_usage (); endif + if (nargout > 0 || nargin == 0) + retval = get (0, "defaultfigure__graphics_toolkit__"); + endif + if (nargin == 0) - retval = get (0, "defaultfigure__graphics_toolkit__"); return; elseif (nargin == 1) if (! ischar (name)) @@ -65,10 +68,6 @@ set (hlist, "__graphics_toolkit__", name); endif - if (isargout (1)) - retval = name; - endif - endfunction @@ -83,3 +82,14 @@ %! close (hf); %! end_unwind_protect +%!testif HAVE_FLTK +%! old_toolkit = graphics_toolkit (); +%! switch old_toolkit +%! case {"gnuplot"} +%! new_toolkit = "fltk"; +%! otherwise +%! new_toolkit = "gnuplot"; +%! endswitch +%! assert (graphics_toolkit (new_toolkit), old_toolkit) +%! assert (graphics_toolkit (old_toolkit), new_toolkit) +
--- a/scripts/plot/mesh.m +++ b/scripts/plot/mesh.m @@ -34,7 +34,7 @@ ## specified independent of @var{z}, by adding a fourth matrix, @var{c}. ## ## The optional return value @var{h} is a graphics handle to the created -## suface object. +## surface object. ## @seealso{colormap, contour, meshgrid, surf} ## @end deftypefn
--- a/scripts/sparse/svds.m +++ b/scripts/sparse/svds.m @@ -241,46 +241,56 @@ endfunction -%!shared n, k, A, u, s, v, opts +%!shared n, k, A, u, s, v, opts, rand_state, randn_state %! n = 100; %! k = 7; -%! A = sparse([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),0.4*n*ones(1,n),ones(1,n-2)]); -%! [u,s,v] = svd(full(A)); -%! s = diag(s); -%! [~, idx] = sort(abs(s)); +%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),0.4*n*ones(1,n),ones(1,n-2)]); +%! [u,s,v] = svd (full (A)); +%! s = diag (s); +%! [~, idx] = sort (abs(s)); %! s = s(idx); -%! u = u(:,idx); -%! v = v(:,idx); -%! old_state1 = randn ("state"); -%! restore_state1 = onCleanup (@() randn ("state", old_state1)); -%! old_state2 = rand ("state"); -%! restore_state2 = onCleanup (@() rand ("state", old_state2)); -%! randn ('state', 42); % Initialize to make normest function reproducible -%! rand ('state', 42); +%! u = u(:, idx); +%! v = v(:, idx); +%! randn_state = randn ("state"); +%! rand_state = rand ("state"); +%! randn ("state", 42); % Initialize to make normest function reproducible +%! rand ("state", 42); %! opts.v0 = rand (2*n,1); % Initialize eigs ARPACK starting vector %! % to guarantee reproducible results +%! %!test -%! [u2,s2,v2,flag] = svds(A,k); -%! s2 = diag(s2); -%! assert(flag,!1); -%! assert(s2, s(end:-1:end-k+1), 1e-10); +%! [u2,s2,v2,flag] = svds (A,k); +%! s2 = diag (s2); +%! assert (flag, !1); +%! assert (s2, s(end:-1:end-k+1), 1e-10); +%! %!testif HAVE_UMFPACK -%! [u2,s2,v2,flag] = svds(A,k,0,opts); -%! s2 = diag(s2); -%! assert(flag,!1); -%! assert(s2, s(k:-1:1), 1e-10); +%! [u2,s2,v2,flag] = svds (A,k,0,opts); +%! s2 = diag (s2); +%! assert (flag, !1); +%! assert (s2, s(k:-1:1), 1e-10); +%! %!testif HAVE_UMFPACK %! idx = floor(n/2); %! % Don't put sigma right on a singular value or there are convergence issues %! sigma = 0.99*s(idx) + 0.01*s(idx+1); -%! [u2,s2,v2,flag] = svds(A,k,sigma,opts); -%! s2 = diag(s2); -%! assert(flag,!1); -%! assert(s2, s((idx+floor(k/2)):-1:(idx-floor(k/2))), 1e-10); +%! [u2,s2,v2,flag] = svds (A,k,sigma,opts); +%! s2 = diag (s2); +%! assert (flag, !1); +%! assert (s2, s((idx+floor(k/2)):-1:(idx-floor(k/2))), 1e-10); +%! %!test -%! [u2,s2,v2,flag] = svds(zeros (10), k); -%! assert (isequal(u2, eye (10, k)) && isequal (s2, zeros(k)) && isequal (v2, eye(10, 7))); +%! [u2,s2,v2,flag] = svds (zeros (10), k); +%! assert (u2, eye (10, k)); +%! assert (s2, zeros (k)); +%! assert (v2, eye (10, 7)); +%! %!test %! s = svds (speye (10)); %! assert (s, ones (6, 1), 2*eps); +%!test +%! ## Restore random number generator seeds at end of tests +%! rand ("state", rand_state); +%! randn ("state", randn_state); +
--- a/scripts/testfun/assert.m +++ b/scripts/testfun/assert.m @@ -23,7 +23,7 @@ ## @deftypefnx {Function File} {} assert (@var{observed}, @var{expected}) ## @deftypefnx {Function File} {} assert (@var{observed}, @var{expected}, @var{tol}) ## -## Produces an error if the condition is not met. @code{assert} can be +## Produce an error if the condition is not met. @code{assert} can be ## called in three different ways. ## ## @table @code
--- a/scripts/testfun/example.m +++ b/scripts/testfun/example.m @@ -83,6 +83,7 @@ endfunction + %!## warning: don't modify the demos without modifying the tests! %!demo %! example ('example'); @@ -98,5 +99,6 @@ %! assert (idx, [1, 23, 63]); %% Test input validation -%!error example; -%!error example('example', 3, 5) +%!error example +%!error example ('example', 3, 5) +
--- a/src/DLD-FUNCTIONS/__delaunayn__.cc +++ b/src/DLD-FUNCTIONS/__delaunayn__.cc @@ -50,14 +50,11 @@ #include "error.h" #include "oct-obj.h" -#ifdef HAVE_QHULL -extern "C" { -#include <qhull/qhull_a.h> -} - -#ifdef NEED_QHULL_VERSION +#if defined (HAVE_QHULL) +# include "oct-qhull.h" +# if defined (NEED_QHULL_VERSION) char qh_version[] = "__delaunayn__.oct 2007-08-21"; -#endif +# endif #endif DEFUN_DLD (__delaunayn__, args, , @@ -70,7 +67,7 @@ { octave_value_list retval; -#ifdef HAVE_QHULL +#if defined (HAVE_QHULL) retval(0) = 0.0;
--- a/src/DLD-FUNCTIONS/__voronoi__.cc +++ b/src/DLD-FUNCTIONS/__voronoi__.cc @@ -45,14 +45,11 @@ #include "error.h" #include "oct-obj.h" -#ifdef HAVE_QHULL -extern "C" { -#include <qhull/qhull_a.h> -} - -#ifdef NEED_QHULL_VERSION +#if defined (HAVE_QHULL) +# include "oct-qhull.h" +# if defined (NEED_QHULL_VERSION) char qh_version[] = "__voronoi__.oct 2007-07-24"; -#endif +# endif #endif DEFUN_DLD (__voronoi__, args, , @@ -67,7 +64,7 @@ std::string caller = args(0).string_value (); -#ifdef HAVE_QHULL +#if defined (HAVE_QHULL) retval(0) = 0.0;
--- a/src/DLD-FUNCTIONS/amd.cc +++ b/src/DLD-FUNCTIONS/amd.cc @@ -55,7 +55,7 @@ @deftypefn {Loadable Function} {@var{p} =} amd (@var{S})\n\ @deftypefnx {Loadable Function} {@var{p} =} amd (@var{S}, @var{opts})\n\ \n\ -Returns the approximate minimum degree permutation of a matrix. This\n\ +Return the approximate minimum degree permutation of a matrix. This\n\ permutation such that the Cholesky@tie{}factorization of @code{@var{S}\n\ (@var{p}, @var{p})} tends to be sparser than the Cholesky@tie{}factorization\n\ of @var{S} itself. @code{amd} is typically faster than @code{symamd} but\n\
--- a/src/DLD-FUNCTIONS/chol.cc +++ b/src/DLD-FUNCTIONS/chol.cc @@ -129,8 +129,9 @@ \n\ @end ifnottex\n\ \n\ -For full matrices, if the 'lower' flag is set only the lower triangular part of the matrix \ -is used for the factorization, otherwise the upper triangular part is used.\n\ +For full matrices, if the 'lower' flag is set only the lower triangular part\n\ +of the matrix is used for the factorization, otherwise the upper triangular\n\ +part is used.\n\ \n\ In general the lower triangular factorization is significantly faster for\n\ sparse matrices.\n\
--- a/src/DLD-FUNCTIONS/colamd.cc +++ b/src/DLD-FUNCTIONS/colamd.cc @@ -647,7 +647,7 @@ @deftypefnx {Loadable Function} {@var{p} =} etree (@var{S}, @var{typ})\n\ @deftypefnx {Loadable Function} {[@var{p}, @var{q}] =} etree (@var{S}, @var{typ})\n\ \n\ -Returns the elimination tree for the matrix @var{S}. By default @var{S}\n\ +Return the elimination tree for the matrix @var{S}. By default @var{S}\n\ is assumed to be symmetric and the symmetric elimination tree is\n\ returned. The argument @var{typ} controls whether a symmetric or\n\ column elimination tree is returned. Valid values of @var{typ} are\n\
--- a/src/DLD-FUNCTIONS/config-module.awk +++ b/src/DLD-FUNCTIONS/config-module.awk @@ -7,7 +7,8 @@ print "EXTRA_DIST += \\" print " DLD-FUNCTIONS/config-module.sh \\" print " DLD-FUNCTIONS/config-module.awk \\" - print " DLD-FUNCTIONS/module-files" + print " DLD-FUNCTIONS/module-files \\" + print " DLD-FUNCTIONS/oct-qhull.h" print "" } /^#.*/ { next; }
--- a/src/DLD-FUNCTIONS/convhulln.cc +++ b/src/DLD-FUNCTIONS/convhulln.cc @@ -41,15 +41,12 @@ #include "oct-obj.h" #include "parse.h" -#ifdef HAVE_QHULL -extern "C" { -#include <qhull/qhull_a.h> -} - -# ifdef NEED_QHULL_VERSION +#if defined (HAVE_QHULL) +# include "oct-qhull.h" +# if defined (NEED_QHULL_VERSION) char qh_version[] = "convhulln.oct 2007-07-24"; # endif -#endif /* HAVE_QHULL */ +#endif DEFUN_DLD (convhulln, args, nargout, "-*- texinfo -*-\n\ @@ -85,7 +82,7 @@ { octave_value_list retval; -#ifdef HAVE_QHULL +#if defined (HAVE_QHULL) int nargin = args.length (); if (nargin < 1 || nargin > 2)
new file mode 100644 --- /dev/null +++ b/src/DLD-FUNCTIONS/oct-qhull.h @@ -0,0 +1,54 @@ +/* + +Copyright (C) 2011 John W. Eaton + +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 +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_oct_qhull_h) +#define octave_oct_qhull_h 1 + +#include <cstdio> + +extern "C" { + +#if defined (HAVE_QHULL_LIBQHULL_H) || defined (HAVE_QHULL_QHULL_H) +# if defined (HAVE_QHULL_LIBQHULL_H) +# include <qhull/libqhull.h> +# else +# include <qhull/qhull.h> +# endif +# include <qhull/qset.h> +# include <qhull/geom.h> +# include <qhull/poly.h> +# include <qhull/io.h> +#elif defined (HAVE_LIBQHULL_H) || defined (HAVE_QHULL_H) +# if defined (HAVE_LIBQHULL_H) +# include <libqhull.h> +# else +# include <qhull.h> +# endif +# include <qset.h> +# include <geom.h> +# include <poly.h> +# include <io.h> +#endif + +} + +#endif
--- a/src/DLD-FUNCTIONS/rand.cc +++ b/src/DLD-FUNCTIONS/rand.cc @@ -1024,9 +1024,9 @@ @deftypefnx {Loadable Function} {} randperm (@var{n}, @var{m})\n\ Return a row vector containing a random permutation of @code{1:@var{n}}.\n\ If @var{m} is supplied, return @var{m} unique entries, sampled without\n\ -replacement from @code{1:@var{n}}. The complexity is O(@var{n}) in\n\ +replacement from @code{1:@var{n}}. The complexity is O(@var{n}) in\n\ memory and O(@var{m}) in time, unless @var{m} < @var{n}/5, in which case\n\ -O(@var{m}) memory is used as well. The randomization is performed using\n\ +O(@var{m}) memory is used as well. The randomization is performed using\n\ rand(). All permutations are equally likely.\n\ @seealso{perms}\n\ @end deftypefn")
--- a/src/debug.cc +++ b/src/debug.cc @@ -308,7 +308,7 @@ } } else - error ("add_breakpoint: unable to find the function requested\n"); + error ("add_breakpoint: unable to find the requested function\n"); tree_evaluator::debug_mode = bp_table::have_breakpoints () || Vdebugging; @@ -363,7 +363,7 @@ } } else - error ("remove_breakpoint: unable to find the function requested\n"); + error ("remove_breakpoint: unable to find the requested function\n"); } tree_evaluator::debug_mode = bp_table::have_breakpoints () || Vdebugging; @@ -403,7 +403,7 @@ } else if (! silent) error ("remove_all_breakpoint_in_file: " - "unable to find the function requested\n"); + "unable to find the requested function\n"); tree_evaluator::debug_mode = bp_table::have_breakpoints () || Vdebugging; @@ -504,20 +504,31 @@ DEFUN (dbstop, args, , "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{rline} =} dbstop (@var{func}, @var{line}, @dots{})\n\ -Set a breakpoint in a function\n\ -@table @code\n\ +@deftypefn {Loadable Function} {@var{rline} =} dbstop (\"@var{func}\")\n\ +@deftypefnx {Loadable Function} {@var{rline} =} dbstop (\"@var{func}\", @var{line}, @dots{})\n\ +Set a breakpoint in function @var{func}.\n\ +\n\ +Arguments are\n\ +\n\ +@table @var\n\ @item func\n\ -String representing the function name. When already in debug\n\ +Function name as a string variable. When already in debug\n\ mode this should be left out and only the line should be given.\n\ \n\ @item line\n\ -Line number you would like the breakpoint to be set on. Multiple\n\ -lines might be given as separate arguments or as a vector.\n\ +Line number where the breakpoint should be set. Multiple\n\ +lines may be given as separate arguments or as a vector.\n\ @end table\n\ \n\ -The rline returned is the real line that the breakpoint was set at.\n\ -@seealso{dbclear, dbstatus, dbstep}\n\ +When called with a single argument @var{func}, the breakpoint\n\ +is set at the first executable line in the named function.\n\ +\n\ +The optional output @var{rline} is the real line number where the\n\ +breakpoint was set. This can differ from specified line if\n\ +the line is not executable. For example, if a breakpoint attempted on a\n\ +blank line then Octave will set the real breakpoint at the\n\ +next executable line.\n\ +@seealso{dbclear, dbstatus, dbstep, debug_on_error, debug_on_warning, debug_on_interrupt}\n\ @end deftypefn") { bp_table::intmap retval; @@ -537,19 +548,26 @@ DEFUN (dbclear, args, , "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} dbclear (@var{func}, @var{line}, @dots{})\n\ -Delete a breakpoint in a function\n\ -@table @code\n\ +@deftypefn {Loadable Function} {} dbclear (\"@var{func}\")\n\ +@deftypefnx {Loadable Function} {} dbclear (\"@var{func}\", @var{line}, @dots{})\n\ +Delete a breakpoint in the function @var{func}.\n\ +\n\ +Arguments are\n\ +\n\ +@table @var\n\ @item func\n\ -String representing the function name. When already in debug\n\ +Function name as a string variable. When already in debug\n\ mode this should be left out and only the line should be given.\n\ \n\ @item line\n\ -Line number where you would like to remove the breakpoint. Multiple\n\ -lines might be given as separate arguments or as a vector.\n\ +Line number from which to remove a breakpoint. Multiple\n\ +lines may be given as separate arguments or as a vector.\n\ @end table\n\ -No checking is done to make sure that the line you requested is really\n\ -a breakpoint. If you get the wrong line nothing will happen.\n\ +\n\ +When called without a line number specification all breakpoints\n\ +in the named function are cleared.\n\ +\n\ +If the requested line is not a breakpoint no action is performed.\n\ @seealso{dbstop, dbstatus, dbwhere}\n\ @end deftypefn") { @@ -567,14 +585,31 @@ DEFUN (dbstatus, args, nargout, "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {lst =} dbstatus (@var{func})\n\ -Return a vector containing the lines on which a function has\n\ -breakpoints set.\n\ -@table @code\n\ -@item func\n\ -String representing the function name. When already in debug\n\ -mode this should be left out.\n\ +@deftypefn {Loadable Function} {} dbstatus ()\n\ +@deftypefnx {Loadable Function} {@var{brk_list} =} dbstatus ()\n\ +@deftypefnx {Loadable Function} {@var{brk_list} =} dbstatus (\"@var{func}\")\n\ +Report the location of active breakpoints.\n\ +\n\ +When called with no input or output arguments, print the list of\n\ +all functions with breakpoints and the line numbers where those\n\ +breakpoints are set.\n\ +If a function name @var{func} is specified then only report breakpoints\n\ +for the named function.\n\ +\n\ +The optional return argument @var{brk_list} is a struct array with the\n\ +following fields.\n\ +\n\ +@table @asis\n\ +@item name\n\ +The name of the function with a breakpoint.\n\ +\n\ +@item file\n\ +The name of the m-file where the function code is located.\n\ +\n\ +@item line\n\ +A line number, or vector of line numbers, with a breakpoint.\n\ @end table\n\ +\n\ @seealso{dbclear, dbwhere}\n\ @end deftypefn") { @@ -586,7 +621,7 @@ if (nargin != 0 && nargin != 1) { - error ("dbstatus: only zero or one arguements accepted\n"); + error ("dbstatus: only zero or one arguments accepted\n"); return octave_value (); } @@ -663,8 +698,9 @@ DEFUN (dbwhere, , , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} dbwhere ()\n\ -Show where we are in the code\n\ -@seealso{dbclear, dbstatus, dbstop}\n\ +In debugging mode, report the current file and line number where\n\ +execution is stopped.\n\ +@seealso{dbstatus, dbcont, dbstep, dbup}\n\ @end deftypefn") { octave_value retval; @@ -704,7 +740,7 @@ octave_stdout << " <unknown line>" << std::endl; } else - error ("dbwhere: must be inside of a user function to use dbwhere\n"); + error ("dbwhere: must be inside a user function to use dbwhere\n"); return retval; } @@ -754,9 +790,17 @@ DEFUN (dbtype, args, , "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} dbtype ()\n\ -List script file with line numbers.\n\ -@seealso{dbclear, dbstatus, dbstop}\n\ +@deftypefn {Loadable Function} {} dbtype ()\n\ +@deftypefnx {Loadable Function} {} dbtype (\"startl:endl\")\n\ +@deftypefnx {Loadable Function} {} dbtype (\"@var{func}\")\n\ +@deftypefnx {Loadable Function} {} dbtype (\"@var{func}\", \"startl:endl\")\n\ +When in debugging mode and called with no arguments, list the script file\n\ +being debugged with line numbers. An optional range specification,\n\ +specified as a string, can be used to list only a portion of the file.\n\ +\n\ +When called with the name of a function, list that script file\n\ +with line numbers.\n\ +@seealso{dbstatus, dbstop}\n\ @end deftypefn") { octave_value retval; @@ -775,7 +819,7 @@ if (dbg_fcn) do_dbtype (octave_stdout, dbg_fcn->name (), 0, INT_MAX); else - error ("dbtype: must be in a user function to give no arguments to dbtype\n"); + error ("dbtype: must be inside a user function to give no arguments to dbtype\n"); break; case 1: // (dbtype func) || (dbtype start:end) @@ -887,7 +931,7 @@ if (n > 0) nskip = n; else - error ("dbstack: expecting N to be a nonnegative integer"); + error ("dbstack: N must be a non-negative integer"); } if (! error_state) @@ -960,10 +1004,38 @@ DEFUN (dbstack, args, nargout, "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {[@var{stack}, @var{idx}]} dbstack (@var{n})\n\ -Print or return current stack information. With optional argument\n\ -@var{n}, omit the @var{n} innermost stack frames.\n\ -@seealso{dbclear, dbstatus, dbstop}\n\ +@deftypefn {Loadable Function} {} dbstack ()\n\ +@deftypefnx {Loadable Function} {} dbstack (@var{n})\n\ +@deftypefnx {Loadable Function} {[@var{stack}, @var{idx}] =} dbstack (@dots{})\n\ +Display or return current debugging function stack information.\n\ +With optional argument @var{n}, omit the @var{n} innermost stack frames.\n\ +\n\ +The optional return argument @var{stack} is a struct array with the\n\ +following fields:\n\ +\n\ +@table @asis\n\ +@item file\n\ +The name of the m-file where the function code is located.\n\ +\n\ +@item name\n\ +The name of the function with a breakpoint.\n\ +\n\ +@item line\n\ +The line number of an active breakpoint.\n\ +\n\ +@item column\n\ +The column number of the line where the breakpoint begins.\n\ +\n\ +@item scope\n\ +Undocumented.\n\ +\n\ +@item context\n\ +Undocumented.\n\ +@end table\n\ +\n\ +The return argument @var{idx} specifies which element of the @var{stack}\n\ +struct array is currently active.\n\ +@seealso{dbup, dbdown, dbwhere, dbstatus}\n\ @end deftypefn") { return do_dbstack (args, nargout, octave_stdout); @@ -1004,7 +1076,7 @@ @deftypefnx {Loadable Function} {} dbup (@var{n})\n\ In debugging mode, move up the execution stack @var{n} frames.\n\ If @var{n} is omitted, move up one frame.\n\ -@seealso{dbstack}\n\ +@seealso{dbstack, dbdown}\n\ @end deftypefn") { octave_value retval; @@ -1020,7 +1092,7 @@ @deftypefnx {Loadable Function} {} dbdown (@var{n})\n\ In debugging mode, move down the execution stack @var{n} frames.\n\ If @var{n} is omitted, move down one frame.\n\ -@seealso{dbstack}\n\ +@seealso{dbstack, dbup}\n\ @end deftypefn") { octave_value retval; @@ -1036,14 +1108,17 @@ @deftypefnx {Command} {} dbstep @var{n}\n\ @deftypefnx {Command} {} dbstep in\n\ @deftypefnx {Command} {} dbstep out\n\ +@deftypefnx {Command} {} dbnext @dots{}\n\ In debugging mode, execute the next @var{n} lines of code.\n\ -If @var{n} is omitted , execute the next single line of code.\n\ -If the next line of code is itself\n\ -defined in terms of an m-file remain in the existing function.\n\ +If @var{n} is omitted, execute the next single line of code.\n\ +If the next line of code is itself defined in terms of an m-file remain in\n\ +the existing function.\n\ \n\ Using @code{dbstep in} will cause execution of the next line to step into\n\ any m-files defined on the next line. Using @code{dbstep out} will cause\n\ execution to continue until the current function returns.\n\ +\n\ +@code{dbnext} is an alias for @code{dbstep}.\n\ @seealso{dbcont, dbquit}\n\ @end deftypefn") { @@ -1089,7 +1164,7 @@ } } else - error ("dbstep: expecting character string as argument"); + error ("dbstep: input argument must be a character string"); } else { @@ -1109,7 +1184,7 @@ DEFUN (dbcont, args, , "-*- texinfo -*-\n\ @deftypefn {Command} {} dbcont\n\ -In debugging mode, quit debugging mode and continue execution.\n\ +Leave command-line debugging mode and continue code execution normally.\n\ @seealso{dbstep, dbquit}\n\ @end deftypefn") { @@ -1133,8 +1208,9 @@ DEFUN (dbquit, args, , "-*- texinfo -*-\n\ @deftypefn {Command} {} dbquit\n\ -In debugging mode, quit debugging mode and return to the top level.\n\ -@seealso{dbstep, dbcont}\n\ +Quit debugging mode immediately without further code execution and\n\ +return to the Octave prompt.\n\ +@seealso{dbcont, dbstep}\n\ @end deftypefn") { if (Vdebugging) @@ -1159,8 +1235,8 @@ DEFUN (isdebugmode, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} isdebugmode ()\n\ -Return true if debug mode is on, otherwise false.\n\ -@seealso{dbstack, dbclear, dbstop, dbstatus}\n\ +Return true if in debugging mode, otherwise false.\n\ +@seealso{dbwhere, dbstack, dbstatus}\n\ @end deftypefn") { octave_value retval;
--- a/src/error.cc +++ b/src/error.cc @@ -552,7 +552,8 @@ } // For given warning ID, return 0 if warnings are disabled, 1 if -// enabled, and 2 if this ID should be an error instead of a warning. +// enabled, and 2 if the given ID should be an error instead of a +// warning. int warning_enabled (const std::string& id) @@ -598,8 +599,9 @@ } } + // If "all" is not present, assume warnings are enabled. if (all_state == -1) - panic_impossible (); + all_state = 1; if (all_state == 0) {
--- a/src/load-save.cc +++ b/src/load-save.cc @@ -1565,7 +1565,7 @@ @noindent\n\ saves the variable @samp{a} and all variables beginning with @samp{b} to\n\ the file @file{data} in Octave's binary format.\n\ -@seealso{load, default_save_options, dlmread, csvread, fread}\n\ +@seealso{load, default_save_options, save_header_format_string, dlmread, csvread, fread}\n\ @end deftypefn") { octave_value_list retval;
--- a/src/ov-range.cc +++ b/src/ov-range.cc @@ -669,7 +669,7 @@ %! save = allow_noninteger_range_as_index (); %! warn_state = warning ("query", "Octave:noninteger-range-as-index"); %! unwind_protect -%! save = allow_noninteger_range_as_index (false); +%! allow_noninteger_range_as_index (false); %! fail ('x(2.1:5)'); %! assert (x(2:5), 1:4); %! allow_noninteger_range_as_index (true);
--- a/src/pager.cc +++ b/src/pager.cc @@ -321,7 +321,7 @@ octave_pager_stream::flush_current_contents_to_diary (void) { if (instance_ok ()) - instance->flush_current_contents_to_diary (); + instance->do_flush_current_contents_to_diary (); } void @@ -640,7 +640,7 @@ DEFUN (page_output_immediately, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} page_output_immediately ()\n\ -@deftypefnx {Built-in Function} {@var{val} =} page_output_immediately (@var{new_val})\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} page_output_immediately (@var{new_val})\n\ @deftypefnx {Built-in Function} {} page_output_immediately (@var{new_val}, \"local\")\n\ Query or set the internal variable that controls whether Octave sends\n\ output to the pager as soon as it is available. Otherwise, Octave\n\