DHMM_HQ.cpp
上传用户:avbj512
上传日期:2013-09-18
资源大小:6239k
文件大小:19k
源码类别:

DSP编程

开发平台:

Visual C++

  1. // DHMM_HQ.cpp:
  2. // Implementation of the DHMM_HQ Module.
  3. // That is the C rewritten
  4. // of previous Matlab DHMM program by HeQiang.
  5. //
  6. // Created 2001/08, By DongMing, MDSR.
  7. //
  8. //////////////////////////////////////////////////////////////////////
  9. #include "stdafx.h"
  10. #include "DHMM_HQ.h"
  11. #include "kwspot.h"
  12. #include <math.h>
  13. #include "DHMM_GL.h"
  14. extern PRO_CONFIG u_Pro_Config;
  15. #define VQ_TRAIN_CODE_BOOK_LOOP_TIME 40 // 设置VQ中K-mean的最大迭代次数
  16. // The best loop: 100, better than 80
  17. #define MODEL_TRAIN_CODE_BOOK_LOOP_TIME 32 // 设置模型训练时的最大迭代次数
  18. // 20, 40 are better
  19. //////////////////////////////////////////////////////////////////////
  20. // Private Function Head
  21. int DHMM_Model_Calculate_Gamma(WORD_SAMPLE * pu_Word_Sample, DHMM_MODEL * pu_DHMM_Model);
  22. //////////////////////////////////////////////////////////////////////
  23. // API functions
  24. int DHMM_VQ_Train_Code_Book_HQ(DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Word, int n_Code_Word_Num, int n_Code_Word_Dim,
  25.    DYNA_2DIM_DOUBLE_ARRAY d2dda_Initial_Code_Book, DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size)
  26. {
  27. int * pn_Initial_Code_Book_Index;
  28. int * pn_Code_Word_Min_Index; // 存储每个特征的最近类中心
  29. double * pd_Code_Word_Min_Distance; // 存储每个特征到最近类中心的距离
  30. int n_Loop_Index, n_Feature_Index, n_Code_Word_Index, n_Dim_Index;
  31. double dTmp;
  32. double d_Old_Distance, d_Distance; // 上次与此次的类内平均距离
  33. int nTmp;
  34. BOOL boolTmp;
  35. PRO_LOG("tVQ = HQ, loop = %4d.n", VQ_TRAIN_CODE_BOOK_LOOP_TIME);
  36. // 若设置初始码本,拷贝之
  37. if (d2dda_Initial_Code_Book != NULL)
  38. {
  39. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  40. {
  41. memcpy(d2dda_Code_Book[n_Code_Word_Index], d2dda_Initial_Code_Book[n_Code_Word_Index], sizeof(double) * n_Code_Word_Dim);
  42. }
  43. }
  44. // 若没有设置初始码本,则随机生成
  45. else
  46. {
  47. pn_Initial_Code_Book_Index = new int[n_Code_Book_Size];
  48. ASSERT(pn_Initial_Code_Book_Index);
  49. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  50. {
  51. do {
  52. pn_Initial_Code_Book_Index[n_Code_Word_Index] = int((double(rand()) / (double(RAND_MAX) + 1)) * n_Code_Word_Num);
  53. boolTmp = FALSE;
  54. for (nTmp = 0; nTmp < n_Code_Word_Index; nTmp++)
  55. {
  56. if (pn_Initial_Code_Book_Index[n_Code_Word_Index] == pn_Initial_Code_Book_Index[nTmp]) boolTmp = TRUE;
  57. }
  58. } while (boolTmp);
  59. }
  60. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  61. {
  62. memcpy(d2dda_Code_Book[n_Code_Word_Index], d2dda_Code_Word[pn_Initial_Code_Book_Index[n_Code_Word_Index]], sizeof(double) * n_Code_Word_Dim);
  63. }
  64. delete[] pn_Initial_Code_Book_Index;
  65. }
  66. pn_Code_Word_Min_Index = new int[n_Code_Word_Num];
  67. pd_Code_Word_Min_Distance = new double[n_Code_Word_Num];
  68. ASSERT((pn_Code_Word_Min_Index != NULL) && (pd_Code_Word_Min_Distance != NULL));
  69. d_Distance = MAX_DOUBLE_VALUE;
  70. for (n_Loop_Index = 0; n_Loop_Index < VQ_TRAIN_CODE_BOOK_LOOP_TIME; n_Loop_Index++)
  71. {
  72. DEBUG_PRINTF("VQ:tLoop = %4d of %d.n", n_Loop_Index, VQ_TRAIN_CODE_BOOK_LOOP_TIME);
  73. // 计算每个特征的最近类中心及距离
  74. for (n_Feature_Index = 0; n_Feature_Index < n_Code_Word_Num; n_Feature_Index++)
  75. {
  76. pn_Code_Word_Min_Index[n_Feature_Index] = -1;
  77. pd_Code_Word_Min_Distance[n_Feature_Index] = MAX_DOUBLE_VALUE;
  78. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  79. {
  80. dTmp = 0.0F;
  81. for (n_Dim_Index = 0; n_Dim_Index < n_Code_Word_Dim; n_Dim_Index++)
  82. {
  83. dTmp += (d2dda_Code_Word[n_Feature_Index][n_Dim_Index] - d2dda_Code_Book[n_Code_Word_Index][n_Dim_Index])
  84. * (d2dda_Code_Word[n_Feature_Index][n_Dim_Index] - d2dda_Code_Book[n_Code_Word_Index][n_Dim_Index]);
  85. }
  86. if (dTmp < pd_Code_Word_Min_Distance[n_Feature_Index])
  87. {
  88. pn_Code_Word_Min_Index[n_Feature_Index] = n_Code_Word_Index;
  89. pd_Code_Word_Min_Distance[n_Feature_Index] = dTmp;
  90. }
  91. }
  92. }
  93. // 计算类内平均距离
  94. d_Old_Distance = d_Distance;
  95. d_Distance = 0.0F;
  96. for (n_Feature_Index = 0; n_Feature_Index < n_Code_Word_Num; n_Feature_Index++)
  97. {
  98. d_Distance += pd_Code_Word_Min_Distance[n_Feature_Index];
  99. }
  100. d_Distance /= n_Code_Word_Num;
  101. DEBUG_PRINTF("tAverage Distance = %10.4f, Changed %15.4E.n", d_Distance, ((d_Old_Distance - d_Distance) / d_Old_Distance));
  102. // 按最近距离原则给每类分派样点,并用该类样点的平均值更新类中心
  103. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  104. {
  105. nTmp = 0;
  106. for (n_Dim_Index = 0; n_Dim_Index < n_Code_Word_Dim; n_Dim_Index++)
  107. {
  108. d2dda_Code_Book[n_Code_Word_Index][n_Dim_Index] = 0.0F;
  109. }
  110. for (n_Feature_Index = 0; n_Feature_Index < n_Code_Word_Num; n_Feature_Index++)
  111. {
  112. if (pn_Code_Word_Min_Index[n_Feature_Index] == n_Code_Word_Index)
  113. {
  114. nTmp++;
  115. for (n_Dim_Index = 0; n_Dim_Index < n_Code_Word_Dim; n_Dim_Index++)
  116. {
  117. d2dda_Code_Book[n_Code_Word_Index][n_Dim_Index] += d2dda_Code_Word[n_Feature_Index][n_Dim_Index];
  118. }
  119. }
  120. }
  121. // 该类分到了样点,直接计算
  122. if (nTmp != 0)
  123. {
  124. for (n_Dim_Index = 0; n_Dim_Index < n_Code_Word_Dim; n_Dim_Index++)
  125. {
  126. d2dda_Code_Book[n_Code_Word_Index][n_Dim_Index] /= nTmp;
  127. }
  128. }
  129. // 该类没有分到样点,则丢弃原类中心,随机选中一个样点作为该类中心
  130. else
  131. {
  132. do {
  133. nTmp = int((double(rand()) / (double(RAND_MAX) + 1)) * n_Code_Word_Num);
  134. boolTmp = FALSE;
  135. if (pd_Code_Word_Min_Distance[nTmp] < EPSILON_DOUBLE_VALUE) boolTmp = TRUE;
  136. } while (boolTmp);
  137. memcpy(d2dda_Code_Book[n_Code_Word_Index], d2dda_Code_Word[nTmp], sizeof(double) * n_Code_Word_Dim);
  138. }
  139. }
  140. }
  141. PRO_LOG("VQ:tLoop = %4d, Average Distance = %10.4f, Changed %15.4E.n", n_Loop_Index, d_Distance, ((d_Old_Distance - d_Distance) / d_Old_Distance));
  142. delete[] pn_Code_Word_Min_Index;
  143. delete[] pd_Code_Word_Min_Distance;
  144. return 0;
  145. }
  146. int DHMM_Model_Train_DHMM_Model_HQ(WORD_SAMPLE * pu_Word_Sample, int n_Word_Sample_Num,
  147.    DHMM_MODEL * pu_DHMM_Model)
  148. {
  149. DYNA_2DIM_DOUBLE_ARRAY d2dda_Nom; // 状态数 * 输出个数
  150. double * pd_Denom; // 状态数
  151. int n_Loop_Index, n_State_Index, n_Code_Word_Index, n_Word_Sample_Index, n_Frame_Index;
  152. int nTmp;
  153. double d_Old_Total_Likelihood, d_Total_Likelihood; // 上次与此次迭代的模型对所有词条匹配分数的加和
  154. double dTmp;
  155. PRO_LOG("tModel = HQ, loop = %4d.n", MODEL_TRAIN_CODE_BOOK_LOOP_TIME);
  156. // 初始化Pi,初始状态为状态0
  157. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  158. {
  159. pu_DHMM_Model->pdPi[n_State_Index] = 0.0F;
  160. }
  161. pu_DHMM_Model->pdPi[0] = 1.0F;
  162. // 初始化A,只能停留或跳向下一个状态,并且等概0.5,最后一个状态只能停留
  163. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  164. {
  165. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  166. {
  167. pu_DHMM_Model->d2dda_A[n_State_Index][nTmp] = 0.0F;
  168. }
  169. }
  170. for (n_State_Index = 0; n_State_Index < (pu_DHMM_Model->n_State_Num - 1); n_State_Index++)
  171. {
  172. pu_DHMM_Model->d2dda_A[n_State_Index][n_State_Index] = 0.5F;
  173. pu_DHMM_Model->d2dda_A[n_State_Index][n_State_Index + 1] = 0.5F;
  174. }
  175. pu_DHMM_Model->d2dda_A[pu_DHMM_Model->n_State_Num - 1][pu_DHMM_Model->n_State_Num - 1] = 1.0F;
  176. // 初始化B,均匀初始化,每个状态输出各个输出码字的概率均等,为码字总数的倒数
  177. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  178. {
  179. for (n_Code_Word_Index = 0; n_Code_Word_Index < pu_DHMM_Model->n_Code_Book_Size; n_Code_Word_Index++)
  180. {
  181. pu_DHMM_Model->d2dda_B[n_State_Index][n_Code_Word_Index] = 1.0F / pu_DHMM_Model->n_Code_Book_Size;
  182. }
  183. }
  184. d2dda_Nom = d2dda_New(pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
  185. pd_Denom = new double[pu_DHMM_Model->n_State_Num];
  186. ASSERT((d2dda_Nom != NULL) && (pd_Denom != NULL));
  187. for (n_Word_Sample_Index = 0; n_Word_Sample_Index < n_Word_Sample_Num; n_Word_Sample_Index++)
  188. {
  189. pu_Word_Sample[n_Word_Sample_Index].d2dda_Gamma = d2dda_New(pu_Word_Sample[n_Word_Sample_Index].n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  190. ASSERT(pu_Word_Sample[n_Word_Sample_Index].d2dda_Gamma != NULL);
  191. }
  192. d_Total_Likelihood = -MAX_DOUBLE_VALUE;
  193. for (n_Loop_Index = 0; n_Loop_Index < MODEL_TRAIN_CODE_BOOK_LOOP_TIME; n_Loop_Index++)
  194. {
  195. // 计算每个词条的Gamma系数,二维数组,帧数 * 状态数
  196. for (n_Word_Sample_Index = 0; n_Word_Sample_Index < n_Word_Sample_Num; n_Word_Sample_Index++)
  197. {
  198. DHMM_Model_Calculate_Gamma(&pu_Word_Sample[n_Word_Sample_Index], pu_DHMM_Model);
  199. }
  200. // 准备重估B
  201. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  202. {
  203. pd_Denom[n_State_Index] = 0.0F;
  204. for (n_Code_Word_Index = 0; n_Code_Word_Index < pu_DHMM_Model->n_Code_Book_Size; n_Code_Word_Index++)
  205. {
  206. d2dda_Nom[n_State_Index][n_Code_Word_Index] = 0.0F;
  207. }
  208. }
  209. // 计算重估B时每项的分子,和每行的分母
  210. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  211. {
  212. for (n_Word_Sample_Index = 0; n_Word_Sample_Index < n_Word_Sample_Num; n_Word_Sample_Index++)
  213. {
  214. for (n_Frame_Index = 0; n_Frame_Index < pu_Word_Sample[n_Word_Sample_Index].n_Feature_Sequence_Len; n_Frame_Index++)
  215. {
  216. d2dda_Nom[n_State_Index][pu_Word_Sample[n_Word_Sample_Index].pn_VQed_Feature_Sequence[n_Frame_Index]]
  217. += pu_Word_Sample[n_Word_Sample_Index].d2dda_Gamma[n_Frame_Index][n_State_Index];
  218. pd_Denom[n_State_Index] += pu_Word_Sample[n_Word_Sample_Index].d2dda_Gamma[n_Frame_Index][n_State_Index];
  219. }
  220. }
  221. }
  222. // 重新计算B
  223. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  224. {
  225. for (n_Code_Word_Index = 0; n_Code_Word_Index < pu_DHMM_Model->n_Code_Book_Size; n_Code_Word_Index++)
  226. {
  227. pu_DHMM_Model->d2dda_B[n_State_Index][n_Code_Word_Index] = 
  228. d2dda_Nom[n_State_Index][n_Code_Word_Index] / pd_Denom[n_State_Index];
  229. }
  230. }
  231. // 计算当前模型对于全体训练词条的匹配分数和
  232. d_Old_Total_Likelihood = d_Total_Likelihood;
  233. d_Total_Likelihood = 0.0F;
  234. for (n_Word_Sample_Index = 0; n_Word_Sample_Index < n_Word_Sample_Num; n_Word_Sample_Index++)
  235. {
  236. DHMM_Recog_Forward_Backward_GL(pu_DHMM_Model, &pu_Word_Sample[n_Word_Sample_Index], &dTmp);
  237. d_Total_Likelihood += dTmp;
  238. }
  239. // 如果迭代收敛,跳出
  240. // if (fabs((d_Old_Total_Likelihood - d_Total_Likelihood) / d_Old_Total_Likelihood) < 1.0E-6) break;
  241. // DEBUG_PRINTF("tTotal likelihood = %10.4f, changed %15.4E.n", d_Total_Likelihood, ((d_Old_Total_Likelihood - d_Total_Likelihood) / d_Old_Total_Likelihood));
  242. }
  243. PRO_LOG("tLoop = %4d, Total likelihood = %10.4f, changed %15.4E.n", n_Loop_Index, d_Total_Likelihood, ((d_Old_Total_Likelihood - d_Total_Likelihood) / d_Old_Total_Likelihood));
  244. for (n_Word_Sample_Index = 0; n_Word_Sample_Index < n_Word_Sample_Num; n_Word_Sample_Index++)
  245. {
  246. d2dda_Free(pu_Word_Sample[n_Word_Sample_Index].d2dda_Gamma, pu_Word_Sample[n_Word_Sample_Index].n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  247. pu_Word_Sample[n_Word_Sample_Index].d2dda_Gamma = NULL;
  248. }
  249. d2dda_Free(d2dda_Nom, pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
  250. delete[] pd_Denom;
  251. return 0;
  252. }
  253. int DHMM_Recog_Viterbi_HQ(DHMM_MODEL * pu_DHMM_Model,
  254.   WORD_SAMPLE * pu_Word_Sample,
  255.   double * pd_Max_Likelihood, int * pn_Status_Sequence)
  256. {
  257. DYNA_2DIM_DOUBLE_ARRAY d2dda_B;
  258. DYNA_2DIM_INT_ARRAY d2dna_LogB;
  259. int n_Code_Word_Index, n_State_Index;
  260. d2dda_B = d2dda_New(pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
  261. d2dna_LogB = d2dna_New(pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
  262. ASSERT((d2dda_B != NULL) && (d2dna_LogB != NULL));
  263. // 对于B矩阵进行定点化处理,下截底并取对数
  264. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  265. {
  266. memcpy(d2dda_B[n_State_Index], pu_DHMM_Model->d2dda_B[n_State_Index], sizeof(double) * pu_DHMM_Model->n_Code_Book_Size);
  267. }
  268. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  269. {
  270. for (n_Code_Word_Index = 0; n_Code_Word_Index < pu_DHMM_Model->n_Code_Book_Size; n_Code_Word_Index++)
  271. {
  272. if (d2dda_B[n_State_Index][n_Code_Word_Index] < EPSILON_DOUBLE_VALUE)
  273. d2dda_B[n_State_Index][n_Code_Word_Index] = EPSILON_DOUBLE_VALUE;
  274. d2dna_LogB[n_State_Index][n_Code_Word_Index]
  275. = (short)(log10(d2dda_B[n_State_Index][n_Code_Word_Index]) * (65536L / LOG_SCALE) + 32768L);
  276. ASSERT((d2dna_LogB[n_State_Index][n_Code_Word_Index] >= short(MIN_SHORT_VALUE)) && (d2dna_LogB[n_State_Index][n_Code_Word_Index] <= MAX_SHORT_VALUE));
  277. }
  278. }
  279. // 调用定点的Viterbi算法计算匹配分数
  280. *pd_Max_Likelihood = DHMM_Recog_Viterbi_HQ_FIX(d2dna_LogB, pu_DHMM_Model->n_State_Num,
  281. pu_Word_Sample->pn_VQed_Feature_Sequence, pu_Word_Sample->n_Feature_Sequence_Len);
  282. d2dda_Free(d2dda_B, pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
  283. d2dna_Free(d2dna_LogB, pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
  284. return 0;
  285. }
  286. // 定点viterbi算法,已经对于Pi和A作了简化假设
  287. long DHMM_Recog_Viterbi_HQ_FIX(DYNA_2DIM_INT_ARRAY d2dna_LogB, int n_State_Num,
  288.   int * pn_VQed_Feature_Sequence, int n_Feature_Sequence_Len)
  289. {
  290. long * pl_Alpha;
  291. int n_State_Index, n_Frame_Index;
  292. long lTmp1, lTmp2;
  293. int i=0;
  294. int first = 1;
  295. long sl_1 = 0;
  296. long sl_2 = 0;
  297. int second = 1;
  298. pl_Alpha = new long[n_State_Num];
  299. ASSERT(pl_Alpha != NULL);
  300. for (n_State_Index = 0; n_State_Index < n_State_Num; n_State_Index++) pl_Alpha[n_State_Index] = long(MIN_LONG_VALUE) / 2;
  301. pl_Alpha[0] = 0;
  302. pl_Alpha[1] = 0;
  303. // lTmp1: Delta[t-1][i-1], lTmp2: Delta[t-1][i]
  304. for (n_Frame_Index = 1; n_Frame_Index < n_Feature_Sequence_Len; n_Frame_Index++)
  305. {
  306. lTmp1 = MIN_LONG_VALUE;
  307. for (n_State_Index = 0; n_State_Index < n_State_Num; n_State_Index++)
  308. {
  309. lTmp2 = pl_Alpha[n_State_Index];
  310. if (lTmp1 > lTmp2) 
  311. pl_Alpha[n_State_Index] = lTmp1;
  312. pl_Alpha[n_State_Index] += d2dna_LogB[n_State_Index][pn_VQed_Feature_Sequence[n_Frame_Index]];
  313. lTmp1 = lTmp2;
  314. }
  315. }
  316. lTmp1 = MIN_LONG_VALUE;
  317. for (n_State_Index = 0; n_State_Index < n_State_Num; n_State_Index++)
  318. {
  319. if (lTmp1 < pl_Alpha[n_State_Index]) 
  320. lTmp1 = pl_Alpha[n_State_Index];
  321. }
  322. delete[] pl_Alpha;
  323. return lTmp1;
  324. }
  325. int DHMM_Recog_Forward_Backward_HQ(DHMM_MODEL * pu_DHMM_Model,
  326.    WORD_SAMPLE * pu_Word_Sample,
  327.    double * pd_Max_Likelihood)
  328. {
  329. DYNA_2DIM_DOUBLE_ARRAY d2dda_Alpha;
  330. int n_Frame_Index, n_State_Index;
  331. int nTmp;
  332. double dTmp;
  333. d2dda_Alpha = d2dda_New(pu_Word_Sample->n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  334. ASSERT(d2dda_Alpha != NULL);
  335. for (n_Frame_Index = 0; n_Frame_Index < pu_Word_Sample->n_Feature_Sequence_Len; n_Frame_Index++)
  336. {
  337. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  338. {
  339. d2dda_Alpha[n_Frame_Index][n_State_Index] = 0.0F;
  340. }
  341. }
  342. d2dda_Alpha[0][0] = pu_DHMM_Model->d2dda_B[0][pu_Word_Sample->pn_VQed_Feature_Sequence[0]];
  343. for (n_Frame_Index = 1; n_Frame_Index < pu_Word_Sample->n_Feature_Sequence_Len; n_Frame_Index++)
  344. {
  345. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  346. {
  347. dTmp = 0.0F;
  348. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  349. {
  350. dTmp += d2dda_Alpha[n_Frame_Index - 1][nTmp] * pu_DHMM_Model->d2dda_A[nTmp][n_State_Index];
  351. }
  352. d2dda_Alpha[n_Frame_Index][n_State_Index] = dTmp * pu_DHMM_Model->d2dda_B[n_State_Index][pu_Word_Sample->pn_VQed_Feature_Sequence[n_Frame_Index]];
  353. }
  354. }
  355. dTmp = 0.0F;
  356. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  357. {
  358. dTmp += d2dda_Alpha[pu_Word_Sample->n_Feature_Sequence_Len - 1][n_State_Index];
  359. }
  360. (*pd_Max_Likelihood) = log(dTmp);
  361. d2dda_Free(d2dda_Alpha, pu_Word_Sample->n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  362. return 0;
  363. }
  364. static int DHMM_Model_Calculate_Gamma(WORD_SAMPLE * pu_Word_Sample, DHMM_MODEL * pu_DHMM_Model)
  365. {
  366. DYNA_2DIM_DOUBLE_ARRAY d2dda_Alpha;
  367. DYNA_2DIM_DOUBLE_ARRAY d2dda_Beta;
  368. double * pd_C;
  369. int n_Frame_Index, n_State_Index;
  370. int nTmp;
  371. double dTmp;
  372. d2dda_Alpha = d2dda_New(pu_Word_Sample->n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  373. ASSERT(d2dda_Alpha !=NULL);
  374. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  375. {
  376. d2dda_Alpha[0][nTmp] = 0.0F;
  377. }
  378. d2dda_Alpha[0][0] = pu_DHMM_Model->d2dda_B[0][pu_Word_Sample->pn_VQed_Feature_Sequence[0]];
  379. pd_C = new double[pu_Word_Sample->n_Feature_Sequence_Len];
  380. pd_C[0] = 0.0F;
  381. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  382. {
  383. pd_C[0] += d2dda_Alpha[0][nTmp];
  384. }
  385. pd_C[0] = 1.0F / pd_C[0];
  386. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  387. {
  388. d2dda_Alpha[0][nTmp] *= pd_C[0];
  389. }
  390. for (n_Frame_Index = 1; n_Frame_Index < pu_Word_Sample->n_Feature_Sequence_Len; n_Frame_Index++)
  391. {
  392. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  393. {
  394. dTmp = 0.0F;
  395. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  396. {
  397. dTmp += d2dda_Alpha[n_Frame_Index - 1][nTmp] * pu_DHMM_Model->d2dda_A[nTmp][n_State_Index];
  398. }
  399. d2dda_Alpha[n_Frame_Index][n_State_Index] = dTmp * pu_DHMM_Model->d2dda_B[n_State_Index][pu_Word_Sample->pn_VQed_Feature_Sequence[n_Frame_Index]];
  400. }
  401. pd_C[n_Frame_Index] = 0.0F;
  402. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  403. {
  404. pd_C[n_Frame_Index] += d2dda_Alpha[n_Frame_Index][nTmp];
  405. }
  406. pd_C[n_Frame_Index] = 1.0F / pd_C[n_Frame_Index];
  407. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  408. {
  409. d2dda_Alpha[n_Frame_Index][nTmp] *= pd_C[n_Frame_Index];
  410. }
  411. }
  412. d2dda_Beta = d2dda_New(pu_Word_Sample->n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  413. ASSERT(d2dda_Beta != NULL);
  414. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  415. {
  416. d2dda_Beta[pu_Word_Sample->n_Feature_Sequence_Len - 1][nTmp] = pd_C[pu_Word_Sample->n_Feature_Sequence_Len - 1];
  417. }
  418. for (n_Frame_Index = pu_Word_Sample->n_Feature_Sequence_Len - 2; n_Frame_Index >= 0; n_Frame_Index--)
  419. {
  420. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  421. {
  422. d2dda_Beta[n_Frame_Index][n_State_Index] = 0.0F;
  423. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  424. {
  425. d2dda_Beta[n_Frame_Index][n_State_Index] +=
  426. d2dda_Beta[n_Frame_Index + 1][nTmp] * pu_DHMM_Model->d2dda_B[nTmp][pu_Word_Sample->pn_VQed_Feature_Sequence[n_Frame_Index + 1]] * pu_DHMM_Model->d2dda_A[n_State_Index][nTmp];
  427. }
  428. }
  429. for (nTmp = 0; nTmp < pu_DHMM_Model->n_State_Num; nTmp++)
  430. {
  431. d2dda_Beta[n_Frame_Index][nTmp] *= pd_C[n_Frame_Index];
  432. }
  433. }
  434. for (n_Frame_Index = 0; n_Frame_Index < pu_Word_Sample->n_Feature_Sequence_Len; n_Frame_Index++)
  435. {
  436. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  437. {
  438. pu_Word_Sample->d2dda_Gamma[n_Frame_Index][n_State_Index]
  439. = d2dda_Alpha[n_Frame_Index][n_State_Index] * d2dda_Beta[n_Frame_Index][n_State_Index];
  440. }
  441. dTmp = 0.0F;
  442. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  443. {
  444. dTmp += pu_Word_Sample->d2dda_Gamma[n_Frame_Index][n_State_Index];
  445. }
  446. for (n_State_Index = 0; n_State_Index < pu_DHMM_Model->n_State_Num; n_State_Index++)
  447. {
  448. pu_Word_Sample->d2dda_Gamma[n_Frame_Index][n_State_Index] /= dTmp;
  449. }
  450. }
  451. d2dda_Free(d2dda_Beta, pu_Word_Sample->n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  452. delete[] pd_C;
  453. d2dda_Free(d2dda_Alpha, pu_Word_Sample->n_Feature_Sequence_Len, pu_DHMM_Model->n_State_Num);
  454. return 0;
  455. }