/*============================================================================*/ double ighmm_rand_std_normal (int seed) { double r2, theta; # define CUR_PROC "ighmm_rand_std_normal" if (seed != 0) { GHMM_RNG_SET (RNG, seed); } #ifdef DO_WITH_GSL return (gsl_ran_gaussian (RNG, 1.0)); #else /* Use the polar Box-Mueller transform */ /* double x, y, r2; do { x = 2.0 * GHMM_RNG_UNIFORM(RNG) - 1.0; y = 2.0 * GHMM_RNG_UNIFORM(RNG) - 1.0; r2 = (x * x) + (y * y); } while (r2 >= 1.0); return x * sqrt((-2.0 * log(r2)) / r2); */ r2 = -2.0 * log (GHMM_RNG_UNIFORM (RNG)); /* r2 ~ chi-square(2) */ theta = 2.0 * PI * GHMM_RNG_UNIFORM (RNG); /* theta ~ uniform(0, 2 \pi) */ return sqrt (r2) * cos (theta); #endif # undef CUR_PROC } /* ighmm_rand_std_normal */
/*============================================================================*/ void ighmm_cvector_random_preserve_struct (double *v, int len) { int i; for (i = 0; i < len; i++) { if (v[i] != 0.0) v[i] = GHMM_RNG_UNIFORM (RNG); } } /* ighmm_cvector_random_preserve_struct */
double ighmm_rand_normal_right (double a, double mue, double u, int seed) { # define CUR_PROC "ighmm_rand_normal_right" double x = -1; double sigma; #ifdef DO_WITH_GSL double s; #else double U, Us, Us1, Feps, t, T; #endif if (u <= 0.0) { GHMM_LOG(LCONVERTED, "u <= 0.0 not allowed\n"); goto STOP; } sigma = sqrt(u); if (seed != 0) { GHMM_RNG_SET (RNG, seed); } #ifdef DO_WITH_GSL /* move boundary to lower values in order to achieve maximum at mue gsl_ran_gaussian_tail(generator, lower_boundary, sigma) */ return mue + gsl_ran_gaussian_tail(RNG, a - mue, sqrt (u)); #else /* DO_WITH_GSL */ /* Inverse transformation with restricted sampling by Fishman */ U = GHMM_RNG_UNIFORM(RNG); Feps = ighmm_rand_get_PHI((a-mue) / sigma); Us = Feps + (1-Feps) * U; Us1 = 1-Us; t = m_min (Us, Us1); t = sqrt (-log (t * t)); T = sigma * (t - (C0 + t * (C1 + t * C2)) / (1 + t * (D1 + t * (D2 + t * D3)))); if (Us < Us1) x = mue - T; else x = mue + T; #endif /* DO_WITH_GSL */ STOP: return x; # undef CUR_PROC } /* randvar_normal_pos */
/*============================================================================*/ double ighmm_rand_uniform_int (int seed, int K) { # define CUR_PROC "ighmm_rand_uniform_int" if (seed != 0) { GHMM_RNG_SET (RNG, seed); } #ifdef DO_WITH_GSL /* more direct solution than old version ! */ return (double) gsl_rng_uniform_int (RNG, K); #else return (double) ((int) (((double) K) * GHMM_RNG_UNIFORM (RNG))); #endif # undef CUR_PROC } /* ighmm_rand_uniform_int */
/*===========================================================================*/ double ighmm_rand_uniform_cont (int seed, double max, double min) { # define CUR_PROC "ighmm_rand_uniform_cont" if (max <= min) { GHMM_LOG(LCONVERTED, "max <= min not allowed\n"); goto STOP; } if (seed != 0) { GHMM_RNG_SET (RNG, seed); } #ifdef DO_WITH_GSL return (double)(((double)gsl_rng_uniform (RNG)*(max-min)) + min); #else return (double)((GHMM_RNG_UNIFORM (RNG))*(max-min) + min ); #endif STOP: return (-1.0); # undef CUR_PROC } /* ighmm_rand_uniform_cont */
/*============================================================================*/ void ighmm_cvector_random_values (double *v, int len) { int i; for (i = 0; i < len; i++) v[i] = GHMM_RNG_UNIFORM (RNG); } /* ighmm_cvector_random_values */
ghmm_cseq *ghmm_sgenerate_extensions (ghmm_cmodel * smo, ghmm_cseq * sqd_short, int seed, int global_len, sgeneration_mode_t mode) { #define CUR_PROC "ghmm_sgenerate_extensions" ghmm_cseq *sq = NULL; int i, j, t, n, m, len = global_len, short_len, max_short_len = 0, up = 0; #ifdef bausparkasse int tilgphase = 0; #endif /* int *v_path = NULL; */ double log_p, *initial_distribution, **alpha, *scale, p, sum; /* aicj */ int class = -1; int pos; /* TEMP */ if (mode == all_viterbi || mode == viterbi_viterbi || mode == viterbi_all) { GHMM_LOG(LCONVERTED, "Error: mode not implemented yet\n"); goto STOP; } if (len <= 0) /* no global length; model should have a final state */ len = (int) GHMM_MAX_SEQ_LEN; max_short_len = ghmm_cseq_max_len (sqd_short); /*---------------alloc-------------------------------------------------*/ sq = ghmm_cseq_calloc (sqd_short->seq_number); if (!sq) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } ARRAY_CALLOC (initial_distribution, smo->N); /* is needed in cfoba_forward() */ alpha = ighmm_cmatrix_alloc (max_short_len, smo->N); if (!alpha) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } ARRAY_CALLOC (scale, max_short_len); ghmm_rng_init (); GHMM_RNG_SET (RNG, seed); /*---------------main loop over all seqs-------------------------------*/ for (n = 0; n < sqd_short->seq_number; n++) { ARRAY_CALLOC (sq->seq[n], len*(smo->dim)); short_len = sqd_short->seq_len[n]; if (len < short_len) { GHMM_LOG(LCONVERTED, "Error: given sequence is too long\n"); goto STOP; } ghmm_cseq_copy (sq->seq[n], sqd_short->seq[n], short_len); #ifdef GHMM_OBSOLETE sq->seq_label[n] = sqd_short->seq_label[n]; #endif /* GHMM_OBSOLETE */ /* Initial distribution */ /* 1. Viterbi-state */ #if 0 /* wieder aktivieren, wenn ghmm_cmodel_viterbi realisiert */ if (mode == viterbi_all || mode == viterbi_viterbi) { v_path = cviterbi (smo, sqd_short->seq[n], short_len, &log_p); if (v_path[short_len - 1] < 0 || v_path[short_len - 1] >= smo->N) { GHMM_LOG(LCONVERTED, "Warning:Error: from viterbi()\n"); sq->seq_len[n] = short_len; m_realloc (sq->seq[n], short_len); continue; } m_memset (initial_distribution, 0, smo->N); initial_distribution[v_path[short_len - 1]] = 1.0; /* all other 0 */ m_free (v_path); } #endif /* 2. Initial Distribution ??? Pi(i) = alpha_t(i)/P(O|lambda) */ if (mode == all_all || mode == all_viterbi) { if (short_len > 0) { if (ghmm_cmodel_forward (smo, sqd_short->seq[n], short_len, NULL /* ?? */ , alpha, scale, &log_p)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } sum = 0.0; for (i = 0; i < smo->N; i++) { /* alpha ist skaliert! */ initial_distribution[i] = alpha[short_len - 1][i]; sum += initial_distribution[i]; } /* nicht ok.? auf eins skalieren? */ for (i = 0; i < smo->N; i++) initial_distribution[i] /= sum; } else { for (i = 0; i < smo->N; i++) initial_distribution[i] = smo->s[i].pi; } } /* if short_len > 0: Initial state == final state from sqd_short; no output here else choose inittial state according to pi and do output */ p = GHMM_RNG_UNIFORM (RNG); sum = 0.0; for (i = 0; i < smo->N; i++) { sum += initial_distribution[i]; if (sum >= p) break; } /* error due to incorrect normalization ?? */ if (i == smo->N) { i--; while (i > 0 && initial_distribution[i] == 0.0) i--; } t = 0; pos = t * smo->dim; if (short_len == 0) { /* Output in state i */ p = GHMM_RNG_UNIFORM (RNG); sum = 0.0; for (m = 0; m < smo->M; m++) { sum += smo->s[i].c[m]; if (sum >= p) break; } /* error due to incorrect normalization ?? */ if (m == smo->M) { m--; while (m > 0 && smo->s[i].c[m] == 0.0) m--; } ghmm_cmodel_get_random_var(smo, i, m, sq->seq[n]+pos); if (smo->cos == 1) { class = 0; } else { if (!smo->class_change->get_class) { printf ("ERROR: get_class not initialized\n"); goto STOP; } /*printf("1: cos = %d, k = %d, t = %d\n",smo->cos,smo->class_change->k,t);*/ class = smo->class_change->get_class (smo, sq->seq[n], n, t); } t++; pos += smo->dim; }
double randvar_normal_pos (double mue, double u, int seed) { # define CUR_PROC "randvar_normal_pos" double x = -1; double sigma; #ifdef DO_WITH_GSL double s; #else double U, Us, Us1, Feps, Feps1, t, T; #endif if (u <= 0.0) { mes_prot ("u <= 0.0 not allowed\n"); goto STOP; } sigma = sqrt (u); if (seed != 0) { GHMM_RNG_SET (RNG, seed); return (1.0); } #ifdef DO_WITH_GSL /* up to version 0.8 gsl_ran_gaussian_tail can not handle negative cutoff */ #define GSL_RAN_GAUSSIAN_TAIL_BUG 1 #ifdef GSL_RAN_GAUSSIAN_TAIL_BUG s = (-mue) / sigma; if (s < 1) { do { x = gsl_ran_gaussian (RNG, 1.0); } while (x < s); return x * sigma + mue; } #endif /* GSL_RAN_GAUSSIAN_TAIL_BUG */ /* move boundary to lower values in order to achieve maximum at mue gsl_ran_gaussian_tail(generator, lower_boundary, sigma) */ return gsl_ran_gaussian_tail (RNG, -mue, sqrt (u)) + mue; #else /* DO_WITH_GSL */ /* Method: Generate Gauss-distributed random nunbers (with GSL-lib.), until a positive one is found -> not very effective if mue << 0 while (x < 0.0) { x = sigma * randvar_std_normal(seed) + mue; } */ /* Inverse transformation with restricted sampling by Fishman */ U = GHMM_RNG_UNIFORM (RNG); Feps = randvar_get_PHI (-(EPS_NDT + mue) / sigma); Us = Feps + (1 - Feps) * U; /* Numerically better: 1-Us = 1-Feps - (1-Feps)*U, therefore: Feps1 = 1-Feps, Us1 = 1-Us */ Feps1 = randvar_get_PHI ((EPS_NDT + mue) / sigma); Us1 = Feps1 - Feps1 * U; t = m_min (Us, Us1); t = sqrt (-log (t * t)); T = sigma * (t - (C0 + t * (C1 + t * C2)) / (1 + t * (D1 + t * (D2 + t * D3)))); if (Us - 0.5 < 0) x = mue - T; else x = mue + T; #endif /* DO_WITH_GSL */ STOP: return (x); # undef CUR_PROC } /* randvar_normal_pos */