comparison notes/cplcaMT-annotated.m @ 5:ed9e20b6b165

Begin annotating the m files
author Chris Cannam
date Wed, 19 Mar 2014 12:40:46 +0000
parents
children 0d181e07c778
comparison
equal deleted inserted replaced
4:155a50cf91f5 5:ed9e20b6b165
1 function [w,h,z,u,xa] = cplcaMT( x, K, T, R, w, h, z, u, iter, sw, sh, sz, su, lw, lh, lz, lu, pa)
2 % function [w,h,xa2] = cplcaMT( x, K, T, R, w, h, z, u, iter, sw, sh, sz, su, lw, lh, lz, lu)
3 %
4 % Perform multiple-source, multiple-template SIPLCA for transcription
5 %
6 % Inputs:
7 % x input distribution
8 % K number of components
9 % T size of components
10 % R size of sources
11 % w initial value of p(w) [default = random]
12 % h initial value of p(h) [default = random]
13 % z initial value of p(z) [default = random]
14 % iter number of EM iterations [default = 10]
15 % sw sparsity parameter for w [default = 1]
16 % sh sparsity parameter for h [default = 1]
17 % sz sparsity parameter for z [default = 1]
18 % lw flag to update w [default = 1]
19 % lh flag to update h [default = 1]
20 % lh flag to update h [default = 1]
21 % pa source-component activity range [Rx2]
22 %
23 % Outputs:
24 % w p(w) - spectral bases
25 % h p(h) - pitch impulse
26 % z p(z) - mixing matrix for p(h)
27 % xa approximation of input
28
29 % Emmanouil Benetos 2011, based on cplca code by Paris Smaragdis
30
31
32 %% for the transcription application,
33 %% x -> noise-reduced constant Q. In the application this is a 2-sec,
34 %% 100-col segment with 2 zeros at top and bottom, so 549x100
35 %% K -> 88, number of notes
36 %% T -> [545 1], a two-element array: 545 is the length of each
37 %% template, but why 1?
38 %% R -> 10, number of instruments
39 %% w -> a 10x88 cell array, in which w{instrument,note} is a 545x1
40 %% array containing the template for the given instrument and note
41 %% number
42 %% h -> empty
43 %% z -> empty
44 %% u -> empty
45 %% iter -> a parameter for the program, 12 in the mirex submission
46 %% sw -> 1
47 %% sh -> 1
48 %% sz -> 1.1
49 %% su -> 1.3, not documented above, presumably sparsity for u
50 %% lw -> 0, don't update w
51 %% lh -> 1, do update h
52 %% lz -> 1, do update z
53 %% lu -> 1, not documented above, presumably do update u
54 %% pa -> a 10x2 array in which pa(instrument,1) is the lowest note
55 %% expected for that instrument and pa(instrument,2) is the highest
56
57
58 % Sort out the sizes
59
60 wc = 2*size(x)-T; %% works out to 553x199
61 hc = size(x)+T-1; %% works out to 1093x100
62
63 % Default training iterations
64 if ~exist( 'iter')
65 iter = 10;
66 end
67
68
69 % Initialize
70 sumx = sum(x); %% for later normalisation
71
72 if ~exist( 'w') || isempty( w)
73 %% doesn't happen, w was provided (it's the template data)
74 w = cell(R, K);
75 for k = 1:K
76 for r=1:R
77 w{r,k} = rand( T);
78 w{r,k} = w{r,k} / sum( w{r,k}(:));
79 end
80 end
81 end
82 if ~exist( 'h') || isempty( h)
83 %% does happen, h was not provided
84 h = cell(1, K);
85 for k = 1:K
86 h{k} = rand( size(x)-T+1);
87 h{k} = h{k};
88 end
89 %% h is now a 1x88 cell, h{note} is a 5x100 array of random values.
90 %% The 5 comes from the height of the CQ array minus the length of
91 %% a template, plus 1. I guess this is space to allow for the
92 %% 5-bins-per-semitone pitch shift.
93 end
94 if ~exist( 'z') || isempty( z)
95 %% does happen, z was not provided
96 z = cell(1, K);
97 for k = 1:K
98 z{k} = rand( size(x,2),1);
99 z{k} = z{k};
100 end
101 %% z is a 1x88 cell, z{note} is a 100x1 array of random values.
102 end
103 if ~exist( 'u') || isempty( u)
104 %% does happen, u was not provided
105 u = cell(R, K);
106 for k = 1:K
107 for r=1:R
108 if( (pa(r,1) <= k && k <= pa(r,2)) )
109 u{r,k} = ones( size(x,2),1);
110 else
111 u{r,k} = zeros( size(x,2),1);
112 end
113 end;
114 end
115 %% u is a 10x88 cell, u{instrument,note} is a 100x1 double containing
116 %% all 1s if note is in-range for instrument and all 0s otherwise
117 end
118
119 fh = cell(1, K);
120 fw = cell(R, K);
121 for k = 1:K
122 fh{k} = ones(wc) + 1i*ones(wc);
123 for r=1:R
124 fw{r,k} = ones(wc) + 1i*ones(wc);
125 end;
126 end;
127
128
129
130 % Make commands for subsequent multidim operations and initialize fw
131 fnh = 'c(hc(1)-(T(1)+(1:size(h{k},1))-2),hc(2)-(T(2)+(1:size(h{k},2))-2))';
132 xai = 'xa(1:size(x,1),1:size(x,2))';
133 flz = 'xbar(end:-1:1,end:-1:1)';
134
135 for k = 1:K
136 for r=1:R
137 if( (pa(r,1) <= k && k <= pa(r,2)) )
138 fw{r,k} = fftn( w{r,k}, wc);
139 end;
140 end;
141 end;
142
143 % Iterate
144 for it = 1:iter
145
146 %disp(['Iteration: ' num2str(it)]);
147
148 % E-step
149 xa = eps;
150 for k = 16:73
151 fh{k} = fftn( h{k}, wc);
152 for r=1:R
153 if( (pa(r,1) <= k && k <= pa(r,2)) )
154 xa1 = abs( real( ifftn( fw{r,k} .* fh{k})));
155 xa = xa + xa1(1:size(x,1),1:size(x,2)) .*repmat(z{k},1,size(x,1))'.*repmat(u{r,k},1,size(x,1))';
156 clear xa1;
157 end
158 end
159 end
160
161 xbar = x ./ xa;
162 xbar = eval( flz);
163 fx = fftn( xbar, wc);
164
165
166 % M-step
167 for k = 16:73
168
169
170 % Update h, z, u
171 nh=eps;
172 for r=1:R
173 if( (pa(r,1) <= k && k <= pa(r,2)) )
174 c = abs( real( ifftn( fx .* fw{r,k} )));
175 nh1 = eval( fnh);
176 nh1 = nh1 .*repmat(u{r,k},1,size(h{k},1))';
177 nh = nh + nh1;
178
179 nhu = eval( fnh);
180 nhu = nhu .* h{k};
181 nu = sum(nhu)';
182 nu = u{r,k} .* nu + eps;
183 if lu
184 u{r,k} = nu;
185 end;
186
187 end;
188 end
189 nh = h{k} .* (nh.^sh);
190 nz = sum(nh)';
191 nz = z{k} .* nz + eps;
192
193
194 % Assign and normalize
195 if lh
196 h{k} = nh;
197 end
198 if lz
199 z{k} = nz;
200 end
201
202
203 end
204
205 % Normalize z over t
206 if lz
207 Z=[]; for i=1:K Z=[Z z{i}]; end;
208 Z = Z.^sz;
209 Z(1:end,1:15)=0;
210 Z(1:end,74:88)=0;
211 Z = Z./repmat(sum(Z,2),1,K); z = num2cell(Z,1); %figure; imagesc(imrotate(Z,90));
212 end
213
214 % Normalize u over z,t
215 if lu
216 U=[]; for r=1:R U(r,:,:) = cell2mat(u(r,:)); end;
217 for i=1:size(U,2) for j=1:size(U,3) U(:,i,j) = U(:,i,j).^su; U(:,i,j) = U(:,i,j) ./ sum(U(:,i,j)); end; end;
218 U0 = permute(U,[2 1 3]); u = squeeze(num2cell(U0,1));
219 end
220
221 % Normalize h over z,t
222 H=[]; for k=1:K H(k,:,:) = cell2mat(h(k)); end; H0 = permute(H,[2 1 3]);
223 for i=1:size(H0,2) for j=1:size(H0,3) H0(:,i,j) = sumx(j)* (H0(:,i,j) ./ sum(H0(:,i,j))); end; end;
224 h = squeeze(num2cell(squeeze(H0),[1 3])); for k=1:K h{k} = squeeze(h{k}); end;
225
226 %figure; imagesc(imrotate(xa',90));
227
228 end
229
230 %figure; imagesc(imrotate(xa',90));