# HG changeset patch # User Jaroslav Hajek # Date 1205134657 -3600 # Node ID c1230c903a74ccd24935ba7ea4d9647820e30a01 # Parent 85da2ab0c6fd626a891fdcb9185ba2d80f96ca0e rewrite dmult to allow scaling from right and along arbitrary dimension diff -r 85da2ab0c6fd -r c1230c903a74 scripts/ChangeLog --- a/scripts/ChangeLog Fri Mar 07 20:17:54 2008 -0500 +++ b/scripts/ChangeLog Mon Mar 10 08:37:37 2008 +0100 @@ -1,3 +1,8 @@ 2008-03-07 John W. Eaton + + * linear-algebra/dmult.m: rewrite to support scaling along arbitrary + dimension. + 2008-03-07 John W. Eaton * plot/contourf.m: Set axes layer property to "top". diff -r 85da2ab0c6fd -r c1230c903a74 scripts/linear-algebra/dmult.m --- a/scripts/linear-algebra/dmult.m Fri Mar 07 20:17:54 2008 -0500 +++ b/scripts/linear-algebra/dmult.m Mon Mar 10 08:37:37 2008 +0100 @@ -1,5 +1,4 @@ -## Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2005, 2006, -## 2007 Kurt Hornik +## Copyright (C) 2008 VZLU Prague, a.s., Czech Republic ## ## This file is part of Octave. ## @@ -18,24 +17,61 @@ ## . ## -*- texinfo -*- -## @deftypefn {Function File} {} dmult (@var{a}, @var{b}) +## @deftypefn {Function File} address@hidden = dmult (@var{a}, @var{b}) +## @deftypefnx {Function File} address@hidden = dmult (@var{a}, @var{b}, @var{index}) +## Scales a matrix by rows or columns, or a multidimensional tensor along +## a specified dimension. @* ## If @var{a} is a vector of length @code{rows (@var{b})}, return ## @code{diag (@var{a}) * @var{b}} (but computed much more efficiently). +## Similarly, if @var{b} is a vector of length @code{columns(@var{a})}, +## return @address@hidden * diag(@var{b})}. +## +## If @var{b} is a multidimensional array and @var{a} a vector, +## @var{c} will have the same shape as @var{b}, with +## @code{C(i,:,@dots{}) = A(i)*B(i,:,@dots{})}. +## @* +## If @var{a} is a multidimensional array and @var{b} a vector, +## @var{c} will have the same shape as @var{a}, with +## @code{C(:,@dots{},i) = A(:,@dots{},i)*B(i)}. +## +## If @var{ind} is supplied, @var{a} should be an array and @var{b} +## a vector of length @code{size (@var{a},index)}. The result is then +## @code{C(:,@dots{},i,:,@dots{}) = A(:,@dots{},i,:,@dots{})*B(i)} +## where i indexes the @var{ind}-th dimension. ## @end deftypefn -## Author: KH -## Description: Rescale the rows of a matrix +## Author: Jaroslav Hajek +## Description: Scale a tensor along a dimension -function M = dmult (a, B) +### Original Author: KH +### Original Description: Rescale the rows of a matrix - if (nargin != 2) - print_usage (); +function M = dmult (A, B, ind) + if (nargin == 2) + if (isvector(A) && length(A) == rows(B)) + A = A(:); + sb = size(B); + M = reshape(kron(ones(prod(sb(2:end)), 1), A), sb) .* B; + elseif (isvector(B) && length(B) == columns(A)) + B = B(:); + sa = size(A); + M = reshape(kron(B, ones(prod(sa(1:end-1)), 1)), sa) .* A; + else + error ("dmult: dimensions mismatch"); + endif + + elseif (nargin == 3 && isscalar(ind)) + if (isvector(B) && ind > 0 && ind <= ndims(A) && length(B) == size(A, ind)) + B = B(:); + sa = size(A); + sal = prod(sa(1:ind-1)); sat = prod(sa(ind+1:end)); + S = kron(ones(sat, 1), kron(B, ones(sal, 1))); + M = reshape(S, sa) .* A; + else + error ("dmult: dimensions mismatch or index out of range") + endif + else + print_usage(); endif - if (! isvector (a)) - error ("dmult: a must be a vector of length rows (B)"); - endif - a = a(:); - sb = size (B); - sb(1) = 1; - M = repmat (a(:), sb) .* B; + endfunction