14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  jacobi.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#ifndef _RTT
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdio.h>
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdlib.h>
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 "portable.h"
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#undef EPSILON
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define EPSILON         0.00000001
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MAX_ITER      100
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEFAULT_MAX_PC_DIFF     0.0001
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEFAULT_MAX_OFF_DIAG 0.0001
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void   Rotate(double **a, int dim, int i, int j, int k, int l, double s,
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                     double tau);
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic double SumOffDiag(double **mat, int dim);
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* ------------------------------------------------------------------------ */
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid Jacobi(double **matrix, int dim, double *egval, double **egvec)
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//    Compute all eigenvalues and eigenvectors of the real symmetric matrix
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//    <mat>  of size  <dim>x<dim>.  Fills in <egval> with the eigenvalues
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//    and  <egvec[i]>  with the i-th normalized eignevector of  <mat>.
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project*/
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int    i, j, k;
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int    nRotations,  /* number of Jacobi rotations that are performed */
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  iter;
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  double g, thresh, sum, c, s, t, tau, h;
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  double *b, *d, *z;
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  double **v, **a;
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(matrix);
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(egval);
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(egvec);
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  b = (double *) CALLOC(dim, sizeof(double), "clib.jacobi.b");
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  d = (double *) CALLOC(dim, sizeof(double), "clib.jacobi.d");
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  z = (double *) CALLOC(dim, sizeof(double), "clib.jacobi.z");
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  a = (double **) CALLOC(dim, sizeof(double *), "clib.jacobi.input_jacobi");
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  v = (double **) CALLOC(dim, sizeof(double *), "clib.jacobi.input_jacobi");
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < dim; i++)
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    a[i] = (double *) CALLOC(dim, sizeof(double), "clib.jacobi.input_jacobi[]");
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    v[i] = (double *) CALLOC(dim, sizeof(double), "clib.jacobi.input_jacobi[]");
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (j = 0; j < dim; j++)
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      a[i][j] = (float) matrix[i][j];
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* initialize v to identity matrix, d and b to the diagonal of mat */
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < dim; i++)
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    v[i][i] = 1.0;
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    b[i] = d[i] = a[i][i];
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  nRotations = 0;
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  iter = 0;
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  while (1)
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sum = SumOffDiag(a, dim);
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (sum < EPSILON)    /* normal convergence */
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      log_report("\nConverged after %u iterations", iter);
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      break;
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (iter >= MAX_ITER)
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      log_report("\nMax number %u of iterations reached",
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 MAX_ITER);
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      break;
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (iter < 3)
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      thresh = 20.0 * sum / (dim * dim);    /* .. first 3 iterations only */
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      thresh = 0.0;                    /* .. thereafter */
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0; i < dim - 1; i++)
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (j = i + 1; j < dim; j++)
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        g = 100.0 * fabs(a[i][i]);
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* after 4 iter's, skip rotation if off-diag elmt is small */
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if ((iter >= 4) && (g < EPSILON*fabs(d[i]))
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            && (g < EPSILON*fabs(d[j])))
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          a[i][i] = 0.0;
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (g > thresh)
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          h = d[j] - d[i];
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          if (g < EPSILON*fabs(h))
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            t = a[i][j] / h;
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          else
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          {
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            double theta = 0.5 * h / a[i][j];
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (theta < 0.0)  t = -t;
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          }
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          c = 1.0 / sqrt(1 + t * t);
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          s = t * c;
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          tau = s / (1.0 + c);
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          h = t * a[i][j];
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          z[i] -= h;
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          z[j] += h;
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          d[i] -= h;
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          d[j] += h;
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          a[i][j] = 0.0;
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          for (k = 0  ; k < i;   k++)  Rotate(a, dim, k, i, k, j, s, tau);
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          for (k = i + 1; k < j;   k++)  Rotate(a, dim, i, k, k, j, s, tau);
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          for (k = j + 1; k < dim; k++)  Rotate(a, dim, i, k, j, k, s, tau);
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          for (k = 0;   k < dim; k++)  Rotate(v, dim, k, i, k, j, s, tau);
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          nRotations++;
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0; i < dim; i++)    /* update d[] and re-initialize z[] */
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      b[i] += z[i];
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      d[i] = b[i];
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      z[i] = 0.0;
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    iter++;
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* save eigenvectors and eigenvalues */
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < dim; i++)
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* the i-th column of v is the i-th eigenvector */
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (j = 0; j < dim; j++)  egvec[i][j] = v[j][i]; /* TODO: should this be egvec[j][i] */
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* the i-th entry of d is the i-th eigenvalue */
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    egval[i] = d[i];
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  log_report("\nDiagonalization required %u Jacobi rotations",
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             nRotations);
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)b);
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)d);
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)z);
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < dim; i++)
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    FREE((char *)a[i]);
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    FREE((char *)v[i]);
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)a);
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)v);
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* ------------------------------------------------------------------------ */
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void Rotate(double **a, int dim, int i, int j, int k, int l, double s,
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                   double tau)
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  double g = a[i][j],
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             h = a[k][l];
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  a[i][j] = g - s * (h + g * tau);
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  a[k][l] = h + s * (g - h * tau);
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic double SumOffDiag(double **mat, int dim)
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//    Compute the sum of the absolute values of the off-diagonal elements
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project**/
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int    i, j;
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  double sum = 0.0;
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < dim - 1; i++)
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (j = i + 1; j < dim; j++)
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      sum += fabs(mat[i][j]);
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (sum);
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
219