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
36static const char matx_ops[] = "$Id: matx_ops.c,v 1.5.6.6 2007/10/15 18:06:24 dahan Exp $";
37
38covdata **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
51void 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
62void 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
73int 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
124imeldata **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
137void 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