blob: 2f4536ed4148b29dcedce8adc2db53319fcd124b [file] [log] [blame]
/*---------------------------------------------------------------------------*
* matx_ops.c *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* Licensed under the Apache License, Version 2.0 (the 'License'); *
* you may not use this file except in compliance with the License. *
* *
* You may obtain a copy of the License at *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an 'AS IS' BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*---------------------------------------------------------------------------*/
#include <stdlib.h>
#ifndef _RTT
#include <stdio.h>
#endif
#include <math.h>
#include <string.h>
#include <assert.h>
#include "hmmlib.h"
#include "prelib.h"
#include "duk_io.h"
#include "duk_err.h"
#include "pendian.h"
#include "portable.h"
static const char matx_ops[] = "$Id: matx_ops.c,v 1.5.6.6 2007/10/15 18:06:24 dahan Exp $";
covdata **create_matrix(int dimen)
{
int ii;
covdata **matrix;
matrix = (covdata **) CALLOC(dimen, sizeof(covdata *),
"clib.cov_matrix");
for (ii = 0; ii < dimen; ii++)
matrix[ii] = (covdata *) CALLOC(dimen, sizeof(covdata),
"clib.cov_matrix[]");
return (matrix);
}
void delete_matrix(covdata **matrix, int dimen)
{
int ii;
ASSERT(matrix);
for (ii = 0; ii < dimen; ii++)
FREE((char *)matrix[ii]);
FREE((char *)matrix);
return;
}
void diagonal_elements(covdata *vector, covdata **matrix, int dim)
{
int ii;
ASSERT(vector);
ASSERT(matrix);
for (ii = 0; ii < dim; ii++)
vector[ii] = (float) matrix[ii][ii];
return;
}
int scale_matrix_for_fixedpoint(imeldata **fixmat, covdata **matrix,
int dimen)
{
int ii, jj, shift;
long scale_coef;
double sum_coef, xfp;
double max_sum_coef = 0.0;
ASSERT(matrix);
ASSERT(fixmat);
ASSERT(dimen > 0);
max_sum_coef = 0;
for (ii = 0; ii < dimen; ii++)
{
sum_coef = 0;
for (jj = 0; jj < dimen; jj++)
sum_coef += fabs(matrix[ii][jj]);
if (sum_coef > max_sum_coef)
max_sum_coef = sum_coef;
}
scale_coef = (long)((double)FIXED_MAX / max_sum_coef);
if (scale_coef < 1)
SERVICE_ERROR(BAD_IMELDA); /* TODO: find a suitable code */
shift = 0;
while (scale_coef > 1)
{
shift++;
scale_coef >>= 1;
}
scale_coef = (1 << shift);
/* read in again and scale up using prep->imel_shift
*/
for (ii = 0; ii < dimen; ii++)
for (jj = 0; jj < dimen; jj++)
{
xfp = ((double)scale_coef) * matrix[ii][jj];
if (xfp > 0.0)
xfp += 0.5;
else if (xfp < 0.0)
xfp -= 0.5;
ASSERT(xfp < FIXED_MAX);
ASSERT(xfp > -FIXED_MAX);
fixmat[ii][jj] = (imeldata) xfp;
}
return (shift);
}
imeldata **create_fixed_matrix(int dimen)
{
int ii;
imeldata **matrix;
matrix = (imeldata **) CALLOC(dimen, sizeof(imeldata *),
"clib.fixed_matrix");
for (ii = 0; ii < dimen; ii++)
matrix[ii] = (imeldata *) CALLOC(dimen, sizeof(imeldata),
"clib.fixed_matrix[]");
return (matrix);
}
void delete_fixed_matrix(imeldata **matrix, int dimen)
{
int ii;
ASSERT(matrix);
for (ii = 0; ii < dimen; ii++)
FREE((char *)matrix[ii]);
FREE((char *)matrix);
return;
}