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