Mercurial > hg > silvet
comparison src/EM.cpp @ 92:81eaba98985b bqvec
Complete using bqvec for allocation etc, but with unchanged processing logic
| author | Chris Cannam |
|---|---|
| date | Tue, 06 May 2014 14:19:19 +0100 |
| parents | 2b0818a1c058 |
| children | 891cbcf1e4d2 |
comparison
equal
deleted
inserted
replaced
| 91:2b0818a1c058 | 92:81eaba98985b |
|---|---|
| 66 m_q = allocate<double>(m_binCount); | 66 m_q = allocate<double>(m_binCount); |
| 67 } | 67 } |
| 68 | 68 |
| 69 EM::~EM() | 69 EM::~EM() |
| 70 { | 70 { |
| 71 deallocate(m_q); | |
| 72 deallocate(m_estimate); | |
| 73 deallocate_channels(m_sources, m_sourceCount); | |
| 74 deallocate_channels(m_shifts, m_shiftCount); | |
| 75 deallocate(m_pitches); | |
| 71 } | 76 } |
| 72 | 77 |
| 73 void | 78 void |
| 74 EM::rangeFor(int instrument, int &minPitch, int &maxPitch) | 79 EM::rangeFor(int instrument, int &minPitch, int &maxPitch) |
| 75 { | 80 { |
| 84 rangeFor(instrument, minPitch, maxPitch); | 89 rangeFor(instrument, minPitch, maxPitch); |
| 85 return (pitch >= minPitch && pitch <= maxPitch); | 90 return (pitch >= minPitch && pitch <= maxPitch); |
| 86 } | 91 } |
| 87 | 92 |
| 88 void | 93 void |
| 89 EM::normaliseColumn(V &column) | 94 EM::normaliseColumn(double *column, int size) |
| 90 { | 95 { |
| 91 double sum = 0.0; | 96 double sum = v_sum(column, size); |
| 92 for (int i = 0; i < (int)column.size(); ++i) { | 97 v_scale(column, 1.0 / sum, size); |
| 93 sum += column[i]; | 98 } |
| 94 } | 99 |
| 95 for (int i = 0; i < (int)column.size(); ++i) { | 100 void |
| 96 column[i] /= sum; | 101 EM::normaliseGrid(double **grid, int size1, int size2) |
| 97 } | 102 { |
| 98 } | 103 double *denominators = allocate_and_zero<double>(size2); |
| 99 | 104 |
| 100 void | 105 for (int i = 0; i < size1; ++i) { |
| 101 EM::normaliseGrid(Grid &grid) | 106 for (int j = 0; j < size2; ++j) { |
| 102 { | |
| 103 V denominators(grid[0].size()); | |
| 104 | |
| 105 for (int i = 0; i < (int)grid.size(); ++i) { | |
| 106 for (int j = 0; j < (int)grid[i].size(); ++j) { | |
| 107 denominators[j] += grid[i][j]; | 107 denominators[j] += grid[i][j]; |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 | 110 |
| 111 for (int i = 0; i < (int)grid.size(); ++i) { | 111 for (int i = 0; i < size1; ++i) { |
| 112 for (int j = 0; j < (int)grid[i].size(); ++j) { | 112 v_divide(grid[i], denominators, size2); |
| 113 grid[i][j] /= denominators[j]; | 113 } |
| 114 } | 114 |
| 115 } | 115 deallocate(denominators); |
| 116 } | 116 } |
| 117 | 117 |
| 118 void | 118 void |
| 119 EM::iterate(V column) | 119 EM::iterate(const double *column) |
| 120 { | 120 { |
| 121 normaliseColumn(column); | 121 double *norm = allocate<double>(m_binCount); |
| 122 expectation(column); | 122 v_copy(norm, column, m_binCount); |
| 123 maximisation(column); | 123 normaliseColumn(norm, m_binCount); |
| 124 expectation(norm); | |
| 125 maximisation(norm); | |
| 124 } | 126 } |
| 125 | 127 |
| 126 const double * | 128 const double * |
| 127 EM::templateFor(int instrument, int note, int shift) | 129 EM::templateFor(int instrument, int note, int shift) |
| 128 { | 130 { |
| 129 return silvet_templates[instrument].data[note] + shift; | 131 return silvet_templates[instrument].data[note] + shift; |
| 130 } | 132 } |
| 131 | 133 |
| 132 void | 134 void |
| 133 EM::expectation(const V &column) | 135 EM::expectation(const double *column) |
| 134 { | 136 { |
| 135 // cerr << "."; | 137 // cerr << "."; |
| 136 | 138 |
| 137 for (int i = 0; i < m_binCount; ++i) { | 139 for (int i = 0; i < m_binCount; ++i) { |
| 138 m_estimate[i] = epsilon; | 140 m_estimate[i] = epsilon; |
| 157 m_q[i] = column[i] / m_estimate[i]; | 159 m_q[i] = column[i] / m_estimate[i]; |
| 158 } | 160 } |
| 159 } | 161 } |
| 160 | 162 |
| 161 void | 163 void |
| 162 EM::maximisation(const V &column) | 164 EM::maximisation(const double *column) |
| 163 { | 165 { |
| 164 V newPitches(m_noteCount, epsilon); | 166 double *newPitches = allocate<double>(m_noteCount); |
| 165 Grid newShifts(m_shiftCount, V(m_noteCount, epsilon)); | 167 v_set(newPitches, epsilon, m_noteCount); |
| 166 Grid newSources(m_sourceCount, V(m_noteCount, epsilon)); | 168 |
| 169 double **newShifts = allocate_channels<double>(m_shiftCount, m_noteCount); | |
| 170 for (int i = 0; i < m_shiftCount; ++i) { | |
| 171 v_set(newShifts[i], epsilon, m_noteCount); | |
| 172 } | |
| 173 | |
| 174 double **newSources = allocate_channels<double>(m_sourceCount, m_noteCount); | |
| 175 for (int i = 0; i < m_sourceCount; ++i) { | |
| 176 v_set(newSources[i], epsilon, m_noteCount); | |
| 177 } | |
| 167 | 178 |
| 168 for (int n = 0; n < m_noteCount; ++n) { | 179 for (int n = 0; n < m_noteCount; ++n) { |
| 169 | 180 |
| 170 const double pitch = m_pitches[n]; | 181 const double pitch = m_pitches[n]; |
| 171 | 182 |
| 208 newSources[i][n] = pow(newSources[i][n], m_sourceSparsity); | 219 newSources[i][n] = pow(newSources[i][n], m_sourceSparsity); |
| 209 } | 220 } |
| 210 } | 221 } |
| 211 } | 222 } |
| 212 | 223 |
| 213 normaliseColumn(newPitches); | 224 normaliseColumn(newPitches, m_noteCount); |
| 214 normaliseGrid(newShifts); | 225 normaliseGrid(newShifts, m_shiftCount, m_noteCount); |
| 215 normaliseGrid(newSources); | 226 normaliseGrid(newSources, m_sourceCount, m_noteCount); |
| 227 | |
| 228 deallocate(m_pitches); | |
| 229 deallocate_channels(m_shifts, m_shiftCount); | |
| 230 deallocate_channels(m_sources, m_sourceCount); | |
| 216 | 231 |
| 217 m_pitches = newPitches; | 232 m_pitches = newPitches; |
| 218 m_shifts = newShifts; | 233 m_shifts = newShifts; |
| 219 m_sources = newSources; | 234 m_sources = newSources; |
| 220 } | 235 } |
