Home | History | Annotate | Download | only in clib
      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