% multiplies block defined matrix stored inside cell array%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DESCRIPTION: cell_mult multiplies block defined matrix stored inside cell% array%% CALL: [cell3] = ssm.blockMatMult(cell1,cell2,isnotempty_1,isnotempty_2)%% INPUTS:% cell1 - cell array of matrices representing a matrix by blocs.% blocs may be empty% cell2 - cell array of matrices representing a matrix by blocs.% blocs may be empty%% OPTIONNAL INPUTS:% isnotempty_1 - logical array tells ~isequal(cell1{ii,jj},[])% isnotempty_2 - logical array tells ~isequal(cell2{ii,jj},[])%% OUTPUTS:% cell3 - cell array of matrices representing a matrix by blocs.% blocs may be empty%% NOTE : function is private to the ssm class%% VERSION: '$Id: blockMatMult.m,v 1.7 2011/04/08 08:56:24 hewitson Exp $'%% TO DO :% check ME in case of mixed symbolic and double%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function c = blockMatMult(varargin) a=varargin{1}; b =varargin{2}; n1 = size(a,1); n2 = size(a,2); n3 = size(b,2); if nargin == 4 sizes1 = varargin{3}; sizes3 = varargin{4}; if numel(sizes1)~=n1 error('Incompatible user input (3rd argument does not correctly indicate final line heights)'); elseif numel(sizes3)~=n3 error('Incompatible user output (4th argument does not correctly indicate final column widths)'); end end c = cell(n1,n3); if isempty(a)||isempty(b) % if the content matrix is empty if n2==0 && n1>0 && n3>0 if nargin == 4 c = ssm.blockMatFillDiag(c,sizes1,sizes3); else error('cannot build proper matrices') end end else % if matrices are not empty isnotempty_a = not(cellfun(@isempty, a)); isnotempty_b = not(cellfun(@isempty, b)); % extra check for the extended diagonal for ii=1:max(n1, n2) isnotempty_a(min(ii,n1),min(ii,n2)) = true; end for ii=1:max(n2, n3) isnotempty_b(min(ii,n2), min(ii,n3)) = true; end isempty_c = true(n1,n3); for ii=1:n1 for kk=1:n2 if isnotempty_a(ii,kk) for jj=1:n3 if isnotempty_b(kk,jj) if isempty_c(ii,jj) % note that the matrix multiplication preserves a non-empty block diagonal if (isempty(a{ii,kk}) || isempty(b{kk,jj})) % exception for the case where you have one or more empty matrix c{ii,jj} = zeros(size(a{ii,kk},1), size(b{kk,jj},2)); else c{ii,jj} = a{ii,kk}*b{kk,jj}; end isempty_c(ii,jj) = false; else if (isempty(a{ii,kk}) || isempty(b{kk,jj})) % exception for the case where you have one or more empty matrix else c{ii,jj} = c{ii,jj} + a{ii,kk}*b{kk,jj}; end end end end end end end endend