Mercurial > hg > octave-lyh
changeset 17269:533c980b5796
maint: Merge away extra head.
author | Rik <rik@octave.org> |
---|---|
date | Thu, 15 Aug 2013 22:11:22 -0700 |
parents | a654c1eccd29 (diff) 92effb035b97 (current diff) |
children | 12e5fa85f1bb |
files | |
diffstat | 11 files changed, 324 insertions(+), 164 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/interpreter/mk_doc_cache.m +++ b/doc/interpreter/mk_doc_cache.m @@ -24,7 +24,7 @@ docstrings_files = args(2:end); ## Special character used as break between DOCSTRINGS -doc_delim = char (0x1e); +doc_delim = char (0x1d); ## Read the contents of all the DOCSTRINGS files into TEXT. ## It is more efficient to fork to shell for makeinfo only once on large data
--- a/doc/interpreter/munge-texi.pl +++ b/doc/interpreter/munge-texi.pl @@ -6,7 +6,7 @@ $top_srcdir = shift (@ARGV); # Constant patterns -$doc_delim = qr/^\x{1e}/; +$doc_delim = qr/^\x{1d}/; $tex_delim = qr/\Q-*- texinfo -*-\E/; $comment_line = qr/^\s*(?:$|#)/; # Pre-declare hash size for efficiency
--- a/doc/interpreter/stmt.txi +++ b/doc/interpreter/stmt.txi @@ -860,40 +860,46 @@ In the Octave language, most statements end with a newline character and you must tell Octave to ignore the newline character in order to continue a statement from one line to the next. Lines that end with the -characters @code{...} or @code{\} are joined with the following line -before they are divided into tokens by Octave's parser. For example, -the lines +characters @code{...} are joined with the following line before they are +divided into tokens by Octave's parser. For example, the lines @example @group x = long_variable_name ... - + longer_variable_name \ + + longer_variable_name ... - 42 @end group @end example @noindent -form a single statement. The backslash character on the second line -above is interpreted as a continuation character, @emph{not} as a division -operator. +form a single statement. -For continuation lines that do not occur inside string constants, -whitespace and comments may appear between the continuation marker and -the newline character. For example, the statement +Any text between the continuation marker and the newline character is +ignored. For example, the statement @example @group -x = long_variable_name ... # comment one - + longer_variable_name \ # comment two - - 42 # last comment +x = long_variable_name ... # comment one + + longer_variable_name ...comment two + - 42 # last comment @end group @end example @noindent -is equivalent to the one shown above. Inside string constants, the -continuation marker must appear at the end of the line just before the -newline character. +is equivalent to the one shown above. + +Inside double-quoted string constants, the character @code{\} has to be +used as continuation marker. The @code{\} must appear at the end of the +line just before the newline character: +@example +@group +s = "This text starts in the first line \ +and is continued in the second line." +@end group +@end example + +@noindent Input that occurs inside parentheses can be continued to the next line without having to use a continuation marker. For example, it is possible to write statements like
--- a/libinterp/corefcn/help.cc +++ b/libinterp/corefcn/help.cc @@ -967,7 +967,7 @@ if (file) { // Ignore header; - file.ignore (1000, 0x1e); + file.ignore (1000, 0x1d); if (file.gcount () == 1000) { @@ -988,7 +988,7 @@ while (! file.eof ()) { - file.getline (buf, bufsize, 0x1e); + file.getline (buf, bufsize, 0x1d); std::string tmp (buf);
--- a/libinterp/corefcn/rand.cc +++ b/libinterp/corefcn/rand.cc @@ -533,6 +533,19 @@ %! endif */ +/* +%!# Test out-of-range values as rand() seeds. See oct-rand.cc: double2uint32(). +%!function v = __rand_sample__ (initval) +%! rand ("state", initval); +%! v = rand (1, 6); +%!endfunction +%! +%!assert (__rand_sample__ (0), __rand_sample__ (2^32)) +%!assert (__rand_sample__ (-2), __rand_sample__ (2^32-2)) +%!assert (__rand_sample__ (Inf), __rand_sample__ (NaN)) +%!assert (! isequal (__rand_sample__ (-1), __rand_sample__ (-2))) +*/ + static std::string current_distribution = octave_rand::distribution (); DEFUN (randn, args, ,
--- a/libinterp/gendoc.pl +++ b/libinterp/gendoc.pl @@ -64,7 +64,7 @@ foreach $i (0 .. $#func_list) { $func = $func_list[$i]; - print "\x{1e}$func\n"; + print "\x{1d}$func\n"; print "\@c $func $src_fname\n"; print $docstr[$i],"\n"; }
--- a/liboctave/numeric/oct-rand.cc +++ b/liboctave/numeric/oct-rand.cc @@ -663,6 +663,30 @@ return retval; } +// Guarantee reproducible conversion of negative initialization values to +// random number algorithm. Note that Matlab employs slightly different rules. +// 1) Seed saturates at 2^32-1 for any value larger than that. +// 2) NaN, Inf are translated to 2^32-1. +// 3) -Inf is translated to 0. +static uint32_t +double2uint32 (double d) +{ + uint32_t u; + static const double TWOUP32 = std::numeric_limits<uint32_t>::max() + 1.0; + + if (! xfinite (d)) + u = 0; + else + { + d = fmod (d, TWOUP32); + if (d < 0) + d += TWOUP32; + u = static_cast<uint32_t> (d); + } + + return u; +} + void octave_rand::set_internal_state (const ColumnVector& s) { @@ -672,7 +696,7 @@ OCTAVE_LOCAL_BUFFER (uint32_t, tmp, MT_N + 1); for (octave_idx_type i = 0; i < n; i++) - tmp[i] = static_cast<uint32_t> (s.elem (i)); + tmp[i] = double2uint32 (s.elem (i)); if (len == MT_N + 1 && tmp[MT_N] <= MT_N && tmp[MT_N] > 0) oct_set_state (tmp);
--- a/scripts/mkdoc.pl +++ b/scripts/mkdoc.pl @@ -52,7 +52,7 @@ @help_txt = gethelp ($fcn, $full_fname); next MFILE if ($help_txt[0] eq ""); - print "\x{1e}$fcn\n"; + print "\x{1d}$fcn\n"; print "\@c $fcn scripts/$m_fname\n"; foreach $_ (@help_txt)
--- a/scripts/plot/contour.m +++ b/scripts/plot/contour.m @@ -91,7 +91,7 @@ %! [x, y, z] = peaks (); %! contour (x, y, z); %! title ('contour() plot of peaks() function'); -%! title ({'contour() plot (isolines of constant Z)'; 'Z = peaks()'); +%! title ({'contour() plot (isolines of constant Z)'; 'Z = peaks()'}); %!demo %! clf; @@ -100,7 +100,7 @@ %! [X, Y] = pol2cart (theta, r); %! Z = sin (2*theta) .* (1-r); %! contour (X, Y, abs (Z), 10); -%! title ({'contour() plot'; 'polar fcn Z = sin (2*theta) * (1-r)'}); +%! title ({'contour() plot'; 'polar fcn: Z = sin (2*theta) * (1-r)'}); %!test %! hf = figure ("visible", "off");
--- a/scripts/plot/contourf.m +++ b/scripts/plot/contourf.m @@ -92,7 +92,7 @@ %! colormap ('default'); %! [x, y, z] = peaks (50); %! contourf (x, y, z, -7:9); -%! title ({'contourf() plot (filled contour lines)'; 'Z = peaks()'); +%! title ({'contourf() plot (filled contour lines)'; 'Z = peaks()'}); %!demo %! clf; @@ -101,7 +101,7 @@ %! [X, Y] = pol2cart (theta, r); %! Z = sin (2*theta) .* (1-r); %! contourf (X, Y, abs (Z), 10); -%! title ({'contourf() plot'; 'polar fcn Z = sin (2*theta) * (1-r)'}); +%! title ({'contourf() plot'; 'polar fcn: Z = sin (2*theta) * (1-r)'}); %!demo %! clf;
--- a/scripts/testfun/assert.m +++ b/scripts/testfun/assert.m @@ -77,6 +77,7 @@ if (nargin == 1 || (nargin > 1 && islogical (cond) && ischar (varargin{1}))) if ((! isnumeric (cond) && ! islogical (cond)) || ! all (cond(:))) + call_depth--; if (nargin == 1) ## Perhaps, say which elements failed? error ("assert %s failed", in); @@ -100,18 +101,15 @@ if (ischar (expected)) if (! ischar (cond)) - err.index{end+1} = "[]"; + err.index{end+1} = "."; err.expected{end+1} = expected; if (isnumeric (cond)) err.observed{end+1} = num2str (cond); err.reason{end+1} = "Expected string, but observed number"; - elseif (iscell (cond)) - err.observed{end+1} = "{}"; - err.reason{end+1} = "Expected string, but observed cell"; else - err.observed{end+1} = "[]"; - err.reason{end+1} = "Expected string, but observed struct"; - end + err.observed{end+1} = "O"; + err.reason{end+1} = ["Expected string, but observed " class(cond)]; + endif elseif (! strcmp (cond, expected)) err.index{end+1} = "[]"; err.observed{end+1} = cond; @@ -120,11 +118,17 @@ endif elseif (iscell (expected)) - if (! iscell (cond) || any (size (cond) != size (expected))) - err.index{end+1} = "{}"; + if (! iscell (cond)) + err.index{end+1} = "."; err.observed{end+1} = "O"; err.expected{end+1} = "E"; - err.reason{end+1} = "Cell sizes don't match"; + err.reason{end+1} = ["Expected cell, but observed " class(cond)]; + elseif (ndims (cond) != ndims (expected) + || any (size (cond) != size (expected))) + err.index{end+1} = "."; + err.observed{end+1} = ["O(" sprintf("%dx", size(cond))(1:end-1) ")"]; + err.expected{end+1} = ["E(" sprintf("%dx", size(expected))(1:end-1) ")"]; + err.reason{end+1} = "Dimensions don't match"; else try ## Recursively compare cell arrays @@ -140,11 +144,18 @@ endif elseif (isstruct (expected)) - if (! isstruct (cond) || any (size (cond) != size (expected)) - || rows (fieldnames (cond)) != rows (fieldnames (expected))) - err.index{end+1} = "{}"; + if (! isstruct (cond)) + err.index{end+1} = "."; err.observed{end+1} = "O"; err.expected{end+1} = "E"; + err.reason{end+1} = ["Expected struct, but observed " class(cond)]; + elseif (ndims (cond) != ndims (expected) + || any (size (cond) != size (expected)) + || rows (fieldnames (cond)) != rows (fieldnames (expected))) + + err.index{end+1} = "."; + err.observed{end+1} = ["O(" sprintf("%dx", size(cond))(1:end-1) ")"]; + err.expected{end+1} = ["E(" sprintf("%dx", size(expected))(1:end-1) ")"]; err.reason{end+1} = "Structure sizes don't match"; else try @@ -219,57 +230,63 @@ B = expected; ## Check exceptional values. - erridx = find ( isna (real (A)) != isna (real (B)) - | isna (imag (A)) != isna (imag (B))); + errvec = ( isna (real (A)) != isna (real (B)) + | isna (imag (A)) != isna (imag (B))); + erridx = find (errvec); if (! isempty (erridx)) - err.index(end+1:end + length (erridx)) = ... - ind2tuple (size (A), erridx); - err.observed(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (A(erridx) (:)))); - err.expected(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (B(erridx) (:)))); - err.reason(end+1:end + length (erridx)) = ... - cellstr (repmat ("'NA' mismatch", length (erridx), 1)); + err.index(end+1:end+length (erridx)) = ... + ind2tuple (size (A), erridx); + err.observed(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (A(erridx) (:)))); + err.expected(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (B(erridx) (:)))); + err.reason(end+1:end+length (erridx)) = ... + repmat ({"'NA' mismatch"}, length (erridx), 1); endif + errseen = errvec; - erridx = find ( isnan (real (A)) != isnan (real (B)) - | isnan (imag (A)) != isnan (imag (B))); + errvec = ( isnan (real (A)) != isnan (real (B)) + | isnan (imag (A)) != isnan (imag (B))); + erridx = find (errvec & !errseen); if (! isempty (erridx)) - err.index(end+1:end + length (erridx)) = ... - ind2tuple (size (A), erridx); - err.observed(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (A(erridx) (:)))); - err.expected(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (B(erridx) (:)))); - err.reason(end+1:end + length (erridx)) = ... - cellstr (repmat ("'NaN' mismatch", length (erridx), 1)); + err.index(end+1:end+length (erridx)) = ... + ind2tuple (size (A), erridx); + err.observed(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (A(erridx) (:)))); + err.expected(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (B(erridx) (:)))); + err.reason(end+1:end+length (erridx)) = ... + repmat ({"'NaN' mismatch"}, length (erridx), 1); endif + errseen |= errvec; - erridx = find (((isinf (real (A)) | isinf (real (B))) ... - & real (A) != real (B)) ... - | ((isinf (imag (A)) | isinf (imag (B))) - & imag (A) != imag (B))); + errvec = ((isinf (real (A)) | isinf (real (B))) ... + & (real (A) != real (B))) ... + | ((isinf (imag (A)) | isinf (imag (B))) ... + & (imag (A) != imag (B))); + erridx = find (errvec & !errseen); if (! isempty (erridx)) - err.index(end+1:end + length (erridx)) = ... - ind2tuple (size (A), erridx); - err.observed(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (A(erridx) (:)))); - err.expected(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (B(erridx) (:)))); - err.reason(end+1:end + length (erridx)) = ... - cellstr (repmat ("'Inf' mismatch", length (erridx), 1)); + err.index(end+1:end+length (erridx)) = ... + ind2tuple (size (A), erridx); + err.observed(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (A(erridx) (:)))); + err.expected(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (B(erridx) (:)))); + err.reason(end+1:end+length (erridx)) = ... + repmat ({"'Inf' mismatch"}, length (erridx), 1); endif + errseen |= errvec; ## Check normal values. ## Replace exceptional values already checked above by zero. A_null_real = real (A); B_null_real = real (B); - exclude = ! isfinite (A_null_real) & ! isfinite (B_null_real); + exclude = errseen | ! isfinite (A_null_real) & ! isfinite (B_null_real); A_null_real(exclude) = 0; B_null_real(exclude) = 0; A_null_imag = imag (A); B_null_imag = imag (B); - exclude = ! isfinite (A_null_imag) & ! isfinite (B_null_imag); + exclude = errseen | ! isfinite (A_null_imag) & ! isfinite (B_null_imag); A_null_imag(exclude) = 0; B_null_imag(exclude) = 0; A_null = complex (A_null_real, A_null_imag); @@ -283,45 +300,45 @@ k = (mtol == 0); erridx = find ((A_null != B_null) & k); if (! isempty (erridx)) - err.index(end+1:end + length (erridx)) = ... - ind2tuple (size (A), erridx); - err.observed(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (A(erridx) (:)))); - err.expected(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (B(erridx) (:)))); - err.reason(end+1:end + length (erridx)) = ... - ostrsplit (deblank (sprintf ("Abs err %g exceeds tol %g\n", ... - [abs(A_null(erridx) - B_null(erridx)) mtol(erridx)]')), "\n"); + err.index(end+1:end+length (erridx)) = ... + ind2tuple (size (A), erridx); + err.observed(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (A(erridx) (:)))); + err.expected(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (B(erridx) (:)))); + err.reason(end+1:end+length (erridx)) = ... + ostrsplit (deblank (sprintf ("Abs err %.5g exceeds tol %.5g\n",... + [abs(A_null(erridx) - B_null(erridx))(:) mtol(erridx)(:)]')), "\n"); endif k = (mtol > 0); erridx = find ((abs (A_null - B_null) > mtol) & k); if (! isempty (erridx)) - err.index(end+1:end + length (erridx)) = ... - ind2tuple (size (A), erridx); - err.observed(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (A(erridx) (:)))); - err.expected(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (B(erridx) (:)))); - err.reason(end+1:end + length (erridx)) = ... - ostrsplit (deblank (sprintf ("Abs err %g exceeds tol %g\n", ... - [abs(A_null(erridx) - B_null(erridx)) mtol(erridx)]')), "\n"); + err.index(end+1:end+length (erridx)) = ... + ind2tuple (size (A), erridx); + err.observed(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (A(erridx) (:)))); + err.expected(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (B(erridx) (:)))); + err.reason(end+1:end+length (erridx)) = ... + ostrsplit (deblank (sprintf ("Abs err %.5g exceeds tol %.5g\n",... + [abs(A_null(erridx) - B_null(erridx))(:) mtol(erridx)(:)]')), "\n"); endif k = (mtol < 0); - if (any (k)) + if (any (k(:))) ## Test for absolute error where relative error can't be calculated. erridx = find ((B_null == 0) & abs (A_null) > abs (mtol) & k); if (! isempty (erridx)) - err.index(end+1:end + length (erridx)) = ... - ind2tuple (size (A), erridx); - err.observed(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (A(erridx) (:)))); - err.expected(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (B(erridx) (:)))); - err.reason(end+1:end + length (erridx)) = ... - ostrsplit (deblank (sprintf ("Abs err %g exceeds tol %g\n", - [abs(A_null(erridx) - B_null(erridx)) -mtol(erridx)]')), "\n"); + err.index(end+1:end+length (erridx)) = ... + ind2tuple (size (A), erridx); + err.observed(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (A(erridx) (:)))); + err.expected(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (B(erridx) (:)))); + err.reason(end+1:end+length (erridx)) = ... + ostrsplit (deblank (sprintf ("Abs err %.5g exceeds tol %.5g\n", + [abs(A_null(erridx) - B_null(erridx)) -mtol(erridx)]')), "\n"); endif ## Test for relative error Bdiv = Inf (size (B_null)); @@ -329,15 +346,15 @@ relerr = abs ((A_null - B_null) ./ abs (Bdiv)); erridx = find ((relerr > abs (mtol)) & k); if (! isempty (erridx)) - err.index(end+1:end + length (erridx)) = ... - ind2tuple (size (A), erridx); - err.observed(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (A(erridx) (:)))); - err.expected(end+1:end + length (erridx)) = ... - strtrim (cellstr (num2str (B(erridx) (:)))); - err.reason(end+1:end + length (erridx)) = ... - ostrsplit (deblank (sprintf ("Rel err %g exceeds tol %g\n", - [relerr(erridx) -mtol(erridx)]')), "\n"); + err.index(end+1:end+length (erridx)) = ... + ind2tuple (size (A), erridx); + err.observed(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (A(erridx) (:)))); + err.expected(end+1:end+length (erridx)) = ... + strtrim (cellstr (num2str (B(erridx) (:)))); + err.reason(end+1:end+length (erridx)) = ... + ostrsplit (deblank (sprintf ("Rel err %.5g exceeds tol %.5g\n", + [relerr(erridx)(:) -mtol(erridx)(:)]')), "\n"); endif endif endif @@ -369,8 +386,8 @@ ## empty input %!assert ([]) %!assert (zeros (3,0), zeros (3,0)) -%!error assert (zeros (3,0), zeros (0,2)) -%!error assert (zeros (3,0), []) +%!error <O\(3x0\)\s+E\(0x2\)> assert (zeros (3,0), zeros (0,2)) +%!error <Dimensions don't match> assert (zeros (3,0), []) %!error <Dimensions don't match> assert (zeros (2,0,2), zeros (2,0)) ## conditions @@ -385,85 +402,135 @@ %!error assert ([1,0;1,1]) ## scalars -%!error assert (3, [3,3; 3,3]) -%!error assert ([3,3; 3,3], 3) +%!error <Dimensions don't match> assert (3, [3,3]) +%!error <Dimensions don't match> assert (3, [3,3; 3,3]) +%!error <Dimensions don't match> assert ([3,3; 3,3], 3) %!assert (3, 3) +%!error <Abs err 1 exceeds tol> assert (3, 4) %!assert (3+eps, 3, eps) %!assert (3, 3+eps, eps) -%!error assert (3+2*eps, 3, eps) -%!error assert (3, 3+2*eps, eps) +%!error <Abs err 4.4409e-16 exceeds tol> assert (3+2*eps, 3, eps) +%!error <Abs err 4.4409e-16 exceeds tol> assert (3, 3+2*eps, eps) ## vectors %!assert ([1,2,3],[1,2,3]); %!assert ([1;2;3],[1;2;3]); -%!error assert ([2,2,3,3],[1,2,3,4]); -%!error assert ([6;6;7;7],[5;6;7;8]); -%!error assert ([1,2,3],[1;2;3]); -%!error assert ([1,2],[1,2,3]); -%!error assert ([1;2;3],[1;2]); -%!assert ([1,2;3,4],[1,2;3,4]); -%!error assert ([1,4;3,4],[1,2;3,4]) -%!error assert ([1,3;2,4;3,5],[1,2;3,4]) +%!error <Abs err 1 exceeds tol 0> assert ([2,2,3,3],[1,2,3,4]); +%!error <Abs err 1 exceeds tol 0.5> assert ([2,2,3,3],[1,2,3,4],0.5); +%!error <Rel err 1 exceeds tol 0.1> assert ([2,2,3,5],[1,2,3,4],-0.1); +%!error <Abs err 1 exceeds tol 0> assert ([6;6;7;7],[5;6;7;8]); +%!error <Abs err 1 exceeds tol 0.5> assert ([6;6;7;7],[5;6;7;8],0.5); +%!error <Rel err .* exceeds tol 0.1> assert ([6;6;7;7],[5;6;7;8],-0.1); +%!error <Dimensions don't match> assert ([1,2,3],[1;2;3]); +%!error <Dimensions don't match> assert ([1,2],[1,2,3]); +%!error <Dimensions don't match> assert ([1;2;3],[1;2]); ## matrices -%!test +%!assert ([1,2;3,4],[1,2;3,4]); +%!error <\(1,2\)\s+4\s+2> assert ([1,4;3,4],[1,2;3,4]) +%!error <Dimensions don't match> assert ([1,3;2,4;3,5],[1,2;3,4]) +%!test # 2-D matrix %! A = [1 2 3]'*[1,2]; -%! assert (A,A); +%! assert (A, A); %! fail ("assert (A.*(A!=2),A)"); +%!test # N-D matrix %! X = zeros (2,2,3); %! Y = X; -%! Y (1,2,3) = 1; -%! fail ("assert (X,Y)"); +%! Y(1,2,3) = 1.5; +%! fail ("assert (X,Y)", "\(1,2,3\).*Abs err 1.5 exceeds tol 0"); ## must give a small tolerance for floating point errors on relative %!assert (100+100*eps, 100, -2*eps) %!assert (100, 100+100*eps, -2*eps) -%!error assert (100+300*eps, 100, -2*eps) -%!error assert (100, 100+300*eps, -2*eps) -%!error assert (3, [3,3]) -%!error assert (3, 4) +%!error <Rel err .* exceeds tol> assert (100+300*eps, 100, -2*eps) +%!error <Rel err .* exceeds tol> assert (100, 100+300*eps, -2*eps) ## test relative vs. absolute tolerances -%!test assert (0.1+eps, 0.1, 2*eps); # accept absolute -%!error assert (0.1+eps, 0.1, -2*eps); # fail relative -%!test assert (100+100*eps, 100, -2*eps); # accept relative -%!error assert (100+100*eps, 100, 2*eps); # fail absolute +%!test assert (0.1+eps, 0.1, 2*eps); +%!error <Rel err 2.2204e-15 exceeds tol> assert (0.1+eps, 0.1, -2*eps); +%!test assert (100+100*eps, 100, -2*eps); +%!error <Abs err 2.8422e-14 exceeds tol> assert (100+100*eps, 100, 2*eps); + +## Corner case of relative tolerance with 0 divider +%!error <Abs err 2 exceeds tol 0.1> assert (2, 0, -0.1) + +## Extra checking of inputs when tolerance unspecified. +%!error <Class single != double> assert (single (1), 1) +%!error <Class uint8 != uint16> assert (uint8 (1), uint16 (1)) +%!error <sparse != non-sparse> assert (sparse([1]), [1]) +%!error <non-sparse != sparse> assert ([1], sparse([1])) +%!error <complex != real> assert (1+i, 1) +%!error <real != complex> assert (1, 1+i) ## exceptional values %!assert ([NaN, NA, Inf, -Inf, 1+eps, eps], [NaN, NA, Inf, -Inf, 1, 0], eps) -%!error assert (NaN, 1) -%!error assert ([NaN 1], [1 NaN]) -%!error assert (NA, 1) + +%!error <'NaN' mismatch> assert (NaN, 1) +%!error <'NaN' mismatch> assert ([NaN 1], [1 NaN]) +%!test +%! try +%! assert ([NaN 1], [1 NaN]); +%! catch +%! errmsg = lasterr (); +%! if (sum (errmsg () == "\n") != 4) +%! error ("Too many errors reported for NaN assert"); +%! elseif (strfind (errmsg, "NA")) +%! error ("NA reported for NaN assert"); +%! elseif (strfind (errmsg, "Abs err NaN exceeds tol 0")) +%! error ("Abs err reported for NaN assert"); +%! endif +%! end_try_catch + +%!error <'NA' mismatch> assert (NA, 1) %!error assert ([NA 1]', [1 NA]') +%!test +%! try +%! assert ([NA 1]', [1 NA]'); +%! catch +%! errmsg = lasterr (); +%! if (sum (errmsg () == "\n") != 4) +%! error ("Too many errors reported for NA assert"); +%! elseif (strfind (errmsg, "NaN")) +%! error ("NaN reported for NA assert"); +%! elseif (strfind (errmsg, "Abs err NA exceeds tol 0")) +%! error ("Abs err reported for NA assert"); +%! endif +%! end_try_catch %!error assert ([(complex (NA, 1)) (complex (2, NA))], [(complex (NA, 2)) 2]) -%!error assert (-Inf, Inf) -%!error assert ([-Inf Inf], [Inf -Inf]) -%!error assert (complex (Inf, 0.2), complex (-Inf, 0.2 + 2*eps), eps) + +%!error <'Inf' mismatch> assert (-Inf, Inf) +%!error <'Inf' mismatch> assert ([-Inf Inf], [Inf -Inf]) +%!test +%! try +%! assert (complex (Inf, 0.2), complex (-Inf, 0.2 + 2*eps), eps); +%! catch +%! errmsg = lasterr (); +%! if (sum (errmsg () == "\n") != 3) +%! error ("Too many errors reported for Inf assert"); +%! elseif (strfind (errmsg, "Abs err")) +%! error ("Abs err reported for Inf assert"); +%! endif +%! end_try_catch +%!error <Abs err> assert (complex (Inf, 0.2), complex (Inf, 0.2 + 2*eps), eps) ## strings %!assert ("dog", "dog") -%!error assert ("dog", "cat") -%!error assert ("dog", 3) -%!error assert (3, "dog") -%!error assert (cellstr ("dog"), "dog") -%!error assert (cell2struct ({"dog"; 3}, {"pet", "age"}, 1), "dog"); - -## structures -%!shared x,y -%! x.a = 1; x.b=[2, 2]; -%! y.a = 1; y.b=[2, 2]; -%!assert (x, y) -%!test y.b=3; -%!error assert (x, y) -%!error assert (3, x) -%!error assert (x, 3) -%!test -%! # Empty structures -%! x = resize (x, 0, 1); -%! y = resize (y, 0, 1); -%! assert (x, y); +%!error <Strings don't match> assert ("dog", "cat") +%!error <Expected string, but observed number> assert (3, "dog") +%!error <Class char != double> assert ("dog", [3 3 3]) +%!error <Expected string, but observed cell> assert ({"dog"}, "dog") +%!error <Expected string, but observed struct> assert (struct ("dog", 3), "dog") ## cell arrays +%!error <Expected cell, but observed double> assert (1, {1}) +%!error <Dimensions don't match> assert (cell (1,2,3), cell (3,2,1)) +%!test +%! x = {{{1}}, 2}; # cell with multiple levels +%! y = x; +%! assert (x,y); +%! y{1}{1}{1} = 3; +%! fail ("assert (x,y)", "Abs err 2 exceeds tol 0"); + %!test %! x = {[3], [1,2,3]; 100+100*eps, "dog"}; %! y = x; @@ -479,7 +546,39 @@ %! y = x; y(1,1) = [2]; y(1,2) = [0, 2, 3]; y(2,1) = 101; y(2,2) = "cat"; %! fail ("assert (x, y)"); -## variable tolerance +## structures +%!error <Expected struct, but observed double> assert (1, struct ("a", 1)) +%!error <Structure sizes don't match> +%! x(1,2,3).a = 1; +%! y(1,2).a = 1; +%! assert (x,y); +%!error <Structure sizes don't match> +%! x(1,2,3).a = 1; +%! y(3,2,2).a = 1; +%! assert (x,y); +%!error <Structure sizes don't match> +%! x.a = 1; x.b = 1; +%! y.a = 1; +%! assert (x,y); +%!error <'b' is not an expected field> +%! x.b = 1; +%! y.a = 1; +%! assert (x,y); + +%!test +%! x.a = 1; x.b=[2, 2]; +%! y.a = 1; y.b=[2, 2]; +%! assert (x, y); +%! y.b=3; +%! fail ("assert (x, y)"); +%! fail ("assert (3, x)"); +%! fail ("assert (x, 3)"); +%! ## Empty structures +%! x = resize (x, 0, 1); +%! y = resize (y, 0, 1); +%! assert (x, y); + +## vector of tolerances %!test %! x = [-40:0]; %! y1 = (10.^x).*(10.^x); @@ -487,6 +586,24 @@ %! assert (y1, y2, eps (y1)); %! fail ("assert (y1, y2 + eps*1e-70, eps (y1))"); +## Multiple tolerances +%!test +%! x = [1 2; 3 4]; +%! y = [0 -1; 1 2]; +%! tol = [-0.1 0; -0.2 0.3]; +%! try +%! assert (x, y, tol); +%! catch +%! errmsg = lasterr (); +%! if (sum (errmsg () == "\n") != 6) +%! error ("Incorrect number of errors reported"); +%! endif +%! assert (!isempty (regexp (errmsg, '\(1,2\).*Abs err 3 exceeds tol 0\>'))); +%! assert (!isempty (regexp (errmsg, '\(2,2\).*Abs err 2 exceeds tol 0.3'))); +%! assert (!isempty (regexp (errmsg, '\(1,1\).*Abs err 1 exceeds tol 0.1'))); +%! assert (!isempty (regexp (errmsg, '\(2,1\).*Rel err 2 exceeds tol 0.2'))); +%! end_try_catch + ## test input validation %!error assert () %!error assert (1,2,3,4)