#include <math.h>
#include <stdlib.h>
+#define MAX_VAL 1.0e6
+
/* C=A*B */
void mtx_mul(int l, int m, int n, double *a, double *b, double *c) {
int i, jl, jm, k, kl;
* M-->V, that M=V*V'
* works only for M=M' & M>0
*/
-void chol_decomp(int n, double *m, double *v) {
+int chol_decomp(int n, double *m, double *v) {
int i, in, j, jn, kn;
+ int rc, fail = 0;
for (i = 0, in = 0; i < n; i++, in += n) {
for (j = 0, jn = 0; j < i; j++, jn += n) {
for (kn = 0; kn < j*n; kn += n)
v[i+jn] -= v[i+kn]*v[j+kn];
v[i+jn] /= v[j+jn];
+
+ if (!finite(v[i+jn])) {
+ fail = 1;
+ if ((rc = isinf(v[i+jn])))
+ v[i+jn] = rc*MAX_VAL;
+ else if (isnan(v[i+jn]))
+ v[i+jn] = 1.0;
+ }
}
v[i+in] = m[i+in];
for (kn = 0; kn < i*n; kn += n)
v[i+in] -= v[i+kn]*v[i+kn];
v[i+in] = sqrt(v[i+in]);
+
+ if (!finite(v[i+jn])) {
+ fail = 1;
+ v[i+in] = 0.0;
+ }
}
+
+ return fail;
}
/*
* inverts real, symmetric, positive definite matrix M (ie. M>0 & M=M')
* M-->W, that M*W=I
*/
-void chol_inv(int n, double *m, double *w) {
+int chol_inv(int n, double *m, double *w) {
int i, in, j, jn, k, kn;
+ int fail;
- chol_decomp(n, m, w);
+ fail = chol_decomp(n, m, w);
/* W=inv(W)' (fill upper triangle) */
for (i = 0, in = 0; i < n; i++, in += n) {
w[i+in] = 1.0/w[i+in];
+
+ if (!finite(w[i+in])) {
+ fail = 1;
+ w[i+in] = isinf(w[i+in])*MAX_VAL;
+ }
+
for (j = 0; j < i; j++) {
w[j+in] = 0.0;
for (kn = j*n; kn < i*n; kn += n)
for (i = 0, in = 0; i < n-1; i++, in += n)
for (j = i+1, jn = j*n; j < n; j++, jn += n)
w[i+jn] = w[j+in];
+
+ return fail;
}
/* KOHEII, */