# HG changeset patch # User jwe # Date 1133321211 0 # Node ID 71cfd8fedd5decb3d2caaa2f8380bfcbc958f4c1 # Parent 815926a781f6b9b7b789d6258ab72713521eed5d [project @ 2005-11-30 03:26:50 by jwe] diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,4 +1,7 @@ -2005-11-26 William Poetra Yoga Hadisoeseno +2005-11-23 William Poetra Yoga Hadisoeseno + + * general/blkdiag.m: Import from octave-forge. + Ignore empty matrices in the input. Add tests. * general/isequal.m, general/isequalwithequalnans.m: New wrapper scripts for general/__isequal__.m. diff --git a/scripts/general/blkdiag.m b/scripts/general/blkdiag.m new file mode 100644 --- /dev/null +++ b/scripts/general/blkdiag.m @@ -0,0 +1,71 @@ +## Copyright (C) 2000 Daniel Calvelo +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## -*- texinfo -*- +## @deftypefn {Function File} {} blkdiag (@var{a}, @var{b}, @var{c}, ...) +## Build a block diagonal matrix from @var{a}, @var{b}, @var{c}, ... . +## All the arguments must be numeric and are two-dimensional matrices or +## scalars. +## @end deftypefn +## +## @seealso{diag, horzcat, vertcat} + +## Author: Daniel Calvelo +## Modified by: William Poetra Yoga Hadisoeseno + +function retval = blkdiag (varargin) + + if (nargin < 1) + usage ("blkdiag (a, b, c, ...)"); + endif + + # isnumeric is not an option for cellfun + if (! all (cell2mat (cellfun (@isnumeric, varargin)))) + error ("all of the arguments to blkdiag must be numeric"); + endif + + # ndims is, so it's used here for speed + # note: trailing singletons are automatically (correctly) ignored + if (! all (cellfun ("ndims", varargin) == 2)) + error ("all of the arguments to blkdiag must be two-dimensional matrices"); + endif + + # ignore empty matrices + notempty = ! cellfun ("isempty", varargin); + varargin = varargin(notempty); + + # size is, but it's a bit different from calling size directly + csz = cumsum ([0 0; (cell2mat (cellfun (@size, varargin')))], 1); + retval = zeros (csz(end,:)); + for p = 1:(length (notempty(notempty))) + retval((csz(p,1)+1):csz(p+1,1),(csz(p,2)+1):csz(p+1,2)) = varargin{p}; + endfor + +endfunction + +# regular tests +%!assert(blkdiag(1,ones(2),1),[1,0,0,0;0,1,1,0;0,1,1,0;0,0,0,1]) +%!assert(blkdiag([1,2],[3,4],[5,6]),[1,2,0,0,0,0;0,0,3,4,0,0;0,0,0,0,5,6]) +%!assert(blkdiag([1,2],[3;4],[5,6]),[1,2,0,0,0;0,0,3,0,0;0,0,4,0,0;0,0,0,5,6]) +%!assert(blkdiag([1,2;3,4],[5,6,7]),[1,2,0,0,0;3,4,0,0,0;0,0,5,6,7]) +# tests involving empty matrices +%!assert(blkdiag([],[],[]),[]) +%!assert(blkdiag([],[1,2;3,4],[],5,[]),[1,2,0;3,4,0;0,0,5]) +%!assert(blkdiag(zeros(1,0,1),[1,2,3],1,0,5,zeros(0,1,1)),[1,2,3,0,0,0;0,0,0,1,0,0;0,0,0,0,0,0;0,0,0,0,0,5]); +# sanity checks +%!test +%! A = rand (round (rand (1, 2) * 10)); +%! assert (blkdiag (A), A);