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