Mercurial > hg > trimatlab
changeset 0:be936975f254
Initial check in.
author | samer |
---|---|
date | Wed, 01 Feb 2012 14:06:37 +0000 |
parents | |
children | 39d4f9e57b26 |
files | mt_calibrate.m mt_ensure.m mt_get_transmat_at.m mt_init.m mt_resample.m mt_show_transmat.m private/mc_fixpt.m private/mc_global_info.m private/sample_transmat_hdp.m private/scatc.m |
diffstat | 10 files changed, 352 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mt_calibrate.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,42 @@ +% mt_calibrate - Set spatial calibration of melody triangle system. +% +% mt_calibrate :: +% mt_system ~'system to calibrate', +% I:[[1,E]->[3]] ~'list triangle corners being updated', +% P:[[3,E]] ~'X-Y coordinates of the E corners being updated' +% -> mt_system ~'calibrated system'. + +function Sys=mt_calibrate(Sys,I,PI) + + if nargin>2, Sys.refpoints(:,I) = PI; end + P = Sys.refpoints; + p0 = P(:,1); + Sys.map = info_map_fn(p0,inv(P(:,2:3)-repmat(p0,1,2))); +end + +function f=info_map_fn(p0,M) + f=@(p)clip_tri(M*(p-p0)); +end + +function x=clip_tri(x) + if x(2)<0 + x(2)=0; + if x(1)<0, x(1)=0; + elseif x(1)>1, x(1)=1; + end + elseif x(1)<0 + x(1)=0; + if x(2)<0, x(2)=1; + elseif x(2)>1, x(2)=1; + end + else + d = [1,1]*x - 1; + if d>0 + x = x - d/2; + if x(1)<0, x=[0;1]; + elseif x(2)<0, x=[1;0]; + end + end + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mt_ensure.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,17 @@ +% mt_ensure - Ensure that Melody Triange system includes transmats of given size +% +% mt_ensure :: +% mt_system ~'melody triangle system', +% K:natural ~'desired size of transition matrices' +% -> action mt_system. +% +% If the system already contains transition matrices of size K, then it is +% returned unchanged. Otherwise, a set of transition matrices is sampled using +% the parameters supplied to mt_init. If sampling is done, a scatter plot +% will be generated as a side effect. + +function Sys=mt_ensure(Sys,K) + if length(Sys.transmats)<K || isempty(Sys.transmats{K}) + Sys=mt_resample(Sys,K); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mt_get_transmat_at.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,37 @@ +% mt_get_transmat_at - Get transition matrix near given point in information space. +% +% mt_get_transmat_at :: +% mt_system ~'Melody Triangle system structure', +% natural ~'voice Id (1 or greater)', +% K:natural ~'size of transition matrix', +% real ~'X-coordinate', +% real ~'Y-coordinate' +% -> [[K,K]] ~'transition matrix', +% [[1,3]] ~'information coordinates'. +% +% The selected transition matrix will be shown using mt_show_transmat, +% and it's information coordinates printed in the title of the main scatter plot. + +function [T,I]=mt_get_transmat_at(Sys,Id,K,X,Y) + normpos = Sys.map([X;Y])'; + target = normpos *log(K); + tmats = Sys.transmats{K}; + info = Sys.info{K}; + L = size(info,1); + + % distance from target + d2 = sum((info(:,1:2) - repmat(target,L,1)).^2,2); + Mask = d2<=max(min(d2)*2,0.01); + + M = find(Mask); +% J = M(argmax(info(M,3))); + J = M(1+floor(length(M)*rand)); + T = tmats(:,:,J); + I = info(J,:); + %Mask=2*int16(Mask); Mask(J)=1; + %set(Sys.hScat{K},'CDATA',Mask); % scatc(info,Mask,16); rotate3d on; + figure(Sys.fig); title(sprintf('info: %.2f, %.2f, %.2f',I(1),I(2),I(3))); + %figure(50); title(sprintf('pos: %.2f, %.2f',normpos(1), normpos(2))); + %fprintf('normpos: %.2f, %.2f',normpos(1), normpos(2)); + mt_show_transmat(Id,T); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mt_init.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,27 @@ +% mt_init - Initialise Melody Triangle system. +% +% mt_init :: +% A0:nonneg ~'parameter for sampling', +% B0:nonneg ~'parameter for sampling', +% A1:nonneg ~'parameter for sampling', +% B0:nonneg ~'parameter for sampling', +% L:natural ~'number of transmats to sample' +% -> mt_system. +% +% Initial system contains no transition matrices - you +% must call mt_ensure with a particular value of K +% to sample a set of L transition matrices of that size. +% +% Initial calibration is equivalent to: +% sys=mt_calibrate(sys, 1:3, [0,1,0;0,0,1]); +% +% The figure for scatter plots is fixed to figure 50 for now. + +function Sys=mt_init(A0,B0,A1,B1,L) + Sys.sample_transmats = @(k)sample_transmat_hdp(A0,B0,A1,B1,k,L); + Sys.transmats = {}; + Sys.info = {}; + Sys.refpoints = [0,0;1,0;0,1]'; + Sys.fig = 50; + Sys = mt_calibrate(Sys); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mt_resample.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,28 @@ +% mt_resample - Sample or resample melody triangle transition matrices of given size +% +% mt_resample :: +% mt_system ~'initial system' +% natural ~'size of transition matrices to resample' +% -> action mt_system. +% +% A new set of transition matrices will be sampled and a 3D information space +% scatter plot generated in the figure determined by the initial call to +% mt_init. + +function Sys=mt_resample(Sys,K) + [TT, II] = Sys.sample_transmats(K); + figure(Sys.fig); % 'name','info space'); + Sys.transmats{K} = TT; + Sys.info{K} = II; + Sys.hScat{K} = scatc(II,II(:,3),16); + axis on; box on; grid off; + lc=[0.4,0.4,0.4]; + set(gca,'Color','none'); + set(gca,'XColor',lc); + set(gca,'YColor',lc); + set(gca,'ZColor',lc); + xlabel('entropy rate'); + ylabel('redundancy'); + zlabel('pred-info rate'); + rotate3d on; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mt_show_transmat.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,11 @@ +% mt_show_transmat - Display image of transition matrix for voice +% +% mt_show_transmat :: +% natural ~'voice id' +% [[K,K]] ~'transition matrix' +% -> action void. + +function mt_show_transmat(Id,T) + figure(Id); + imagesc(T,[0,1]); + axis xy;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/private/mc_fixpt.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,34 @@ +function p=mc_fixpt(Pt) +% mc_fixpt - fixed point of Markov chain (stationary state distribution) +% +% mc_fixpt :: [[K,K]]~'transition matrix'-> [[K]]. + + +% for ergodic HMM we want to get stationary distribution +% use eigenvalues of transition matrix. +[V,D]=eig(Pt); + +% one of the eigenvalues should be 1 +[dummy,k]=max(-abs(diag(D)-1)); + +% check that it is really close +if abs(D(k,k)-1)>0.001 + disp('mc_fixpt: failed to find eigenvalue of 1 in '); + disp(Pt) + error('mc_fixpt:noeig','failed to find eigenvalue of 1'); +end + +% get eigenvector and flip it over if all negative +v=V(:,k); if sum(v)<0, v=-v; end + +if ~isreal(v) + disp('mc_fixpt: discarding complex parts of eigenvector'); + v=real(v); +end +if any(v<0) + %fprintf('mc_fixpt: discarding negative parts of eigenvector: %s\n',mat2str(v(v<0))); + v=max(0,v); +end + +% final normalisation +p=v/sum(v);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/private/mc_global_info.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,55 @@ +function Info=mc_global_info(T,pz) +% mc_global_info - Three global information measures about stationary MC +% +% mc_global_info :: [[N,N]] ~'transmat' -> [[3]]. +% +% mc_global_info :: +% [[N,N]] ~'transmat', +% [[N]] ~'stationary distribution if already known' +% -> [[3]]. +% +% The three measures in order are +% Entropy rate H(X|Z) +% Redundancy I(X,Z) +% Predictive information rate I(X,Y|Z) + + +n=size(T,1); +if nargin<2, pz=mc_fixpt(T); end +TlogT=T.*slog(T); +HXZ=-sum(TlogT,1)*pz; + +pxz=T; % p(x|z) +pyxz=repmat(T,[1,1,n]).*repmat(shiftdim(T,-1),[n,1,1]); % p(y,x|z) +pyz=sum(pyxz,2); % p(y|z) +pyz(pyz==0)=realmin; +pxyz=permute(pyxz./repmat(pyz,[1,n,1]),[2,1,3]); % p(x|y,z) + +HXYz=-shiftdim(sum(sum(permute(pyxz,[2,1,3]).*slog(pxyz),1),2),2); % H(X|Y,z) +IXYZ=(-HXYz' - sum(pxz.*slog(pxz)))*pz; + +IXZ=max(0,(sum(TlogT)-slog(pz)')*pz); + + +Info=[HXZ;IXZ;IXYZ]; +if any(~isreal(Info)) + disp('unreal information'); + keyboard +elseif any(Info<0) + if any(Info<-eps) + disp('negative information'); + disp(Info); + keyboard + else + Info=max(0,Info); + end +end + +function y=slog(x) +% slog - safe log, x<=0 => slog(x)=0 +% +% slog :: real -> real. + + x(x<=0)=1; + y=log(x); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/private/sample_transmat_hdp.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,58 @@ +function [T,I]=sample_transmat_hdp(A0,B0,A1,B1,K,L,T0) +% sample_transmat_hdp - Sample 1st order Markov transition matrix using HDP +% +% sample_transmat_hdp :: +% nonneg ~'Shape parameter for base Dirichlet Gamma prior', +% nonneg ~'Scale parameter for base Dirichlet Gamma prior', +% nonneg ~'Shape parameter for sub Dirichlet Gamma prior', +% nonneg ~'Scale parameter for sub Dirichlet Gamma prior', +% natural ~'size of alphabet', +% natural ~'num of transition matrices to produce', +% -> [[K,K,L]] ~ 'lots of transition matrices', +% [[L,3]] ~ 'entropy rate, redundancy, and predinfo rate for all'. +% +% An extra optional argument of type [[K,K]] can be added, which +% is used as a sort of bias for the sampled matrices. + + if nargin<7, T0=ones(K,K); end + + Alpha0=gamrnd(A0,B0,1,1,L); + Alpha1=gamrnd(A1,B1,1,1,L); + + + % base distributions + H0=sample_dir(repmat(Alpha0/K,[K,1,1])); + HT=stoch(repmat(H0,[1,K,1])).*repmat(T0/sum(T0(:)),[1,1,L]); + T=sample_dir(repmat(Alpha1,[K,K,1]).*HT); + + if any(sum(H0)<0.99) + disp('normalisation problem in H') + keyboard + end + if nargout>=2 + I=zeros(K,3); + for i=1:L + I(i,:)=mc_global_info(T(:,:,i)); + end + end +end + +% taken from stats/models/dirichlet.m>stoch_gamma +function y=sample_dir(beta) + x=randg(beta); + z=sum(x,1); + y=x./repmat(z,size(x,1),1); + bad=find(z==0); + for i=1:length(bad) + beta_i=beta(:,bad(i)); % misbehaving params + k=(beta_i==max(beta_i)); % entries with max beta + y(:,bad(i))=mnrnd(1,stoch(k)); + end +end + +function [Y,Z]=stoch(X), + Z=sum(X,1); + Y=X./repmat(Z,size(X,1),1); +end + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/private/scatc.m Wed Feb 01 14:06:37 2012 +0000 @@ -0,0 +1,43 @@ +function h=scatc(x,C,S,varargin) +% scatc - 2 or 3D scatter plot with colours and sizes +% +% scatc :: [[N,E]] ~'N points in E space', [[N]]~'colours' -> handle. +% scatc :: +% [[N,E]] ~'N points in E space', +% [[N]] ~'colours', +% [[N]] | real ~'array of sizes or single marker size' +% -> handle. +% +% If E<3, does 2D scatter, otherwise, does 3D scatter plot. +% Draws filled circles. + +if size(x,2)<=4 && size(x,1)>4, x=x'; end +if nargin<3 || isempty(S), + % use default marker size + S=get(gca,'DefaultLineMarkerSize').^2; +elseif length(S)==1, + S=S*ones(size(x,2),1); +end + +if size(x,1)<3, + h=scatter(x(1,:),x(2,:),S,C); +else + h=scatter3(x(1,:),x(2,:),x(3,:),S,C); +end + +set(h, ... + 'MarkerFaceColor','flat', ... + 'MarkerEdgeColor','k', ... + 'LineWidth',0.2, ... + varargin{:}); + +axis equal; +if size(x,1)>2 + axis vis3d; + axis off; + set(gca,'DrawMode','fast'); + set(gca,'Projection','perspective'); +else + box on; + % axis off; +end