wolffd@0: function draw_hmm(A, varargin) wolffd@0: % DRAW_HMM Make a picture of the HMM using dotty wolffd@0: % function draw_hmm(A, ...) wolffd@0: % wolffd@0: % For details on dotty, see http://www.research.att.com/sw/tools/graphviz wolffd@0: % wolffd@0: % If A(i,j) > thresh, we draw and arc from state i to state j. wolffd@0: % wolffd@0: % Optional arguments (name/value pairs) [default] wolffd@0: % wolffd@0: % thresh - [1e-1] wolffd@0: % obsprob - If B(i,o) > 0, we include "o" in the name of state i. wolffd@0: % e.g., if state 5 emits 1,3,7, its label becomes "5: 1 3 7". wolffd@0: % startprob - ifstartprob(i) > 0, the state name will be prefixed with "+". wolffd@0: % endprob - if endprob(i) > 0, the state name will be appended with "-". wolffd@0: % filename - if [], we write to 'tmp.dot', convert this to 'tmp.ps' wolffd@0: % using 'dot -Tps tmp.dot -o tmp.ps', and then call ghostview to display the result. wolffd@0: % dot and gv must be on your system path. wolffd@0: % If filename ~= [], we just generate the dot file, and do not wolffd@0: % convert it to postscript or call ghostview. wolffd@0: wolffd@0: [thresh, B, startprob, endprob, filename] = ... wolffd@0: process_options(varargin, 'thresh', 1e-1, 'obsprob', [], 'startprob', [], 'endprob', [], ... wolffd@0: 'filename', []); wolffd@0: wolffd@0: Q = length(A); wolffd@0: wolffd@0: arclabel = cell(Q,Q); wolffd@0: G = zeros(Q,Q); wolffd@0: for i=1:Q wolffd@0: for j=1:Q wolffd@0: if A(i,j) < thresh wolffd@0: arclabel{i,j} = ''; wolffd@0: else wolffd@0: G(i,j) = 1; wolffd@0: arclabel{i,j} = sprintf('%5.3f', A(i,j)); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: wolffd@0: nodelabel = cell(1,Q); wolffd@0: for i=1:Q wolffd@0: % annotate start/stop states wolffd@0: if ~isempty(startprob) & ~approxeq(startprob(i), 0) wolffd@0: start = '+'; wolffd@0: else wolffd@0: start = ''; wolffd@0: end wolffd@0: if ~isempty(endprob) & ~approxeq(hmm.endprob(i), 0) wolffd@0: stop = '-'; wolffd@0: else wolffd@0: stop = ''; wolffd@0: end wolffd@0: label = sprintf('%s%d%s :', start, i, stop); wolffd@0: wolffd@0: if ~isempty(B) wolffd@0: output_label = mk_output_label(B); wolffd@0: label = strcat(label, output_label); wolffd@0: end wolffd@0: wolffd@0: nodelabel{i} = label; wolffd@0: end wolffd@0: wolffd@0: wolffd@0: if isempty(filename) wolffd@0: filename = 'tmp.dot'; wolffd@0: %mkdot(G, filename, arclabel, nodelabel) wolffd@0: graph_to_dot(G, 'filename', filename, 'arc_label', arclabel, 'node_label', nodelabel); wolffd@0: fprintf('converting from .ps to .dot\n') wolffd@0: !dot -Tps tmp.dot -o tmp.ps wolffd@0: !gv tmp.ps & wolffd@0: else wolffd@0: graph_to_dot(G, 'filename', filename, 'arc_label', arclabel, 'node_label', nodelabel); wolffd@0: %mkdot(G, filename, arclabel, nodelabel) wolffd@0: end wolffd@0: wolffd@0: wolffd@0: %%%%%%%%% wolffd@0: wolffd@0: function label = mk_output_label(B) wolffd@0: wolffd@0: [Q O] = size(B); wolffd@0: label = ''; wolffd@0: wolffd@0: if 0 wolffd@0: % print most probable symbols wolffd@0: for i=1:Q wolffd@0: m = max(B(i,:)); wolffd@0: ndx = find(abs(B(i,:) - repmat(m,1,O)) < 1e-2); wolffd@0: %ndx = find(B(i,:)==m); wolffd@0: %label = sprintf('%d,', ndx); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: if 0 wolffd@0: % print prob distrib over all symbols wolffd@0: for o=1:O wolffd@0: if approxeq(B(i,o), 0) wolffd@0: % wolffd@0: else wolffd@0: label = strcat(label, sprintf('%d(%3.2f),', o, B(i,o))); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: if 1 wolffd@0: % print all non-zero symbols wolffd@0: chars = ['a' 'b' 'c']; wolffd@0: for o=1:O wolffd@0: if approxeq(B(i,o), 0) wolffd@0: % wolffd@0: else wolffd@0: label = strcat(label, sprintf('%s', chars(o))); wolffd@0: end wolffd@0: end wolffd@0: end