1 /*******************************************************************************
2 *
3 * This file is part of the General Hidden Markov Model Library,
4 * GHMM version __VERSION__, see http://ghmm.org
5 *
6 * Filename: ghmm/ghmm/matrix.c
7 * Authors: Bernhard Knab, Benjamin Georgi
8 *
9 * Copyright (C) 1998-2004 Alexander Schliep
10 * Copyright (C) 1998-2001 ZAIK/ZPR, Universitaet zu Koeln
11 * Copyright (C) 2002-2004 Max-Planck-Institut fuer Molekulare Genetik,
12 * Berlin
13 *
14 * Contact: schliep@ghmm.org
15 *
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Library General Public
18 * License as published by the Free Software Foundation; either
19 * version 2 of the License, or (at your option) any later version.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Library General Public License for more details.
25 *
26 * You should have received a copy of the GNU Library General Public
27 * License along with this library; if not, write to the Free
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 *
31 * This file is version $Revision: 2267 $
32 * from $Date: 2009-04-24 11:01:58 -0400 (Fri, 24 Apr 2009) $
33 * last change by $Author: grunau $.
34 *
35 *******************************************************************************/
36
37 #ifdef HAVE_CONFIG_H
38 # include "../config.h"
39 #endif
40
41 #include <math.h>
42 #include <float.h>
43
44 #include "ghmmconfig.h"
45
46 #include "matrix.h"
47 #include "vector.h"
48 #include "model.h"
49 #include "rng.h"
50 #include "randvar.h"
51 #include "mes.h"
52 #include "ghmm_internals.h"
53
54 #include "obsolete.h"
55
56 #ifdef GHMM_OBSOLETE
57 static void lrdecomp (int dim, double **a, double *p);
58 static void lyequalsb (double **a, double *b, double *p, int dim, double *y);
59 static void ltranspxequalsy (double **a, double *y, double *p, int dim,
60 double *x);
61
62 /*============================================================================*/
63
ighmm_cmatrix_read(scanner_t * s,double ** matrix,int max_zeile,int max_spalte)64 int ighmm_cmatrix_read (scanner_t * s, double **matrix, int max_zeile,
65 int max_spalte)
66 {
67 #define CUR_PROC "ighmm_cmatrix_read"
68 int len = 0, zeile = 0;
69 ighmm_scanner_consume (s, '{');
70 if (s->err)
71 return (-1);
72 while (!s->eof && !s->err && s->c - '}') {
73 if (zeile >= max_zeile) {
74 ighmm_scanner_error (s, "too many rows in matrix");
75 return (-1);
76 }
77 /* Memory allocation takes place in scanner_get_double_earray */
78 matrix[zeile] = scanner_get_double_earray (s, &len);
79 if (len != max_spalte) {
80 ighmm_scanner_error (s, "wrong number of elements in matrix");
81 return (-1);
82 }
83 ighmm_scanner_consume (s, ';');
84 if (s->err) {
85 ighmm_scanner_error (s, "missing ';' or wrong number of columns");
86 return (-1);
87 }
88 zeile++;
89 }
90 ighmm_scanner_consume (s, '}');
91 if (s->err)
92 return (-1);
93 if (zeile < max_zeile) {
94 ighmm_scanner_error (s, "rows missing in matrix");
95 return (-1);
96 }
97 return (0);
98 #undef CUR_PROC
99 } /* ighmm_cmatrix_read */
100
101 /*============================================================================*/
102 #endif /* GHHM_OBSOLETE */
103
104 #ifdef GHMM_UNSUPPORTED
ighmm_dmatrix_read(scanner_t * s,int ** matrix,int max_zeile,int max_spalte)105 int ighmm_dmatrix_read (scanner_t * s, int **matrix, int max_zeile, int max_spalte)
106 {
107 #define CUR_PROC "ighmm_dmatrix_read"
108 int len = 0, zeile = 0;
109 ighmm_scanner_consume (s, '{');
110 if (s->err)
111 return (-1);
112 while (!s->eof && !s->err && s->c - '}') {
113 if (zeile >= max_zeile) {
114 ighmm_scanner_error (s, "too many rows in matrix");
115 return (-1);
116 }
117 /* Memory allocation takes place in scanner_get_int_array */
118 matrix[zeile] = scanner_get_int_array (s, &len);
119 if (len != max_spalte) {
120 ighmm_scanner_error (s, "wrong number of elements in matrix");
121 return (-1);
122 }
123 ighmm_scanner_consume (s, ';');
124 if (s->err) {
125 ighmm_scanner_error (s, "missing ';' or wrong number of columns");
126 return (-1);
127 }
128 zeile++;
129 }
130 ighmm_scanner_consume (s, '}');
131 if (s->err)
132 return (-1);
133 if (zeile < max_zeile) {
134 ighmm_scanner_error (s, "rows missing in matrix");
135 return (-1);
136 }
137 return (0);
138 #undef CUR_PROC
139 } /* ighmm_dmatrix_read */
140 #endif /* GHMM_UNSUPPORTED */
141
142 /*============================================================================*/
143
144 /* allocation of matrices with fixed dimensions */
ighmm_cmatrix_stat_alloc(int n,int m)145 double **ighmm_cmatrix_stat_alloc (int n, int m)
146 {
147 #define CUR_PROC "ighmm_cmatrix_stat_alloc"
148 int i;
149 double **A;
150 double *tmp;
151
152 /* if (!(A = ighmm_calloc (n * sizeof (*A) + n * m * sizeof (**A)))) { */
153
154
155 if (!(A = ighmm_calloc (n * sizeof (double*) + n * m * sizeof (double)))) {
156 GHMM_LOG_QUEUED(LCONVERTED);
157 goto STOP;
158 }
159
160 tmp = (double *) (A + n);
161 for (i = 0; i < n; i++) {
162 A[i] = tmp;
163 tmp += m;
164 }
165 return A;
166 STOP:
167 ighmm_cmatrix_stat_free (&A);
168 return NULL;
169 #undef CUR_PROC
170 }
171
172
ighmm_cmatrix_stat_free(double *** matrix)173 int ighmm_cmatrix_stat_free (double ***matrix)
174 {
175 #define CUR_PROC "ighmm_cmatrix_stat_free"
176 mes_check_ptr (matrix, return (-1));
177 if (!*matrix)
178 return (0);
179 free (*matrix);
180 return 0;
181 #undef CUR_PROC
182 }
183
184 /*============================================================================*/
185
186 /* allocation of matrices with fixed dimensions */
ighmm_dmatrix_stat_alloc(int n,int m)187 int **ighmm_dmatrix_stat_alloc(int n, int m)
188 {
189 #define CUR_PROC "ighmm_dmatrix_stat_alloc"
190 int i;
191 int **A;
192 int *tmp;
193 if (!(A = ighmm_calloc (n * sizeof(int*) + n * m * sizeof (int)))) {
194 GHMM_LOG_QUEUED(LCONVERTED);
195 goto STOP;
196 }
197
198 tmp = (int *) (A + n);
199 for (i = 0; i < n; i++) {
200 A[i] = tmp;
201 tmp += m;
202 }
203 return A;
204 STOP:
205 ighmm_dmatrix_stat_free (&A);
206 return NULL;
207 #undef CUR_PROC
208 }
209
210
ighmm_dmatrix_stat_free(int *** matrix)211 int ighmm_dmatrix_stat_free (int ***matrix)
212 {
213 #define CUR_PROC "ighmm_dmatrix_stat_free"
214 mes_check_ptr (matrix, return (-1));
215 if (!*matrix)
216 return (0);
217 free (*matrix);
218 return 0;
219 #undef CUR_PROC
220 }
221
222
223 /*============================================================================*/
224
225
ighmm_cmatrix_alloc(int zeilen,int spalten)226 double **ighmm_cmatrix_alloc (int zeilen, int spalten)
227 {
228 #define CUR_PROC "ighmm_cmatrix_alloc"
229 double **matrix;
230 int i;
231
232 /*printf("*** ighmm_cmatrix_alloc %d zeilen, %d spalten:\n",zeilen, spalten);*/
233
234 ARRAY_CALLOC (matrix, zeilen);
235 for (i = 0; i < zeilen; i++)
236 ARRAY_CALLOC (matrix[i], spalten);
237 return matrix;
238 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
239 ighmm_cmatrix_free (&matrix, zeilen);
240 return NULL;
241 #undef CUR_PROC
242 } /* ighmm_cmatrix_alloc */
243
244
ighmm_cmatrix_3d_alloc(int i,int j,int k)245 double *** ighmm_cmatrix_3d_alloc(int i, int j, int k) {
246 #define CUR_PROC "ighmm_cmatrix_3d_alloc"
247 double *** matrix;
248 int a, b;
249
250 /* printf("*** ighmm_cmatrix_alloc %d zeilen, %d spalten:\n",zeilen, spalten); */
251
252 ARRAY_CALLOC (matrix, i);
253 for (a = 0; a < i; a++) {
254 ARRAY_CALLOC (matrix[a], j);
255 for (b=0; b<j; b++) {
256 ARRAY_CALLOC (matrix[a][b], k);
257 }
258 }
259 return matrix;
260 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
261 ighmm_cmatrix_3d_free(&matrix, i, j);
262 return NULL;
263 #undef CUR_PROC
264 } /* ighmm_cmatrix_3d_alloc */
265
266 /** gets a pointer on a 3d matrix and rows and cols **/
ighmm_cmatrix_3d_free(double **** matrix,int i,int j)267 int ighmm_cmatrix_3d_free(double **** matrix, int i, int j) {
268 # define CUR_PROC "ighmm_cmatrix_3d_free"
269 int a,b;
270 mes_check_ptr(matrix, return(-1));
271 if ( !*matrix) return(0);
272 for (a = i - 1; a >= 0; a--) {
273 for (b=j-1; b>=0; b--)
274 m_free((*matrix)[a][b]);
275 m_free((*matrix)[a]);
276 }
277 m_free(*matrix);
278 return (0);
279 # undef CUR_PROC
280 } /* ighmm_cmatrix_3d_free */
281
ighmm_cmatrix_free(double *** matrix,long rows)282 int ighmm_cmatrix_free(double ***matrix, long rows) {
283 # define CUR_PROC "ighmm_cmatrix_free"
284 long i;
285 mes_check_ptr(matrix, return (-1));
286
287 if (*matrix) {
288 for (i=0; i<rows; i++)
289 m_free((*matrix)[i]);
290 m_free(*matrix);
291 }
292 return (0);
293 # undef CUR_PROC
294 } /* ighmm_cmatrix_free */
295
296
297
298 /*============================================================================*/
299
300
301
ighmm_cmatrix_alloc_copy(int zeilen,int spalten,double ** copymatrix)302 double **ighmm_cmatrix_alloc_copy (int zeilen, int spalten, double **copymatrix)
303 {
304 #define CUR_PROC "ighmm_cmatrix_alloc_copy"
305 double **matrix;
306 int i, j;
307 ARRAY_CALLOC (matrix, zeilen);
308 for (i = 0; i < zeilen; i++) {
309 ARRAY_CALLOC (matrix[i], spalten);
310 for (j = 0; j < spalten; j++)
311 matrix[i][j] = copymatrix[i][j];
312 }
313 return matrix;
314 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
315 ighmm_cmatrix_free (&matrix, zeilen);
316 return NULL;
317 #undef CUR_PROC
318 } /* ighmm_cmatrix_alloc_copy */
319
320 /*============================================================================*/
321
ighmm_dmatrix_alloc(int zeilen,int spalten)322 int **ighmm_dmatrix_alloc (int zeilen, int spalten)
323 {
324 #define CUR_PROC "ighmm_dmatrix_alloc"
325 int **matrix;
326 int i;
327 ARRAY_CALLOC (matrix, zeilen);
328 for (i = 0; i < zeilen; i++)
329 ARRAY_CALLOC (matrix[i], spalten);
330 return matrix;
331 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
332 ighmm_dmatrix_free (&matrix, zeilen);
333 return NULL;
334 #undef CUR_PROC
335 } /* ighmm_dmatrix_alloc */
336
337 /*============================================================================*/
338
ighmm_dmatrix_free(int *** matrix,long rows)339 int ighmm_dmatrix_free (int ***matrix, long rows)
340 {
341 # define CUR_PROC "ighmm_dmatrix_free"
342 long i;
343 mes_check_ptr (matrix, return (-1));
344 if (*matrix) {
345 for (i=0; i<rows; i++)
346 m_free((*matrix)[i]);
347 m_free(*matrix);
348 }
349 return (0);
350 # undef CUR_PROC
351 } /* ighmm_dmatrix_free */
352
353 /*============================================================================*/
354 /*============================================================================*/
355
ighmm_dmatrix_3d_alloc(int zeilen,int spalten,int hoehe)356 int*** ighmm_dmatrix_3d_alloc(int zeilen, int spalten, int hoehe) {
357 #define CUR_PROC "ighmm_dmatrix_alloc"
358 int ***matrix;
359 int i, j;
360 ARRAY_CALLOC (matrix, zeilen);
361 for (i = 0; i < zeilen; i++) {
362 ARRAY_CALLOC (matrix[i], spalten);
363 for (j=0; j < spalten; j++)
364 ARRAY_CALLOC (matrix[i][j], hoehe);
365 }
366 return matrix;
367 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
368 ighmm_dmatrix_3d_free(&matrix, zeilen, spalten);
369 return NULL;
370 #undef CUR_PROC
371 } /* ighmm_dmatrix_3d_alloc */
372
373 /*============================================================================*/
374
ighmm_dmatrix_3d_free(int **** matrix,int zeilen,int spalten)375 int ighmm_dmatrix_3d_free(int **** matrix, int zeilen, int spalten) {
376 # define CUR_PROC "ighmm_dmatrix_free"
377 long i, j;
378 mes_check_ptr(matrix, return(-1));
379 if ( !*matrix ) return(0);
380 for (i = zeilen - 1; i >= 0; i--) {
381 for (j=spalten - 1; j >= 0; j--)
382 m_free((*matrix)[i][j]);
383 m_free((*matrix)[i]);
384 }
385 m_free(*matrix);
386 return (0);
387 # undef CUR_PROC
388 } /* ighmm_dmatrix_3d_free */
389
390
391 #ifdef GHMM_OBSOLETE
392 /*============================================================================*/
ighmm_cmatrix_print(FILE * file,double ** matrix,int zeilen,int spalten,char * tab,char * separator,char * ending)393 void ighmm_cmatrix_print(FILE *file, double **matrix, int zeilen, int spalten,
394 char *tab, char *separator, char *ending) {
395 int i;
396 for (i = 0; i < zeilen; i++)
397 ighmm_cvector_print (file, matrix[i], spalten, tab, separator, ending);
398 } /* ighmm_cmatrix_print */
399 #endif /* GHMM_OBSOLETE */
400
401 #ifdef GHMM_UNSUPPORTED
402 /*============================================================================*/
ighmm_cmatrix_print_prec(FILE * file,double ** matrix,int zeilen,int spalten,int width,int prec,char * tab,char * separator,char * ending)403 void ighmm_cmatrix_print_prec (FILE * file, double **matrix, int zeilen,
404 int spalten, int width, int prec, char *tab,
405 char *separator, char *ending)
406 {
407 int i;
408 for (i = 0; i < zeilen; i++)
409 ighmm_cvector_print_prec (file, matrix[i], spalten, width, prec,
410 tab, separator, ending);
411 } /* ighmm_cmatrix_print_prec */
412
413 /*============================================================================*/
ighmm_dmatrix_print(FILE * file,int ** matrix,int zeilen,int spalten,char * tab,char * separator,char * ending)414 void ighmm_dmatrix_print (FILE * file, int **matrix, int zeilen, int spalten,
415 char *tab, char *separator, char *ending)
416 {
417 int i;
418 for (i = 0; i < zeilen; i++)
419 ighmm_dvector_print (file, matrix[i], spalten, tab, separator, ending);
420 } /* ighmm_dmatrix_print */
421 #endif /* GHMM_UNSUPPORTED */
422
423 #ifdef GHMM_OBSOLETE
424 /*============================================================================*/
ighmm_cmatrix_notzero_columns(double ** matrix,int row,int max_col)425 int ighmm_cmatrix_notzero_columns (double **matrix, int row, int max_col)
426 {
427 int i, count = 0;
428 for (i = 0; i < max_col; i++)
429 if (matrix[row][i])
430 count++;
431 return count;
432 } /* ighmm_cmatrix_notzero_columns */
433
434 /*============================================================================*/
ighmm_cmatrix_notzero_rows(double ** matrix,int col,int max_row)435 int ighmm_cmatrix_notzero_rows (double **matrix, int col, int max_row)
436 {
437 int i, count = 0;
438 for (i = 0; i < max_row; i++)
439 if (matrix[i][col])
440 count++;
441 return count;
442 } /* matrix_d__notzero_rows */
443
444 /*============================================================================*/
445 /* Scales the row vectors of a matrix to have the sum 1 */
ighmm_cmatrix_normalize(double ** matrix,int rows,int cols)446 int ighmm_cmatrix_normalize (double **matrix, int rows, int cols)
447 {
448 #define CUR_PROC "ighmm_cmatrix_normalize"
449 int i;
450 for (i = 0; i < rows; i++)
451 if (ighmm_cvector_normalize (matrix[i], cols) == -1)
452 ighmm_mes (MES_WIN, "WARNING: sum row[%d] == 0!\n", i);
453 /* return (-1); */
454 return 0;
455 #undef CUR_PROC
456 } /* ighmm_cmatrix_normalize */
457
458 /*============================================================================*/
ighmm_cmatrix_random_values(double ** matrix,int rows,int cols,double min,double max)459 void ighmm_cmatrix_random_values (double **matrix, int rows, int cols,
460 double min, double max)
461 {
462 int i, j;
463 double interval;
464 if (max < min) {
465 min = 0.0;
466 max = 1.0;
467 }
468 interval = max - min;
469 for (i = 0; i < rows; i++)
470 for (j = 0; j < cols; j++)
471 matrix[i][j] = min + GHMM_RNG_UNIFORM (RNG) * interval;
472 } /* ighmm_cmatrix_random_values */
473
474 /*============================================================================*/
475 /* Fixed value for final state */
ighmm_cmatrix_random_const_values(double ** matrix,int rows,int cols,double min,double max,double c)476 void ighmm_cmatrix_random_const_values (double **matrix, int rows, int cols,
477 double min, double max, double c)
478 {
479 int i, j;
480 double interval;
481 if (rows < 1) {
482 ighmm_mes (MES_WIN, "WARNING: rows = %d not allowed\n", rows);
483 return;
484 }
485 if (max < min) {
486 min = 0.0;
487 max = 1.0;
488 }
489 interval = max - min;
490 for (i = 0; i < rows - 1; i++)
491 for (j = 0; j < cols; j++)
492 matrix[i][j] = min + GHMM_RNG_UNIFORM (RNG) * interval;
493 for (j = 0; j < cols; j++)
494 matrix[rows - 1][j] = c;
495 } /* ighmm_cmatrix_random_const_values */
496
497
498 /*============================================================================*/
ighmm_cmatrix_const_values(double ** matrix,int rows,int cols,double c)499 void ighmm_cmatrix_const_values (double **matrix, int rows, int cols, double c)
500 {
501 int i, j;
502 for (i = 0; i < rows; i++)
503 for (j = 0; j < cols; j++)
504 matrix[i][j] = c;
505 } /* ighmm_cmatrix_const_values */
506
507 /*============================================================================*/
ighmm_cmatrix_random_left_right(double ** matrix,int rows,int cols)508 void ighmm_cmatrix_random_left_right (double **matrix, int rows, int cols)
509 {
510 int i, j;
511 for (i = 0; i < rows; i++)
512 for (j = 0; j < cols; j++)
513 if (j == i || j == i + 1)
514 matrix[i][j] = GHMM_RNG_UNIFORM (RNG);
515 else
516 matrix[i][j] = 0.0;
517 } /* ighmm_cmatrix_random_values */
518
519 /*============================================================================*/
ighmm_cmatrix_left_right_strict(double ** matrix,int rows,int cols)520 void ighmm_cmatrix_left_right_strict (double **matrix, int rows, int cols)
521 {
522 int i, j;
523 for (i = 0; i < rows; i++)
524 for (j = 0; j < cols; j++)
525 if (j == i + 1)
526 matrix[i][j] = 1.0;
527 else
528 matrix[i][j] = 0.0;
529 } /* ighmm_cmatrix_left_right_strict */
530
531 /*============================================================================*/
ighmm_cmatrix_gaussrows_values(double ** matrix,int rows,int cols,double ** mue,double u)532 int ighmm_cmatrix_gaussrows_values (double **matrix, int rows, int cols,
533 double **mue, double u)
534 {
535 # define CUR_PROC "matrix_gaussrows_values"
536 int res = -1;
537 double *mean;
538 int i, j;
539 if (u <= 0.0) {
540 GHMM_LOG(LCONVERTED, "sigma^2 <= 0.0 not allowed\n");
541 goto STOP;
542 }
543 if (*mue == NULL) {
544 /* for each row, a random mean value mean[i] in (0, cols-1) */
545 ARRAY_CALLOC (mean, rows);
546 for (i = 0; i < rows; i++)
547 mean[i] = GHMM_RNG_UNIFORM (RNG) * (cols - 1);
548 /* for (i = 0; i < rows; i++) printf("%6.4f ", mean[i]); printf("\n"); */
549 *mue = mean;
550 }
551 else
552 /* Check, if the mean value is on the right interval */
553 mean = *mue;
554 for (i = 0; i < rows; i++) {
555 /* Gauss-distribution around the mean value for each state. */
556 for (j = 0; j < cols; j++) {
557 matrix[i][j] = ighmm_rand_normal_density ((double) j, mean[i], u);
558 if (matrix[i][j] == -1) {
559 GHMM_LOG_QUEUED(LCONVERTED);
560 goto STOP;
561 }
562 /* To avoid zero: (Cheap version!!) */
563 if (matrix[i][j] < 0.0001)
564 matrix[i][j] = 0.0001; /* The Output has only 4 significant digits! */
565 }
566 }
567 res = 0;
568 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
569 return (res);
570 # undef CUR_PROC
571 } /* matrix_gaussrows_values */
572
573 /*============================================================================*/
ighmm_cmatrix_const_preserve_struct(double ** matrix,int rows,int cols,double c)574 void ighmm_cmatrix_const_preserve_struct (double **matrix, int rows, int cols,
575 double c)
576 {
577 int i, j;
578 for (i = 0; i < rows; i++)
579 for (j = 0; j < cols; j++) {
580 if (matrix[i][j] != 0)
581 matrix[i][j] = c;
582 }
583 } /* ighmm_cmatrix_const_preserve_struct */
584
585 /*============================================================================*/
ighmm_cmatrix_random_preserve_struct(double ** matrix,int rows,int cols)586 void ighmm_cmatrix_random_preserve_struct (double **matrix, int rows, int cols)
587 {
588 int i, j;
589 for (i = 0; i < rows; i++)
590 for (j = 0; j < cols; j++) {
591 if (matrix[i][j] != 0)
592 matrix[i][j] = GHMM_RNG_UNIFORM (RNG);
593 }
594 } /* ighmm_cmatrix_random_preserve_struct */
595
596 /*============================================================================*/
ighmm_cmatrix_transpose(double ** A,int rows,int cols,double ** A_T)597 void ighmm_cmatrix_transpose (double **A, int rows, int cols, double **A_T)
598 {
599 int i, j;
600 for (i = 0; i < rows; i++)
601 for (j = 0; j < cols; j++)
602 A_T[j][i] = A[i][j];
603 } /* ighmm_cmatrix_transpose */
604
605
606 /*----------------------------------------------------------------------------*/
607 /* Decomposes a positiv definit, symmetric matrix A in L*L-T, that is except for
608 the diagonal, L (= lower triangular marix) is stored in A. The Diagonal is
609 stored in a vector p.
610 */
lrdecomp(int dim,double ** a,double * p)611 static void lrdecomp (int dim, double **a, double *p)
612 {
613 int k, i, j;
614 double x;
615 for (i = 0; i < dim; i++) {
616 for (j = i; j < dim; j++) {
617 x = a[i][j];
618 for (k = i - 1; k >= 0; k--)
619 x = x - a[j][k] * a[i][k];
620 if (i == j) {
621 if (x < DBL_MIN)
622 ighmm_mes (MES_WIN, "FEHLER: Pivotel.<=0!");
623 p[i] = 1 / sqrt (x);
624 }
625 else
626 a[j][i] = x * p[i];
627 }
628 }
629 }
630
631 /*----------------------------------------------------------------------------*/
632 /* Solves L*y=b, L is a lower triangular matrix stored in A, p=1/diagonal elements. */
lyequalsb(double ** a,double * b,double * p,int dim,double * y)633 static void lyequalsb (double **a, double *b, double *p, int dim, double *y)
634 {
635 int k, j;
636 for (k = 0; k < dim; k++) {
637 y[k] = b[k];
638 for (j = 0; j < k; j++)
639 y[k] = y[k] - a[k][j] * y[j];
640 y[k] = y[k] * p[k];
641 }
642 }
643
644 /*----------------------------------------------------------------------------*/
645 /* Solves L-T*x=y, L-T an upper triangular matrix, BUT saved in A as L! */
ltranspxequalsy(double ** a,double * y,double * p,int dim,double * x)646 static void ltranspxequalsy (double **a, double *y, double *p, int dim,
647 double *x)
648 {
649 int k, j;
650 for (k = dim - 1; k >= 0; k--) {
651 x[k] = y[k];
652 for (j = k + 1; j < dim; j++)
653 x[k] = x[k] - a[j][k] * x[j];
654 x[k] = x[k] * p[k];
655 }
656 }
657
658
659 /*============================================================================*/
660 /* Solves a linear equation system for a symmetric, positiv definite matrix. */
ighmm_cmatrix_cholesky(double ** a,double * b,int dim,double * x)661 int ighmm_cmatrix_cholesky (double **a, double *b, int dim, double *x)
662 {
663 #define CUR_PROC "ighmm_cmatrix_cholesky"
664 int res = -1;
665 double *p, *y;
666 ARRAY_CALLOC (p, dim);
667 ARRAY_CALLOC (y, dim);
668 lrdecomp (dim, a, p);
669 lyequalsb (a, b, p, dim, y);
670 ltranspxequalsy (a, y, p, dim, x);
671 res = 0;
672 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
673 return (res);
674 #undef CUR_PROC
675 }
676
677 /* Finds the determinant of a symetric, positiv definit matrix. */
ighmm_cmatrix_det_symposdef(double ** a,int dim,double * det)678 int ighmm_cmatrix_det_symposdef (double **a, int dim, double *det)
679 {
680 #define CUR_PROC "ighmm_cmatrix_det_symposdef"
681 int res = -1;
682 int i;
683 double *p, r;
684 ARRAY_CALLOC (p, dim);
685 lrdecomp (dim, a, p);
686 *det = 1.0;
687 for (i = 0; i < dim; i++) {
688 r = 1 / p[i];
689 *det *= (r * r);
690 }
691 res = 0;
692 STOP: /* Label STOP from ARRAY_[CM]ALLOC */
693 return (res);
694 #undef CUR_PROC
695 }
696
697 /*============================================================================*/
698 /* Copies a matrix, the memory allocations must to be done outside! */
ighmm_cmatrix_copy(double ** src,double ** target,int rows,int cols)699 void ighmm_cmatrix_copy (double **src, double **target, int rows, int cols)
700 {
701 int i, j;
702
703 for (i = 0; i < rows; i++)
704 for (j = 0; j < cols; j++)
705 target[i][j] = src[i][j];
706 }
707
708 /*============================================================================*/
709 /**
710 Checks whether a quadratic double matrix is stochastic
711 @return 0/1 flag for true/false
712 @param matrix double NxN matrix to be checked
713 @param N number of rows/columns (matrix must be quadaratic)
714 */
ighmm_cmatrix_check_stochasticity(double ** matrix,int N)715 int ighmm_cmatrix_check_stochasticity (double **matrix, int N)
716 {
717 int i, j;
718 double row_sum;
719 int stochastic = 1;
720
721 for (i = 0; i < N; i++) {
722 row_sum = 0.0;
723 for (j = 0; j < N; j++) {
724 row_sum = row_sum + matrix[i][j];
725 }
726 if (row_sum != 1.0) {
727 stochastic = 0;
728 break;
729 }
730 }
731 return (stochastic);
732 }
733 #endif /* GHMM_OBSOLETE */
734