# HG changeset patch
# User Jaroslav Hajek
# Date 1206515428 -3600
# Node ID e8581b9e3208978491f836b003c61cf8e14ee225
# Parent 0220da981c2a4f9fc5171ea037c1bec4efc5271b
extend dmult to allow scaling arbitrary dimension
diff -r 0220da981c2a -r e8581b9e3208 scripts/ChangeLog
--- a/scripts/ChangeLog Tue Mar 25 23:57:49 2008 -0400
+++ b/scripts/ChangeLog Wed Mar 26 08:10:28 2008 +0100
@@ -1,3 +1,8 @@
+2008-03-26 Jaroslav Hajek
+
+ * linear-algebra/dmult.m: rewrite to support scaling along arbitrary
+ dimension.
+
2008-03-20 Ben Abbott
* statistics/base/statistics.m: Calculate median and quantiles in
diff -r 0220da981c2a -r e8581b9e3208 scripts/linear-algebra/dmult.m
--- a/scripts/linear-algebra/dmult.m Tue Mar 25 23:57:49 2008 -0400
+++ b/scripts/linear-algebra/dmult.m Wed Mar 26 08:10:28 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,75 @@
## .
## -*- 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{ind})
+## 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
+## @address@hidden(i,:,@dots{}) = @var{a}(i)address@hidden(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
+## @address@hidden(:,@dots{},i) = @var{a}(:,@dots{},i)address@hidden(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
+## @address@hidden(:,@dots{},i,:,@dots{}) = @var{a}(:,@dots{},i,:,@dots{})address@hidden(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)
+function m = dmult (a, b, ind)
+ if (nargin == 2)
+ sa = size (a);
+ sb = size (b);
+ if (isvector (a) && length (a) == sb(1))
+ a = a(:);
+ m = reshape (kron (ones (prod (sb(2:end)), 1), a), sb) .* b;
+ elseif (isvector (b) && length (b) == sa(end))
+ b = b(:);
+ 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
+
+%!test
+%! assert ( dmult ([1,2,3], ones(3)), [1,1,1;2,2,2;3,3,3] )
+%! assert ( dmult ([1,2,3]', ones(3)), [1,1,1;2,2,2;3,3,3] )
+%!test
+%! assert ( dmult ([1,2,3], ones(3,2,2)), reshape ([1,1,1,1;2,2,2,2;3,3,3,3], [3,2,2]) )
+%!test
+%! assert ( dmult (ones(3), [1,2,3]), [1,2,3;1,2,3;1,2,3] )
+%! assert ( dmult (ones(3), [1,2,3]'), [1,2,3;1,2,3;1,2,3] )
+%!test
+%! assert ( dmult (ones(2,2,3), [1,2,3]), reshape ([1,2,3;1,2,3;1,2,3;1,2,3], [2,2,3]) )
+%!test
+%! assert ( dmult (ones(3,4,2), [1 2 3 4], 2),...
+%! reshape ([1 1 1 2 2 2 3 3 3 4 4 4 1 1 1 2 2 2 3 3 3 4 4 4], [3,4,2]) )