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 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 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 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