Multidimensional arrays in Matlab Xanadu Halkias Overview • Creating/accessing/indexing multidimensional arrays • Using and computing with multidimensional arrays • Multidimensional cell arrays • Multidimensional structure arrays Corpus hypercubus %Creating multidimensional arrays a = [1 2 3;0 6 4;2 5 4]; a(:,:,2) = [4 2 1;0 5 1;6 3 2]; a(:,:,3) = 3; %turning a into a 3x3x3x2 a(:,:,:,2) = ones(3,3,3); a(:,:,1,2) = 4; More on creating %different way b = repmat(2,[3 3 3 2]); c = repmat(rand(2),[3 1 2]); %one more d = cat(4,[1 4; 2 3],[5 8;2 3]); Memory: try to pre-allocate eg. zeros or use repmat for best performance A few good functions… %reshape and permute %a bunch of data x = rand(3,3,2); new_x = reshape(x,[6 3]); tranx = permute(x,[2 1 3]); Ind = sub2ind(size(x),1,3,2); Working with them %computing with multidimensional arrays x = rand(3,3,3); s = sum(x,3); d = sin(x); e = eig(x(:,:,2)); ee = eig(squeeze(x(2,:,:))); Multidimensional cell arrays %multidimensional cells a = {[1 2 5 3 77 2 4 5], 1:10; rand(1,3), 2}; b = {1:2:15, rand(1,5); [1 0 0 1], 5;} c = cat(3,a,b); [D{1}] = conv(c{1:2}); [D{2}] = conv(c{1,1,:}); d = cell2mat(D); for i=1:length(D{1}), m1(i) = D{1}(i); end for i=1:length(D{2}), m2(i) = D{2}(i); end m = [m1, m2]; Multidimensional structure arrays %multidimensional structures dolphin(1,1,1).species = 'bottlenose'; dolphin(1,1,1).sampfreq = 44100; dolphin(1,1,1).signal = rand(1,100); dolphin(1,2,1).species = 'atlantic'; dolphin(1,2,1).sampfreq = 44100; dolphin(1,2,1).signal = rand(1,100); dolphin(1,1,2).species = 'pink'; dolphin(1,1,2).sampfreq = 44100; dolphin(1,1,2).signal = rand(1,100); dolphin(1,2,2).species = 'riso'; dolphin(1,2,2).sampfreq = 44100; dolphin(1,2,2).signal = rand(1,100); Multidimensional structures more… %computing some stuff s = sum([dolphin.sampfreq]); [b{1}] = fft(dolphin(1,1,1).signal); dolphin(1,1,1).fourier = b; Murphy’s mhmm_em.m %each page gets its own cell if ~iscell(data) data = num2cell(data, [1 2]); end numex = length(data); %num of pages is number mixtures O = size(data{1},1); %getting the dimensionality Q = length(prior); %number of states if isempty(mixmat)%number of mixtures mixmat = ones(Q,1); end M = size(mixmat,2); if M == 1 adj_mix = 0; end Murphy’s more-EM while (num_iter <= max_iter) & ~converged % E step [loglik, exp_num_trans, exp_num_visits1, postmix, m, ip, op] = ... ess_mhmm(prior, transmat, mixmat, mu, Sigma, data); % M step if verbose, fprintf(1, 'iteration %d, loglik = %f\n', num_iter, loglik); end num_iter = num_iter + 1; converged = em_converged(loglik,previous_loglik, thresh); previous_loglik = loglik; LL = [LL loglik]; end The E of EM function [loglik, exp_num_trans, exp_num_visits1, postmix, m, ip, op] = ... ess_mhmm(prior, transmat, mixmat, mu, Sigma, data) Loglik: likelihood of the model Exp_num_trans: expected number of transitions is the transition matrix Exp_num_visits1: expected number of visits to each state is our priors Postmix: is the mixing matrix M: is the weighted observations Ip: is the weighted inner product of the observations Op: is the weighted outer product of the observations More on E %initialization verbose = 0; numex = length(data); O = size(data{1},1); Q = length(prior); M = size(mixmat,2); exp_num_trans = zeros(Q,Q); exp_num_visits1 = zeros(Q,1); postmix = zeros(Q,M); m = zeros(O,Q,M); op = zeros(O,O,Q,M); ip = zeros(Q,M); mix = (M>1); One more on expectation loglik = 0; if verbose, fprintf(1, 'forwards-backwards example # '); end for ex=1:numex if verbose, fprintf(1, '%d ', ex); end obs = data{ex}; T = size(obs,2); if mix %if you have mixtures [B, B2] = mixgauss_prob(obs, mu, Sigma, mixmat); [alpha, beta, gamma, current_loglik, xi, gamma2] = ... fwdback(prior, transmat, B, 'obslik2', B2, 'mixmat', mixmat); else %one single gaussian as an emission B = mixgauss_prob(obs, mu, Sigma); [alpha, beta, gamma, current_loglik, xi] = fwdback(prior, transmat, B); end Almost done loglik = loglik + current_loglik; if verbose, fprintf(1, 'll at ex %d = %f\n', ex, loglik); end exp_num_trans = exp_num_trans + sum(xi,3); exp_num_visits1 = exp_num_visits1 + gamma(:,1); if mix postmix = postmix + sum(gamma2,3); else postmix = postmix + sum(gamma,2); gamma2 = reshape(gamma, [Q 1 T]); end Last one for i=1:Q for k=1:M w = reshape(gamma2(i,k,:), [1 T]); % w(t) = w(i,k,t,l) wobs = obs .* repmat(w, [O 1]); % wobs(:,t) = w(t) * obs(:,t) m(:,i,k) = m(:,i,k) + sum(wobs, 2); % m(:) = sum_t w(t) obs(:,t) op(:,:,i,k) = op(:,:,i,k) + wobs * obs'; % op(:,:) = sum_t w(t) * obs(:,t) * obs(:,t)' ip(i,k) = ip(i,k) + sum(sum(wobs .* obs, 2)); % ip = sum_t w(t) * obs(:,t)' * obs(:,t) end end end if verbose, fprintf(1, '\n'); end