1 /* -*- c-basic-offset: 4 -*- */
2 /* ====================================================================
3 * Copyright (c) 1997-2006 Carnegie Mellon University. All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * This work was supported in part by funding from the Defense Advanced
19 * Research Projects Agency and the National Science Foundation of the
20 * United States of America, and the CMU Sphinx Speech Consortium.
22 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
23 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * ====================================================================
44 #include "sphinxbase/clapack_lite.h"
45 #include "sphinxbase/matrix.h"
46 #include "sphinxbase/err.h"
47 #include "sphinxbase/ckd_alloc.h"
50 norm_3d(float32 ***arr,
58 for (i = 0; i < d1; i++) {
59 for (j = 0; j < d2; j++) {
61 /* compute sum (i, j) as over all k */
62 for (k = 0, s = 0; k < d3; k++) {
66 /* do 1 floating point divide */
69 /* divide all k by sum over k */
70 for (k = 0; k < d3; k++) {
78 accum_3d(float32 ***out,
86 for (i = 0; i < d1; i++) {
87 for (j = 0; j < d2; j++) {
88 for (k = 0; k < d3; k++) {
89 out[i][j][k] += in[i][j][k];
96 floor_nz_3d(float32 ***m,
104 for (i = 0; i < d1; i++) {
105 for (j = 0; j < d2; j++) {
106 for (k = 0; k < d3; k++) {
107 if ((m[i][j][k] != 0) && (m[i][j][k] < floor))
114 floor_nz_1d(float32 *v,
120 for (i = 0; i < d1; i++) {
121 if ((v[i] != 0) && (v[i] < floor))
127 band_nz_1d(float32 *v,
133 for (i = 0; i < d1; i++) {
135 if ((v[i] > 0) && (v[i] < band)) {
138 else if ((v[i] < 0) && (v[i] > -band)) {
147 determinant(float32 **a, int32 n)
149 E_FATAL("No LAPACK library available, cannot compute determinant (FIXME)\n");
153 invert(float32 **ainv, float32 **a, int32 n)
155 E_FATAL("No LAPACK library available, cannot compute matrix inverse (FIXME)\n");
159 solve(float32 **a, float32 *b, float32 *out_x, int32 n)
161 E_FATAL("No LAPACK library available, cannot solve linear equations (FIXME)\n");
166 matrixmultiply(float32 ** c, float32 ** a, float32 ** b, int32 n)
170 memset(c[0], 0, n*n*sizeof(float32));
171 for (i = 0; i < n; ++i) {
172 for (j = 0; j < n; ++j) {
173 for (k = 0; k < n; ++k) {
174 c[i][k] += a[i][j] * b[j][k];
179 #else /* WITH_LAPACK */
180 /* Find determinant through LU decomposition. */
182 determinant(float32 ** a, int32 n)
189 /* a is assumed to be symmetric, so we don't need to switch the
190 * ordering of the data. But we do need to copy it since it is
191 * overwritten by LAPACK. */
192 tmp_a = (float32 **)ckd_calloc_2d(n, n, sizeof(float32));
193 memcpy(tmp_a[0], a[0], n*n*sizeof(float32));
196 spotrf_(&uplo, &n, tmp_a[0], &n, &info);
198 /* det = prod(diag(l))^2 */
199 for (i = 1; i < n; ++i)
201 ckd_free_2d((void **)tmp_a);
203 return -1.0; /* Generic "not positive-definite" answer */
209 solve(float32 **a, /*Input : an n*n matrix A */
210 float32 *b, /*Input : a n dimesion vector b */
211 float32 *out_x, /*Output : a n dimesion vector x */
218 /* a is assumed to be symmetric, so we don't need to switch the
219 * ordering of the data. But we do need to copy it since it is
220 * overwritten by LAPACK. */
221 tmp_a = (float32 **)ckd_calloc_2d(n, n, sizeof(float32));
222 memcpy(tmp_a[0], a[0], n*n*sizeof(float32));
223 memcpy(out_x, b, n*sizeof(float32));
226 sposv_(&uplo, &n, &nrhs, tmp_a[0], &n, out_x, &n, &info);
227 ckd_free_2d((void **)tmp_a);
235 /* Find inverse by solving AX=I. */
237 invert(float32 ** ainv, float32 ** a, int32 n)
243 /* Construct an identity matrix. */
244 memset(ainv[0], 0, sizeof(float32) * n * n);
245 for (i = 0; i < n; i++)
247 /* a is assumed to be symmetric, so we don't need to switch the
248 * ordering of the data. But we do need to copy it since it is
249 * overwritten by LAPACK. */
250 tmp_a = (float32 **)ckd_calloc_2d(n, n, sizeof(float32));
251 memcpy(tmp_a[0], a[0], n*n*sizeof(float32));
254 sposv_(&uplo, &n, &nrhs, tmp_a[0], &n, ainv[0], &n, &info);
255 ckd_free_2d((void **)tmp_a);
264 matrixmultiply(float32 ** c, float32 ** a, float32 ** b, int32 n)
272 ssymm_(&side, &uplo, &n, &n, &alpha, a[0], &n, b[0], &n, &alpha, c[0], &n);
275 #endif /* WITH_LAPACK */
278 outerproduct(float32 ** a, float32 * x, float32 * y, int32 len)
282 for (i = 0; i < len; ++i) {
283 a[i][i] = x[i] * y[i];
284 for (j = i + 1; j < len; ++j) {
285 a[i][j] = x[i] * y[j];
286 a[j][i] = x[j] * y[i];
292 scalarmultiply(float32 ** a, float32 x, int32 n)
296 for (i = 0; i < n; ++i) {
298 for (j = i+1; j < n; ++j) {
306 matrixadd(float32 ** a, float32 ** b, int32 n)
310 for (i = 0; i < n; ++i)
311 for (j = 0; j < n; ++j)
317 * Log record. Maintained by RCS.
320 * Revision 1.4 2004/07/21 18:05:40 egouvea
321 * Changed the license terms to make it the same as sphinx2 and sphinx3.
323 * Revision 1.3 2001/04/05 20:02:30 awb
324 * *** empty log message ***
326 * Revision 1.2 2000/09/29 22:35:13 awb
327 * *** empty log message ***
329 * Revision 1.1 2000/09/24 21:38:31 awb
330 * *** empty log message ***
332 * Revision 1.1 97/07/16 11:36:22 eht