14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------* 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * imeld_rd.c * 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Copyright 2007, 2008 Nuance Communciations, Inc. * 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the 'License'); * 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * you may not use this file except in compliance with the License. * 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * You may obtain a copy of the License at * 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 * 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software * 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * distributed under the License is distributed on an 'AS IS' BASIS, * 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * See the License for the specific language governing permissions and * 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * limitations under the License. * 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/ 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef _RTT 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdio.h> 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdlib.h> 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <math.h> 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string.h> 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifdef unix 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <limits.h> 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <assert.h> 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "prelib.h" 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef _RTT 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "duk_io.h" 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "pendian.h" 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "portable.h" 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const char imeld_rd[] = "$Id: imeld_rd.c,v 1.5.6.7 2007/10/15 18:06:24 dahan Exp $"; 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* function prototypes */ 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectimeldata **create_fixed_matrix(int dimen); 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectcovdata **create_matrix(int dimen); 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid delete_matrix(covdata **matrix, int dimen); 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid delete_fixed_matrix(imeldata **matrix, int dimen); 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint scale_matrix_for_fixedpoint(imeldata **fixmat, covdata **matrix,int dimen); 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint invert_matrix(covdata **mat, covdata **inv, int dim); 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid create_linear_transform(preprocessed *prep, int matdim, 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int with_offset) 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(prep); 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(matdim > 0); 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->dim = matdim; 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->matrix = create_fixed_matrix(matdim); 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (with_offset) 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->offset = (imeldata *) CALLOC(matdim, 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sizeof(imeldata), "clib.offset"); 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->imelda = create_matrix(matdim); 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->invmat = create_fixed_matrix(matdim); 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->inverse = create_matrix(matdim); 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid free_linear_transform(preprocessed *prep) 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(prep); 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(prep->matrix); 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete_fixed_matrix(prep->matrix, prep->dim); 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (prep->offset) 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE(prep->offset); 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->matrix = NULL; 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->offset = NULL; 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(prep->imelda); 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete_matrix(prep->imelda, prep->dim); 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->imelda = NULL; 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(prep->invmat); 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(prep->inverse); 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete_fixed_matrix(prep->invmat, prep->dim); 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete_matrix(prep->inverse, prep->dim); 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->invmat = NULL; 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->inverse = NULL; 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef _RTT 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint init_newton_transform(preprocessed *prep, float reqscale, 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *filename, int dimen) 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project*/ 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int ii, jj; 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned short matdim; 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project double scale, onerow[MAX_DIMEN]; 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project PFile* dfpt; 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project long foffset; 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project double xfp; 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Open file 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(prep); 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(filename); 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project dfpt = file_must_open(NULL, filename, ("rb"), ESR_TRUE); 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->post_proc |= LIN_TRAN; 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->use_dim = dimen; 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfread(&matdim, sizeof(short), 1, dfpt); 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (matdim > MAX_DIMEN) 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SERVICE_ERROR(BAD_IMELDA); 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project create_linear_transform(prep, matdim, 1); 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfread(&scale, sizeof(double), 1, dfpt); 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (reqscale != 0) scale = reqscale; 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project PLogMessage("L: LDA Suggested scale is %.1f\n", scale); 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!prep->dim) prep->dim = matdim; 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (prep->dim != matdim) 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log_report("Data (%d) and LDA (%d) dimensions don't match\n", 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->dim, matdim); 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SERVICE_ERROR(BAD_IMELDA); 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Eigenvalues, ignored 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfread(onerow, sizeof(double), matdim, dfpt); 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Translation Vector 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfread(onerow, sizeof(double), matdim, dfpt); 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (ii = 0; ii < matdim; ii++) 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project xfp = scale * (onerow[ii] - UTB_MEAN) + UTB_MEAN; 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (xfp > 0.0) 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project xfp += 0.5; 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (xfp < 0.0) 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project xfp -= 0.5; 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->offset[ii] = (imeldata) xfp; 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* The imelda matrix 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (ii = 0; ii < matdim; ii++) 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfread(onerow, sizeof(double), matdim, dfpt); 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (jj = 0; jj < matdim; jj++) 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->imelda[ii][jj] = (covdata)(scale * onerow[jj]); 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->imel_shift = scale_matrix_for_fixedpoint(prep->matrix, 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->imelda, matdim); 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* The inverse imelda matrix 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project foffset = pftell(dfpt); 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfread(onerow, sizeof(double), matdim, dfpt); 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (pfeof(dfpt) != 0) 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifdef SREC_ENGINE_VERBOSE_LOGGING 1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project PLogMessage("W: Inverting imelda matrix"); 1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project invert_matrix(prep->imelda, prep->inverse, prep->dim); 1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfseek(dfpt, foffset, SEEK_SET); 1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (ii = 0; ii < matdim; ii++) 1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfread(onerow, sizeof(double), matdim, dfpt); 1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (jj = 0; jj < matdim; jj++) 1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->inverse[ii][jj] = (covdata)(onerow[jj] / scale); 1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->inv_shift = scale_matrix_for_fixedpoint(prep->invmat, 1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prep->inverse, matdim); 1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pfclose(dfpt); 1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (0); 1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 188