# HG changeset patch # User jwe # Date 1083875789 0 # Node ID e7da90a1cc114f6c63eb877ea37c72bafc6879da # Parent 658aad1c1b05731c987839b3f7568752e95eb14a [project @ 2004-05-06 20:36:29 by jwe] diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,17 @@ +2004-05-06 David Bateman + + * general/issquare.m: Fail if ndim(x) > 2. + + * linear-algebra/norm.m, linear-algebra/norm.m: Fail if ndim(x) > 2. + + * linear-alegbra/cross.m, linear-algebra/dot.m: Allow matrix and + N-d array arguments. Add optional dim argument to define + dimension along which to operate. + + * linear-algebra/dmult.m: Allow N-d arrays. + + * linear-algebra/vec.m: Use v(:) and not reshape. + 2004-04-29 David Bateman * statistics/base/ranks.m, statistics/base/run_count.m, diff --git a/scripts/general/issquare.m b/scripts/general/issquare.m --- a/scripts/general/issquare.m +++ b/scripts/general/issquare.m @@ -33,7 +33,7 @@ retval = 0; if (nargin == 1) - if (ismatrix (x)) + if (ismatrix (x) && ndims (x) < 3) [nr, nc] = size (x); if (nr == nc && nr > 0) retval = nr; diff --git a/scripts/linear-algebra/cond.m b/scripts/linear-algebra/cond.m --- a/scripts/linear-algebra/cond.m +++ b/scripts/linear-algebra/cond.m @@ -30,6 +30,10 @@ function retval = cond (a) if (nargin == 1) + if (ndims (x) > 2) + error ("cond: Only valid on 2-D objects") + endif + [nr, nc] = size (a); if (nr == 0 || nc == 0) retval = 0.0; diff --git a/scripts/linear-algebra/cross.m b/scripts/linear-algebra/cross.m --- a/scripts/linear-algebra/cross.m +++ b/scripts/linear-algebra/cross.m @@ -18,7 +18,7 @@ ## 02111-1307, USA. ## -*- texinfo -*- -## @deftypefn {Function File} {} cross (@var{x}, @var{y}) +## @deftypefn {Function File} {} cross (@var{x}, @var{y}, @var{dim}) ## Computes the vector cross product of the two 3-dimensional vectors ## @var{x} and @var{y}. ## @@ -29,44 +29,62 @@ ## @end group ## @end example ## -## If @var{x} and @var{y} are two - dimensional matrices the -## cross product is applied along the first dimension with 3 elements. -## +## If @var{x} and @var{y} are matrices, the cross product is applied +## along the first dimension with 3 elements. The optional argument +## @var{dim} is used to force the cross product to be calculated along +## the dimension defiend by @var{dim}. ## @end deftypefn ## Author: Kurt Hornik ## Created: 15 October 1994 ## Adapted-By: jwe -function z = cross (x, y) +function z = cross (x, y, dim) - if (nargin != 2) - usage ("cross (x, y)"); + if (nargin != 2 && nargin != 3) + usage ("cross (x, y, dim)"); + endif + + if (ndims (x) < 3 && ndims (y) < 3 && nargin < 3) + ## XXX COMPATIBILITY XXX opposite behaviour for cross(row,col) + ## Swap x and y in the assignments below to get the matlab behaviour. + ## Better yet, fix the calling code so that it uses conformant vectors. + if (columns (x) == 1 && rows (y) == 1) + warning ("cross: taking cross product of column by row"); + y = y.'; + elseif (rows (x) == 1 && columns (y) == 1) + warning ("cross: taking cross product of row by column"); + x = x.'; + endif endif - ## XXX COMPATIBILITY XXX opposite behaviour for cross(row,col) - ## Swap x and y in the assignments below to get the matlab behaviour. - ## Better yet, fix the calling code so that it uses conformant vectors. - if (columns(x) == 1 && rows(y) == 1) - warning ("cross: taking cross product of column by row"); - y = y.'; - elseif (rows(x) == 1 && columns(y) == 1) - warning ("cross: taking cross product of row by column"); - x = x.'; + if (nargin == 2) + dim = min (find (size (x) == 3)); + if (isempty (dim)) + error ("cross: must have at least one dimension with 3 elements"); + endif + else + if (size (x) != 3) + error ("cross: dimension dim must have 3 elements"); + endif endif - if (size(x) == size(y)) - if (rows(x) == 3) - z = [ ( x (2,:) .* y (3,:) - x (3,:) .* y (2,:) ) ; - ( x (3,:) .* y (1,:) - x (1,:) .* y (3,:) ) ; - ( x (1,:) .* y (2,:) - x (2,:) .* y (1,:) ) ]; - elseif (columns(x) == 3) - z = [ ( x (:,2) .* y (:,3) - x (:,3) .* y (:,2) ) , \ - ( x (:,3) .* y (:,1) - x (:,1) .* y (:,3) ) , \ - ( x (:,1) .* y (:,2) - x (:,2) .* y (:,1) ) ]; - else - error ("cross: x,y must have dimension nx3 or 3xn"); - endif + nd = ndims (x); + sz = size (x); + idx1 = cell (); + for i = 1:nd + idx1{i} = 1:sz(i); + endfor + idx2 = idx3 = idx1; + idx1(dim) = 1; + idx2(dim) = 2; + idx3(dim) = 3; + + if (size (x) == size (y)) + z = cat (dim, + (x(idx2{:}) .* y(idx3{:}) - x(idx3{:}) .* y(idx2{:})), + (x(idx3{:}) .* y(idx1{:}) - x(idx1{:}) .* y(idx3{:})), + (x(idx1{:}) .* y(idx2{:}) - x(idx2{:}) .* y(idx1{:}))); else error ("cross: x and y must have the same dimensions"); endif diff --git a/scripts/linear-algebra/dmult.m b/scripts/linear-algebra/dmult.m --- a/scripts/linear-algebra/dmult.m +++ b/scripts/linear-algebra/dmult.m @@ -31,12 +31,11 @@ if (nargin != 2) usage ("dmult (a, B)"); endif - - s = size (a); - if ((min (s) > 1) || (max (s) != rows (B))) + if (! isvector (a)) error ("dmult: a must be a vector of length rows (B)"); endif - - M = (reshape (a, max (s), 1) * ones (1, columns (B))) .* B; - + a = a(:); + sb = size (B); + sb(1) = 1; + M = repmat (a(:), sb) .* B; endfunction diff --git a/scripts/linear-algebra/dot.m b/scripts/linear-algebra/dot.m --- a/scripts/linear-algebra/dot.m +++ b/scripts/linear-algebra/dot.m @@ -18,36 +18,37 @@ ## 02111-1307, USA. ## -*- texinfo -*- -## @deftypefn {Function File} {} dot (@var{x}, @var{y}) -## Computes the dot product of two vectors. +## @deftypefn {Function File} {} dot (@var{x}, @var{y}, @var{dim}) +## Computes the dot product of two vectors. If @var{x} and @var{y} +## are matrices, calculate the dot-product along the first +## non-singleton dimension. If the optional argument @var{dim} is +## given, calculate the dot-product along this dimension. ## @end deftypefn ## Author: jwe -function z = dot (x, y) +function z = dot (x, y, dim) - if (nargin != 2) - usage ("dot (x, y)"); + if (nargin != 2 && nargin != 3) + usage ("dot (x, y, dim)"); endif - if (isvector (x) && isvector (y) && length (x) == length (y)) - [x_nr, x_nc] = size (x); - [y_nr, y_nc] = size (y); - if (x_nr == 1) - if (y_nr == 1) - z = x * y.'; - else - z = x * y; - endif - else - if (y_nr == 1) - z = y * x; - else - z = y.' * x; - endif + if (nargin < 3) + if isvector (x) + x = x(:); + endif + if isvector (y) + y = y(:); endif + if (size (x) != size (y)) + error ("dot: sizes of arguments must match") + endif + z = sum(x .* y); else - error ("dot: both arguments must be vectors of the same length"); + if (size (x) != size (y)) + error ("dot: sizes of arguments must match") + endif + z = sum(x .* y, dim); endif endfunction diff --git a/scripts/linear-algebra/norm.m b/scripts/linear-algebra/norm.m --- a/scripts/linear-algebra/norm.m +++ b/scripts/linear-algebra/norm.m @@ -68,6 +68,10 @@ return; endif + if (ndims (x) > 2) + error ("norm: Only valid on 2-D objects") + endif + ## Do we have a vector or matrix as the first argument? if (rows (x) == 1 || columns (x) == 1) diff --git a/scripts/linear-algebra/vec.m b/scripts/linear-algebra/vec.m --- a/scripts/linear-algebra/vec.m +++ b/scripts/linear-algebra/vec.m @@ -36,6 +36,6 @@ usage ("vec (x)"); endif - v = reshape (x, prod (size (x)), 1); + v = x(:); endfunction