14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  matx_ops.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#include <stdlib.h>
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef _RTT
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdio.h>
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <math.h>
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string.h>
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <assert.h>
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "hmmlib.h"
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "prelib.h"
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "duk_io.h"
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "duk_err.h"
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "pendian.h"
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "portable.h"
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const char matx_ops[] = "$Id: matx_ops.c,v 1.5.6.6 2007/10/15 18:06:24 dahan Exp $";
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectcovdata **create_matrix(int dimen)
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int     ii;
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  covdata **matrix;
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  matrix = (covdata **) CALLOC(dimen, sizeof(covdata *),
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                     "clib.cov_matrix");
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii < dimen; ii++)
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    matrix[ii] = (covdata *) CALLOC(dimen, sizeof(covdata),
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                          "clib.cov_matrix[]");
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (matrix);
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid delete_matrix(covdata **matrix, int dimen)
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii;
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(matrix);
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii < dimen; ii++)
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    FREE((char *)matrix[ii]);
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)matrix);
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid diagonal_elements(covdata *vector, covdata **matrix, int dim)
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii;
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(vector);
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(matrix);
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii < dim; ii++)
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    vector[ii] = (float) matrix[ii][ii];
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint scale_matrix_for_fixedpoint(imeldata **fixmat, covdata **matrix,
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                int dimen)
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii, jj, shift;
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  long scale_coef;
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  double sum_coef, xfp;
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  double max_sum_coef = 0.0;
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(matrix);
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(fixmat);
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(dimen > 0);
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  max_sum_coef = 0;
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii < dimen; ii++)
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sum_coef = 0;
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (jj = 0; jj < dimen; jj++)
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      sum_coef += fabs(matrix[ii][jj]);
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (sum_coef > max_sum_coef)
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      max_sum_coef = sum_coef;
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  scale_coef = (long)((double)FIXED_MAX / max_sum_coef);
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (scale_coef < 1)
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SERVICE_ERROR(BAD_IMELDA); /* TODO: find a suitable code */
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  shift = 0;
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  while (scale_coef > 1)
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    shift++;
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    scale_coef >>= 1;
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  scale_coef = (1 << shift);
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* read in again and scale up using prep->imel_shift
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  */
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii < dimen; ii++)
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (jj = 0; jj < dimen; jj++)
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      xfp = ((double)scale_coef) * matrix[ii][jj];
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (xfp > 0.0)
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        xfp += 0.5;
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (xfp < 0.0)
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        xfp -= 0.5;
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ASSERT(xfp < FIXED_MAX);
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ASSERT(xfp > -FIXED_MAX);
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      fixmat[ii][jj] = (imeldata) xfp;
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (shift);
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectimeldata **create_fixed_matrix(int dimen)
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int     ii;
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  imeldata **matrix;
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  matrix = (imeldata **) CALLOC(dimen, sizeof(imeldata *),
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                      "clib.fixed_matrix");
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii < dimen; ii++)
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    matrix[ii] = (imeldata *) CALLOC(dimen, sizeof(imeldata),
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                           "clib.fixed_matrix[]");
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (matrix);
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid delete_fixed_matrix(imeldata **matrix, int dimen)
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii;
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(matrix);
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii < dimen; ii++)
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    FREE((char *)matrix[ii]);
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)matrix);
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
148