• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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