1 /*---------------------------------------------------------------------------*
2 * matx_ops.c *
3 * *
4 * Copyright 2007, 2008 Nuance Communciations, Inc. *
5 * *
6 * Licensed under the Apache License, Version 2.0 (the 'License'); *
7 * you may not use this file except in compliance with the License. *
8 * *
9 * You may obtain a copy of the License at *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, software *
13 * distributed under the License is distributed on an 'AS IS' BASIS, *
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * See the License for the specific language governing permissions and *
16 * limitations under the License. *
17 * *
18 *---------------------------------------------------------------------------*/
19
20
21 #include <stdlib.h>
22 #ifndef _RTT
23 #include <stdio.h>
24 #endif
25 #include <math.h>
26 #include <string.h>
27 #include <assert.h>
28
29 #include "hmmlib.h"
30 #include "prelib.h"
31 #include "duk_io.h"
32 #include "duk_err.h"
33 #include "pendian.h"
34 #include "portable.h"
35
36 static const char matx_ops[] = "$Id: matx_ops.c,v 1.5.6.6 2007/10/15 18:06:24 dahan Exp $";
37
create_matrix(int dimen)38 covdata **create_matrix(int dimen)
39 {
40 int ii;
41 covdata **matrix;
42
43 matrix = (covdata **) CALLOC(dimen, sizeof(covdata *),
44 "clib.cov_matrix");
45 for (ii = 0; ii < dimen; ii++)
46 matrix[ii] = (covdata *) CALLOC(dimen, sizeof(covdata),
47 "clib.cov_matrix[]");
48 return (matrix);
49 }
50
delete_matrix(covdata ** matrix,int dimen)51 void delete_matrix(covdata **matrix, int dimen)
52 {
53 int ii;
54
55 ASSERT(matrix);
56 for (ii = 0; ii < dimen; ii++)
57 FREE((char *)matrix[ii]);
58 FREE((char *)matrix);
59 return;
60 }
61
diagonal_elements(covdata * vector,covdata ** matrix,int dim)62 void diagonal_elements(covdata *vector, covdata **matrix, int dim)
63 {
64 int ii;
65
66 ASSERT(vector);
67 ASSERT(matrix);
68 for (ii = 0; ii < dim; ii++)
69 vector[ii] = (float) matrix[ii][ii];
70 return;
71 }
72
scale_matrix_for_fixedpoint(imeldata ** fixmat,covdata ** matrix,int dimen)73 int scale_matrix_for_fixedpoint(imeldata **fixmat, covdata **matrix,
74 int dimen)
75 {
76 int ii, jj, shift;
77 long scale_coef;
78 double sum_coef, xfp;
79 double max_sum_coef = 0.0;
80
81 ASSERT(matrix);
82 ASSERT(fixmat);
83 ASSERT(dimen > 0);
84 max_sum_coef = 0;
85 for (ii = 0; ii < dimen; ii++)
86 {
87 sum_coef = 0;
88 for (jj = 0; jj < dimen; jj++)
89 sum_coef += fabs(matrix[ii][jj]);
90 if (sum_coef > max_sum_coef)
91 max_sum_coef = sum_coef;
92 }
93
94 scale_coef = (long)((double)FIXED_MAX / max_sum_coef);
95 if (scale_coef < 1)
96 SERVICE_ERROR(BAD_IMELDA); /* TODO: find a suitable code */
97
98 shift = 0;
99 while (scale_coef > 1)
100 {
101 shift++;
102 scale_coef >>= 1;
103 }
104
105 scale_coef = (1 << shift);
106
107 /* read in again and scale up using prep->imel_shift
108 */
109 for (ii = 0; ii < dimen; ii++)
110 for (jj = 0; jj < dimen; jj++)
111 {
112 xfp = ((double)scale_coef) * matrix[ii][jj];
113 if (xfp > 0.0)
114 xfp += 0.5;
115 else if (xfp < 0.0)
116 xfp -= 0.5;
117 ASSERT(xfp < FIXED_MAX);
118 ASSERT(xfp > -FIXED_MAX);
119 fixmat[ii][jj] = (imeldata) xfp;
120 }
121 return (shift);
122 }
123
create_fixed_matrix(int dimen)124 imeldata **create_fixed_matrix(int dimen)
125 {
126 int ii;
127 imeldata **matrix;
128
129 matrix = (imeldata **) CALLOC(dimen, sizeof(imeldata *),
130 "clib.fixed_matrix");
131 for (ii = 0; ii < dimen; ii++)
132 matrix[ii] = (imeldata *) CALLOC(dimen, sizeof(imeldata),
133 "clib.fixed_matrix[]");
134 return (matrix);
135 }
136
delete_fixed_matrix(imeldata ** matrix,int dimen)137 void delete_fixed_matrix(imeldata **matrix, int dimen)
138 {
139 int ii;
140
141 ASSERT(matrix);
142
143 for (ii = 0; ii < dimen; ii++)
144 FREE((char *)matrix[ii]);
145 FREE((char *)matrix);
146 return;
147 }
148