comparison src/Modules/Features/ModuleGaussians.cc @ 162:9fcf55c040fe

- Added property svn:eol-style native to all text files
author tomwalters
date Thu, 22 Jul 2010 04:14:20 +0000
parents f03d4455b262
children c155e7fbe76e
comparison
equal deleted inserted replaced
161:0420c86456c1 162:9fcf55c040fe
24 * \date created 2008/06/23 24 * \date created 2008/06/23
25 * \version \$Id$ 25 * \version \$Id$
26 */ 26 */
27 27
28 #include <math.h> 28 #include <math.h>
29
30 #ifdef _WINDOWS
31 #include <float.h>
32 #endif
33 29
34 #include "Modules/Features/ModuleGaussians.h" 30 #include "Modules/Features/ModuleGaussians.h"
35 #include "Support/Common.h" 31 #include "Support/Common.h"
36 32
37 namespace aimc { 33 namespace aimc {
40 module_description_ = "Gaussian Fitting to SSI profile"; 36 module_description_ = "Gaussian Fitting to SSI profile";
41 module_identifier_ = "gaussians"; 37 module_identifier_ = "gaussians";
42 module_type_ = "features"; 38 module_type_ = "features";
43 module_version_ = "$Id$"; 39 module_version_ = "$Id$";
44 40
45 m_iParamNComp = parameters_->DefaultInt("gaussians.ncomp", 4); 41 m_iParamNComp = parameters_->DefaultInt("features.gaussians.ncomp", 4);
46 m_fParamVar = parameters_->DefaultFloat("gaussians.var", 115.0); 42 m_fParamVar = parameters_->DefaultFloat("features.gaussians.var", 115.0);
47 m_fParamPosteriorExp = parameters_->DefaultFloat("gaussians.posterior_exp", 43 m_fParamPosteriorExp =
48 6.0); 44 parameters_->DefaultFloat("features.gaussians.posterior_exp", 6.0);
49 m_iParamMaxIt = parameters_->DefaultInt("gaussians.maxit", 250); 45 m_iParamMaxIt = parameters_->DefaultInt("features.gaussians.maxit", 250);
50 46
51 // The parameters system doesn't support tiny numbers well, to define this 47 // The parameters system doesn't support tiny numbers well, to define this
52 // variable as a string, then convert it to a float afterwards 48 // variable as a string, then convert it to a float afterwards
53 parameters_->DefaultString("gaussians.priors_converged", "1e-7"); 49 parameters_->DefaultString("features.gaussians.priors_converged", "1e-7");
54 priors_converged_ = parameters_->GetFloat("gaussians.priors_converged"); 50 m_fParamPriorsConverged =
55 output_positions_ = parameters_->DefaultBool("gaussians.positions", false); 51 parameters_->GetFloat("features.gaussians.priors_converged");
56 } 52 }
57 53
58 ModuleGaussians::~ModuleGaussians() { 54 ModuleGaussians::~ModuleGaussians() {
59 } 55 }
60 56
62 m_pA.resize(m_iParamNComp, 0.0f); 58 m_pA.resize(m_iParamNComp, 0.0f);
63 m_pMu.resize(m_iParamNComp, 0.0f); 59 m_pMu.resize(m_iParamNComp, 0.0f);
64 60
65 // Assuming the number of channels is greater than twice the number of 61 // Assuming the number of channels is greater than twice the number of
66 // Gaussian components, this is ok 62 // Gaussian components, this is ok
67 output_component_count_ = 1; // Energy component
68 if (input.channel_count() >= 2 * m_iParamNComp) { 63 if (input.channel_count() >= 2 * m_iParamNComp) {
69 output_component_count_ += (m_iParamNComp - 1); 64 output_.Initialize(m_iParamNComp, 1, input.sample_rate());
70 } else { 65 } else {
71 LOG_ERROR(_T("Too few channels in filterbank to produce sensible " 66 LOG_ERROR(_T("Too few channels in filterbank to produce sensible "
72 "Gaussian features. Either increase the number of filterbank" 67 "Gaussian features. Either increase the number of filterbank"
73 " channels, or decrease the number of Gaussian components")); 68 " channels, or decrease the number of Gaussian components"));
74 return false; 69 return false;
75 } 70 }
76
77 if (output_positions_) {
78 output_component_count_ += m_iParamNComp;
79 }
80
81 output_.Initialize(output_component_count_, 1, input.sample_rate());
82 71
83 m_iNumChannels = input.channel_count(); 72 m_iNumChannels = input.channel_count();
84 m_pSpectralProfile.resize(m_iNumChannels, 0.0f); 73 m_pSpectralProfile.resize(m_iNumChannels, 0.0f);
85 74
86 return true; 75 return true;
98 void ModuleGaussians::Process(const SignalBank &input) { 87 void ModuleGaussians::Process(const SignalBank &input) {
99 if (!initialized_) { 88 if (!initialized_) {
100 LOG_ERROR(_T("Module ModuleGaussians not initialized.")); 89 LOG_ERROR(_T("Module ModuleGaussians not initialized."));
101 return; 90 return;
102 } 91 }
103 output_.set_start_time(input.start_time());
104 // Calculate spectral profile 92 // Calculate spectral profile
105 for (int ch = 0; ch < input.channel_count(); ++ch) { 93 for (int iChannel = 0;
106 m_pSpectralProfile[ch] = 0.0f; 94 iChannel < input.channel_count();
107 for (int i = 0; i < input.buffer_length(); ++i) { 95 ++iChannel) {
108 m_pSpectralProfile[ch] += input[ch][i]; 96 m_pSpectralProfile[iChannel] = 0.0f;
109 } 97 for (int iSample = 0;
110 m_pSpectralProfile[ch] /= static_cast<float>(input.buffer_length()); 98 iSample < input.buffer_length();
99 ++iSample) {
100 m_pSpectralProfile[iChannel] += input[iChannel][iSample];
101 }
102 m_pSpectralProfile[iChannel] /= static_cast<float>(input.buffer_length());
111 } 103 }
112 104
113 float spectral_profile_sum = 0.0f; 105 float spectral_profile_sum = 0.0f;
114 for (int i = 0; i < input.channel_count(); ++i) { 106 for (int i = 0; i < input.channel_count(); ++i) {
115 spectral_profile_sum += m_pSpectralProfile[i]; 107 spectral_profile_sum += m_pSpectralProfile[i];
116 } 108 }
117 109
118 // Set the last component of the feature vector to be the log energy
119 float logsum = log(spectral_profile_sum); 110 float logsum = log(spectral_profile_sum);
120 if (!isinf(logsum)) { 111 if (!isinf(logsum)) {
121 output_.set_sample(output_component_count_ - 1, 0, logsum); 112 output_.set_sample(m_iParamNComp - 1, 0, logsum);
122 } else { 113 } else {
123 output_.set_sample(output_component_count_ - 1, 0, -1000.0); 114 output_.set_sample(m_iParamNComp - 1, 0, -1000.0);
124 } 115 }
125 116
126 for (int ch = 0; ch < input.channel_count(); ++ch) { 117 for (int iChannel = 0;
127 m_pSpectralProfile[ch] = pow(m_pSpectralProfile[ch], 0.8f); 118 iChannel < input.channel_count();
119 ++iChannel) {
120 m_pSpectralProfile[iChannel] = pow(m_pSpectralProfile[iChannel], 0.8);
128 } 121 }
129 122
130 RubberGMMCore(2, true); 123 RubberGMMCore(2, true);
131 124
132 float mean1 = m_pMu[0]; 125 float fMean1 = m_pMu[0];
133 float mean2 = m_pMu[1]; 126 float fMean2 = m_pMu[1];
134 // LOG_INFO(_T("Orig. mean 0 = %f"), m_pMu[0]); 127 // LOG_INFO(_T("Orig. mean 0 = %f"), m_pMu[0]);
135 // LOG_INFO(_T("Orig. mean 1 = %f"), m_pMu[1]); 128 // LOG_INFO(_T("Orig. mean 1 = %f"), m_pMu[1]);
136 // LOG_INFO(_T("Orig. prob 0 = %f"), m_pA[0]); 129 // LOG_INFO(_T("Orig. prob 0 = %f"), m_pA[0]);
137 // LOG_INFO(_T("Orig. prob 1 = %f"), m_pA[1]); 130 // LOG_INFO(_T("Orig. prob 1 = %f"), m_pA[1]);
138 131
139 float a1 = 0.05 * m_pA[0]; 132 float fA1 = 0.05 * m_pA[0];
140 float a2 = 1.0 - 0.25 * m_pA[1]; 133 float fA2 = 1.0 - 0.25 * m_pA[1];
141 134
142 // LOG_INFO(_T("fA1 = %f"), fA1); 135 // LOG_INFO(_T("fA1 = %f"), fA1);
143 // LOG_INFO(_T("fA2 = %f"), fA2); 136 // LOG_INFO(_T("fA2 = %f"), fA2);
144 137
145 float gradient = (mean2 - mean1) / (a2 - a1); 138 float fGradient = (fMean2 - fMean1) / (fA2 - fA1);
146 float intercept = mean2 - gradient * a2; 139 float fIntercept = fMean2 - fGradient * fA2;
147 140
148 // LOG_INFO(_T("fGradient = %f"), fGradient); 141 // LOG_INFO(_T("fGradient = %f"), fGradient);
149 // LOG_INFO(_T("fIntercept = %f"), fIntercept); 142 // LOG_INFO(_T("fIntercept = %f"), fIntercept);
150 143
151 for (int i = 0; i < m_iParamNComp; ++i) { 144 for (int i = 0; i < m_iParamNComp; ++i) {
152 m_pMu[i] = (static_cast<float>(i) 145 m_pMu[i] = (static_cast<float>(i)
153 / (static_cast<float>(m_iParamNComp) - 1.0f)) 146 / (static_cast<float>(m_iParamNComp) - 1.0f))
154 * gradient + intercept; 147 * fGradient + fIntercept;
155 // LOG_INFO(_T("mean %d = %f"), i, m_pMu[i]); 148 // LOG_INFO(_T("mean %d = %f"), i, m_pMu[i]);
156 } 149 }
157 150
158 for (int i = 0; i < m_iParamNComp; ++i) { 151 for (int i = 0; i < m_iParamNComp; ++i) {
159 m_pA[i] = 1.0f / static_cast<float>(m_iParamNComp); 152 m_pA[i] = 1.0f / static_cast<float>(m_iParamNComp);
160 } 153 }
161 154
162 RubberGMMCore(m_iParamNComp, false); 155 RubberGMMCore(m_iParamNComp, false);
163 156
164 // Amplitudes first
165 for (int i = 0; i < m_iParamNComp - 1; ++i) { 157 for (int i = 0; i < m_iParamNComp - 1; ++i) {
166 if (!isnan(m_pA[i])) { 158 if (!isnan(m_pA[i])) {
167 output_.set_sample(i, 0, m_pA[i]); 159 output_.set_sample(i, 0, m_pA[i]);
168 } else { 160 } else {
169 output_.set_sample(i, 0, 0.0f); 161 output_.set_sample(i, 0, 0.0f);
170 } 162 }
171 } 163 }
172 164
173 // Then means if required
174 if (output_positions_) {
175 int idx = 0;
176 for (int i = m_iParamNComp - 1; i < 2 * m_iParamNComp - 1; ++i) {
177 if (!isnan(m_pMu[i])) {
178 output_.set_sample(i, 0, m_pMu[idx]);
179 } else {
180 output_.set_sample(i, 0, 0.0f);
181 }
182 ++idx;
183 }
184 }
185
186 PushOutput(); 165 PushOutput();
187 } 166 }
188 167
189 bool ModuleGaussians::RubberGMMCore(int iNComponents, bool bDoInit) { 168 bool ModuleGaussians::RubberGMMCore(int iNComponents, bool bDoInit) {
190 int iSizeX = m_iNumChannels; 169 int iSizeX = m_iNumChannels;
191 170
192 // Normalise the spectral profile 171 // Normalise the spectral profile
193 float SpectralProfileTotal = 0.0f; 172 float fSpectralProfileTotal = 0.0f;
194 for (int iCount = 0; iCount < iSizeX; iCount++) { 173 for (int iCount = 0; iCount < iSizeX; iCount++) {
195 SpectralProfileTotal += m_pSpectralProfile[iCount]; 174 fSpectralProfileTotal += m_pSpectralProfile[iCount];
196 } 175 }
197 for (int iCount = 0; iCount < iSizeX; iCount++) { 176 for (int iCount = 0; iCount < iSizeX; iCount++) {
198 m_pSpectralProfile[iCount] /= SpectralProfileTotal; 177 m_pSpectralProfile[iCount] /= fSpectralProfileTotal;
199 } 178 }
200 179
201 if (bDoInit) { 180 if (bDoInit) {
202 // Uniformly spaced components 181 // Uniformly spaced components
203 float dd = (iSizeX - 1.0f) / iNComponents; 182 float dd = (iSizeX - 1.0f) / iNComponents;
219 // denominator: the model density at all observation points X 198 // denominator: the model density at all observation points X
220 for (int i = 0; i < iSizeX; ++i) { 199 for (int i = 0; i < iSizeX; ++i) {
221 pP_mod_X[i] = 0.0f; 200 pP_mod_X[i] = 0.0f;
222 } 201 }
223 202
224 for (int c = 0; c < iNComponents; c++) { 203 for (int i = 0; i < iNComponents; i++) {
225 for (int iCount = 0; iCount < iSizeX; iCount++) { 204 for (int iCount = 0; iCount < iSizeX; iCount++) {
226 pP_mod_X[iCount] += 1.0f / sqrt(2.0f * M_PI * m_fParamVar) 205 pP_mod_X[iCount] += 1.0f / sqrt(2.0f * M_PI * m_fParamVar)
227 * exp((-0.5f) 206 * exp((-0.5f)
228 * pow(static_cast<float>(iCount+1) - m_pMu[c], 2) 207 * pow(static_cast<float>(iCount+1) - m_pMu[i], 2)
229 / m_fParamVar) * m_pA[c]; 208 / m_fParamVar) * m_pA[i];
230 } 209 }
231 } 210 }
232 211
233 for (int i = 0; i < iSizeX * iNComponents; ++i) { 212 for (int i = 0; i < iSizeX * iNComponents; ++i) {
234 pP_comp[i] = 0.0f; 213 pP_comp[i] = 0.0f;
270 for (int i = 0; i < iNComponents; ++i) { 249 for (int i = 0; i < iNComponents; ++i) {
271 fPrdist += pow((m_pA[i] - pA_old[i]), 2); 250 fPrdist += pow((m_pA[i] - pA_old[i]), 2);
272 } 251 }
273 fPrdist /= iNComponents; 252 fPrdist /= iNComponents;
274 253
275 if (fPrdist < priors_converged_) { 254 if (fPrdist < m_fParamPriorsConverged) {
276 // LOG_INFO("Converged!"); 255 // LOG_INFO("Converged!");
277 break; 256 break;
278 } 257 }
279 // LOG_INFO("Didn't converge!"); 258 // LOG_INFO("Didn't converge!");
280 259