annotate yeti/silvet.yeti @ 25:80f02ff5d37a

I think that previous normalisation was wrong!
author Chris Cannam
date Mon, 31 Mar 2014 15:41:15 +0100
parents 0e8ee830b5ee
children fbc4011c7693
rev   line source
Chris@12 1
Chris@12 2 program silvet;
Chris@12 3
Chris@12 4 { prepareTimeFrequency } = load timefreq;
Chris@13 5 { loadTemplates, extractRanges } = load templates;
Chris@14 6
Chris@14 7 em = load em;
Chris@19 8 em1 = load em_onecolumn;
Chris@12 9
Chris@12 10 mat = load may.matrix;
Chris@12 11 vec = load may.vector;
Chris@14 12 plot = load may.plot;
Chris@12 13
Chris@12 14 templates = loadTemplates ();
Chris@12 15
Chris@13 16 ranges = extractRanges templates;
Chris@13 17
Chris@13 18 eprintln "\nWe have \(length (keys templates)) instruments:";
Chris@13 19 for (sort (keys templates)) do k:
Chris@14 20 eprintln " * \(k) \(mat.size templates[k]) range \(ranges[k].lowest) -> \(ranges[k].highest)";
Chris@13 21 done;
Chris@12 22 eprintln "";
Chris@12 23
Chris@12 24 columns = prepareTimeFrequency "test.wav";
Chris@12 25
Chris@19 26 /*
Chris@12 27 height = if empty? columns then 0 else vec.length (head columns) fi;
Chris@12 28
Chris@13 29 chunkSize = { rows = height, columns = 100 };
Chris@13 30
Chris@14 31 emdata = em.initialise ranges templates 88 chunkSize;
Chris@13 32
Chris@14 33 eprintln "initialised EM data: overall pitch range \(emdata.lowest) -> \(emdata.highest)";
Chris@13 34
Chris@12 35 chunkify cols =
Chris@12 36 if empty? cols then []
Chris@12 37 else
Chris@13 38 (mat.resizedTo chunkSize
Chris@13 39 (mat.fromColumns (take chunkSize.columns cols)))
Chris@13 40 :. \(chunkify (drop chunkSize.columns cols));
Chris@12 41 fi;
Chris@12 42
Chris@12 43 chunks = chunkify columns;
Chris@12 44
Chris@12 45 eprintln "we have \(length chunks) chunks of size \(mat.size (head chunks))";
Chris@12 46
Chris@14 47 eprintln "attempting one expectation phase...";
Chris@13 48
Chris@14 49 error = em.performExpectation emdata (head chunks);
Chris@14 50
Chris@14 51 eprintln "done, result has dimension \(mat.size error)";
Chris@14 52
Chris@14 53 eprintln "attempting one maximisation phase...";
Chris@14 54
Chris@14 55 newP = em.performMaximisation emdata (head chunks) error;
Chris@14 56
Chris@14 57 eprintln "done";
Chris@14 58
Chris@14 59 \() (plot.plot [ Grid (head chunks) ]);
Chris@14 60 \() (plot.plot [ Grid error ]);
Chris@14 61
Chris@14 62 \() (plot.plot [ Grid newP ]);
Chris@19 63 */
Chris@19 64
Chris@19 65 em1data = em1.initialise ranges templates 88;
Chris@19 66
Chris@23 67 col = head (drop 50 columns); // (drop ((length columns) / 2) columns);
Chris@19 68
Chris@20 69 \() (plot.plot [ Caption "Source frequency distribution", Vector col ]);
Chris@19 70
Chris@22 71 \() (plot.plot [ Caption "Source distribution beforehand", Grid em1data.sources]);
Chris@20 72
Chris@25 73 normalise v =
Chris@25 74 (s = vec.sum v;
Chris@25 75 if s > 0 then vec.divideBy s v
Chris@25 76 else v
Chris@25 77 fi);
Chris@25 78
Chris@20 79 oneIteration em1data col n =
Chris@25 80 ({ estimate, q } = em1.performExpectation em1data col;
Chris@20 81 // \() (plot.plot [ Caption "Frequency distribution and output of E-step for iteration \(n)", Vector col, Vector q ]);
Chris@19 82 newdata = em1.performMaximisation em1data col q;
Chris@21 83 if (n % 6 == 0) then
Chris@20 84 \() (plot.plot [ Caption "Pitch distribution before and after M-step update for iteration \(n)", Vector (em1data.pitches), Vector (newdata.pitches) ]);
Chris@22 85 \() (plot.plot [ Caption "Source distribution after M-step update for iteration \(n)", Grid newdata.sources ]);
Chris@25 86 \() (plot.plot [ Caption "Q function for E-step iteration \(n)", Vector q ]);
Chris@25 87 \() (plot.plot [ Caption "Estimate from E-step iteration \(n) against original source distribution, and difference between them", Vector estimate, Vector (normalise col), Vector (vec.subtract estimate (normalise col)) ]);
Chris@20 88 fi;
Chris@19 89 newdata);
Chris@19 90
Chris@21 91 iterations = 12;
Chris@19 92
Chris@20 93 var d = em1data;
Chris@20 94
Chris@20 95 for [1..iterations] do i:
Chris@20 96 d := oneIteration d col i;
Chris@20 97 done;
Chris@14 98
Chris@21 99 var sounding = [];
Chris@21 100
Chris@22 101 println "pitch distribution: \(vec.list d.pitches)";
Chris@21 102
Chris@21 103 for [d.lowest .. d.highest] do p:
Chris@21 104 if (vec.at d.pitches p) > 0.05 then
Chris@21 105 sounding := sounding ++ [p];
Chris@21 106 fi;
Chris@21 107 done;
Chris@21 108
Chris@21 109 println "Sounding: \(sounding)";
Chris@21 110
Chris@21 111 toNote p = (array ["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"])[p % 12];
Chris@21 112
Chris@21 113 println "Notes: \(map toNote sounding)";
Chris@21 114
Chris@21 115 var instruments = [];
Chris@21 116 for sounding do p:
Chris@22 117 var best = 0;
Chris@21 118 var bestp = 0;
Chris@22 119 for [0..d.instCount-1] do i:
Chris@22 120 if mat.at d.sources p i > bestp then
Chris@22 121 bestp := mat.at d.sources p i;
Chris@21 122 best := i;
Chris@21 123 fi;
Chris@21 124 done;
Chris@21 125 if bestp > 0 then
Chris@21 126 instruments := instruments ++ [best];
Chris@21 127 else
Chris@22 128 instruments := instruments ++ [-1];
Chris@21 129 fi;
Chris@21 130 done;
Chris@21 131
Chris@22 132 println "Instruments: \(map do i: (d.instruments[i]) done instruments)";
Chris@21 133
Chris@24 134 if not (empty? sounding) then
Chris@24 135 p = head sounding;
Chris@24 136 i = head instruments;
Chris@24 137 w = mat.getColumn p d.templates[i];
Chris@24 138 \() (plot.plot [ Vector w, Vector (normalise col), Caption "Template for instrument \(d.instruments[i]), pitch \(p), against normalised source distribution" ]);
Chris@24 139 fi;
Chris@21 140
Chris@14 141 ();
Chris@14 142
Chris@14 143