Mercurial > octave
changeset 33280:c2ab6aba3cdb
maint: Merge stable to default.
author | Nicholas R. Jankowski <jankowski.nicholas@gmail.com> |
---|---|
date | Mon, 01 Apr 2024 10:14:27 -0400 |
parents | 1aa384331bd2 (current diff) 308060bc6b27 (diff) |
children | 92f34eda5c6e f9e4e87a0f4a |
files | |
diffstat | 2 files changed, 72 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/NEWS.9.md Sun Mar 31 15:57:02 2024 +0200 +++ b/etc/NEWS.9.md Mon Apr 01 10:14:27 2024 -0400 @@ -8,6 +8,9 @@ - `hist.m`: Add input validation for `Y` restricting it to 2-D array (bug #65478). +- `cross.m`: Add input validation for 'dim' restricting it to a numeric + integer valued scalar. + ### GUI - Use first word for options in right-click menu of command window widget
--- a/scripts/linear-algebra/cross.m Sun Mar 31 15:57:02 2024 +0200 +++ b/scripts/linear-algebra/cross.m Mon Apr 01 10:14:27 2024 -0400 @@ -29,11 +29,12 @@ ## Compute the vector cross product of two 3-dimensional vectors @var{x} and ## @var{y}. ## -## If @var{x} and @var{y} are matrices, the cross product is applied along the +## If @var{x} and @var{y} are arrays, the cross product is applied along the ## first dimension with three elements. ## ## The optional argument @var{dim} forces the cross product to be calculated -## along the specified dimension. +## along the specified dimension. An error will be produced if the specified +## dimension is not three elements in size. ## ## Example Code: ## @@ -41,7 +42,17 @@ ## @group ## cross ([1, 1, 0], [0, 1, 1]) ## @result{} -## 1 -1 1 +## 1 -1 1 +## @end group +## @end example +## +## @example +## @group +## cross (magic (3), eye (3), 2) +## @result{} +## 0 6 -1 +## -7 0 3 +## 9 -4 0 ## @end group ## @end example ## @@ -54,32 +65,39 @@ print_usage (); endif - if (ndims (x) < 3 && ndims (y) < 3 && nargin < 3) + nd = ndims (x); + + if (nd < 3 && ndims (y) < 3 && nargin < 3) ## COMPATIBILITY -- opposite behavior for cross(row,col) ## Swap x and y in the assignments below to get the matlab behavior. ## Better yet, fix the calling code so that it uses conformant vectors. - if (columns (x) == 1 && rows (y) == 1) + if (iscolumn (x) && isrow (y)) warning ("cross: taking cross product of column by row"); y = y.'; - elseif (rows (x) == 1 && columns (y) == 1) + elseif (isrow (x) && iscolumn (y)) warning ("cross: taking cross product of row by column"); x = x.'; endif endif + sz = size (x); + if (nargin == 2) - dim = find (size (x) == 3, 1); + dim = find (sz == 3, 1); if (isempty (dim)) error ("cross: must have at least one dimension with 3 elements"); endif - else - if (size (x, dim) != 3) - error ("cross: dimension DIM must have 3 elements"); - endif + else + if (! (isnumeric (dim) && dim > 0 && isreal (dim) && ... + isscalar (dim) && dim == fix (dim))) + error ("cross: DIM must be a positive scalar whole number"); + endif + + if (dim > nd || sz(dim) != 3) + error ("cross: must have three elements in dimension DIM"); + endif endif - nd = ndims (x); - sz = size (x); idx2 = idx3 = idx1 = {':'}(ones (1, nd)); idx1(dim) = 1; idx2(dim) = 2; @@ -101,26 +119,48 @@ %!test -%! x = [1 0 0]; -%! y = [0 1 0]; -%! r = [0 0 1]; -%! assert (cross (x, y), r, 2e-8); +%! x = [1, 0, 0]; +%! y = [0, 1, 0]; +%! r = [0, 0, 1]; +%! assert (cross (x, y), r, eps); + +%!test +%! x = [1, 2, 3]; +%! y = [4, 5, 6]; +%! r = [(2*6-3*5), (3*4-1*6), (1*5-2*4)]; +%! assert (cross (x, y), r, eps); %!test -%! x = [1 2 3]; -%! y = [4 5 6]; -%! r = [(2*6-3*5) (3*4-1*6) (1*5-2*4)]; -%! assert (cross (x, y), r, 2e-8); +%! x = [1, 0, 0; 0, 1, 0; 0, 0, 1]; +%! y = [0, 1, 0; 0, 0, 1; 1, 0, 0]; +%! r = [0, 0, 1; 1, 0, 0; 0, 1, 0]; +%! assert (cross (x, y, 2), r, eps); +%! assert (cross (x, y, 1), -r, eps); -%!test -%! x = [1 0 0; 0 1 0; 0 0 1]; -%! y = [0 1 0; 0 0 1; 1 0 0]; -%! r = [0 0 1; 1 0 0; 0 1 0]; -%! assert (cross (x, y, 2), r, 2e-8); -%! assert (cross (x, y, 1), -r, 2e-8); +%!test <*65527> +%! x = cat (3, [1, 1, 1]', [1, 1, 1]'); +%! y = cat (3, [1, 0, 0], [1, 0, 0]); +%! fail ("cross (x, y)", "X and Y must have the same dimensions"); +%! fail ("cross (y, x)", "X and Y must have the same dimensions"); ## Test input validation %!error <Invalid call> cross () %!error <Invalid call> cross (1) -## FIXME: Need tests for other error() conditions and warning() calls. -%!error <must have at least one dimension with 3 elements> cross (0,0) +%!error <must have at least one dimension with 3 elements> cross (0, 0) +%!error <must have at least one dimension with 3 elements> cross ([1, 2], [3, 4]) +%!error <must have at least one dimension with 3 elements> cross ([1, 2], [3, 4, 5]) +%!error <must have three elements in dimension DIM> cross (0, 0, 1) +%!error <must have three elements in dimension DIM> cross ([1, 2, 3], [1, 2, 3], 1) +%!error <must have three elements in dimension DIM> cross ([1, 2, 3], [1, 2, 3], 9) +%!error <must have three elements in dimension DIM> cross (magic (3), magic (3), 4) +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], {1}) +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], "a") +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], true) +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], [1, 2]) +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], 0) +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], -1) +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], 1.5) +%!error <DIM must be a positive scalar whole number> cross ([1, 2, 3], [4, 5, 6], 2i) +%!error <X and Y must have the same dimensions> cross ([1, 2, 3], [3, 4]) +%!warning <taking cross product of column by row> cross ([1, 2, 3]', [4, 5, 6]); +%!warning <taking cross product of row by column> cross ([1, 2, 3], [4, 5, 6]');