1 /*---------------------------------------------------------------------------*
2 * imeld_rd.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 #ifndef _RTT
22 #include <stdio.h>
23 #endif
24 #include <stdlib.h>
25 #include <math.h>
26 #include <string.h>
27 #ifdef unix
28 #include <limits.h>
29 #endif
30 #include <assert.h>
31
32 #include "prelib.h"
33 #ifndef _RTT
34 #include "duk_io.h"
35 #endif
36
37 #include "pendian.h"
38 #include "portable.h"
39
40 static const char imeld_rd[] = "$Id: imeld_rd.c,v 1.5.6.7 2007/10/15 18:06:24 dahan Exp $";
41
42 /* function prototypes */
43
44 imeldata **create_fixed_matrix(int dimen);
45 covdata **create_matrix(int dimen);
46 void delete_matrix(covdata **matrix, int dimen);
47 void delete_fixed_matrix(imeldata **matrix, int dimen);
48 int scale_matrix_for_fixedpoint(imeldata **fixmat, covdata **matrix,int dimen);
49 int invert_matrix(covdata **mat, covdata **inv, int dim);
50
51
create_linear_transform(preprocessed * prep,int matdim,int with_offset)52 void create_linear_transform(preprocessed *prep, int matdim,
53 int with_offset)
54 {
55 ASSERT(prep);
56 ASSERT(matdim > 0);
57 prep->dim = matdim;
58 prep->matrix = create_fixed_matrix(matdim);
59 if (with_offset)
60 prep->offset = (imeldata *) CALLOC(matdim,
61 sizeof(imeldata), "clib.offset");
62 prep->imelda = create_matrix(matdim);
63 prep->invmat = create_fixed_matrix(matdim);
64 prep->inverse = create_matrix(matdim);
65 return;
66 }
67
free_linear_transform(preprocessed * prep)68 void free_linear_transform(preprocessed *prep)
69 {
70 ASSERT(prep);
71 ASSERT(prep->matrix);
72 delete_fixed_matrix(prep->matrix, prep->dim);
73 if (prep->offset)
74 FREE(prep->offset);
75 prep->matrix = NULL;
76 prep->offset = NULL;
77 ASSERT(prep->imelda);
78 delete_matrix(prep->imelda, prep->dim);
79 prep->imelda = NULL;
80 ASSERT(prep->invmat);
81 ASSERT(prep->inverse);
82 delete_fixed_matrix(prep->invmat, prep->dim);
83 delete_matrix(prep->inverse, prep->dim);
84 prep->invmat = NULL;
85 prep->inverse = NULL;
86 return;
87 }
88
89 #ifndef _RTT
init_newton_transform(preprocessed * prep,float reqscale,char * filename,int dimen)90 int init_newton_transform(preprocessed *prep, float reqscale,
91 char *filename, int dimen)
92 /*
93 */
94 {
95 int ii, jj;
96 unsigned short matdim;
97 double scale, onerow[MAX_DIMEN];
98 PFile* dfpt;
99 long foffset;
100 double xfp;
101 /* Open file
102 */
103 ASSERT(prep);
104 ASSERT(filename);
105 dfpt = file_must_open(NULL, filename, ("rb"), ESR_TRUE);
106 prep->post_proc |= LIN_TRAN;
107 prep->use_dim = dimen;
108 pfread(&matdim, sizeof(short), 1, dfpt);
109 if (matdim > MAX_DIMEN)
110 SERVICE_ERROR(BAD_IMELDA);
111
112 create_linear_transform(prep, matdim, 1);
113 pfread(&scale, sizeof(double), 1, dfpt);
114
115 if (reqscale != 0) scale = reqscale;
116 #if DEBUG
117 PLogMessage("L: LDA Suggested scale is %.1f\n", scale);
118 #endif
119 if (!prep->dim) prep->dim = matdim;
120 else if (prep->dim != matdim)
121 {
122 log_report("Data (%d) and LDA (%d) dimensions don't match\n",
123 prep->dim, matdim);
124 SERVICE_ERROR(BAD_IMELDA);
125 }
126
127 /* Eigenvalues, ignored
128 */
129 pfread(onerow, sizeof(double), matdim, dfpt);
130
131 /* Translation Vector
132 */
133 pfread(onerow, sizeof(double), matdim, dfpt);
134 for (ii = 0; ii < matdim; ii++)
135 {
136 xfp = scale * (onerow[ii] - UTB_MEAN) + UTB_MEAN;
137 if (xfp > 0.0)
138 xfp += 0.5;
139 else if (xfp < 0.0)
140 xfp -= 0.5;
141
142 prep->offset[ii] = (imeldata) xfp;
143 }
144
145 /* The imelda matrix
146 */
147 for (ii = 0; ii < matdim; ii++)
148 {
149 pfread(onerow, sizeof(double), matdim, dfpt);
150 for (jj = 0; jj < matdim; jj++)
151 prep->imelda[ii][jj] = (covdata)(scale * onerow[jj]);
152 }
153
154 prep->imel_shift = scale_matrix_for_fixedpoint(prep->matrix,
155 prep->imelda, matdim);
156
157 /* The inverse imelda matrix
158 */
159 foffset = pftell(dfpt);
160 pfread(onerow, sizeof(double), matdim, dfpt);
161
162 if (pfeof(dfpt) != 0)
163 {
164 #ifdef SREC_ENGINE_VERBOSE_LOGGING
165 PLogMessage("W: Inverting imelda matrix");
166 #endif
167 invert_matrix(prep->imelda, prep->inverse, prep->dim);
168 }
169 else
170 {
171 pfseek(dfpt, foffset, SEEK_SET);
172
173 for (ii = 0; ii < matdim; ii++)
174 {
175 pfread(onerow, sizeof(double), matdim, dfpt);
176 for (jj = 0; jj < matdim; jj++)
177 prep->inverse[ii][jj] = (covdata)(onerow[jj] / scale);
178 }
179 }
180
181 prep->inv_shift = scale_matrix_for_fixedpoint(prep->invmat,
182 prep->inverse, matdim);
183
184 pfclose(dfpt);
185 return (0);
186 }
187 #endif
188