static void exp_mixw(float32 ***out, /* the mixture weight matrix for all shared states */ int32 **in, /* mixture weights for states in a given CI phone */ uint32 ci_id, /* the CI phone associated with the input weights */ uint32 ci_only, /* Do CI initialization of non-CI mixture weights */ uint32 *cluster_offset,/* mixture weight array offsets */ uint32 *state_of) /* the model state associated with each senone. Used only * for CI initialization of CD weights. */ { uint32 cd_n_seno; /* # of context dependent senones */ uint32 s_out_org; /* the first weight id under this CI_ID in the output matrix */ uint32 s_out_next; /* the first weight id of the next ci in the output matrix */ uint32 s_out_ci_begin; /* the first CI weight of this CI_ID in the output matrix */ uint32 s_out_ci_next; /* the next CI weight after the last CI weight for this CI_ID */ uint32 s_in_ci_org; /* the first weight id of the ci weights in the input matrix */ uint32 f; /* a feature stream id */ uint32 s_in; /* a weight id in the input matrix */ uint32 s_out; /* a weight id in the output matrix */ uint32 cw; /* a codeword index */ s_out_org = cluster_offset[ci_id]; s_out_next = cluster_offset[ci_id+1]; if (!ci_only) cd_n_seno = s_out_next - s_out_org; else cd_n_seno = 0; s_in_ci_org = cd_n_seno; s_out_ci_begin = ci_id * (S2_N_STATE-1); s_out_ci_next = s_out_ci_begin + (S2_N_STATE-1); E_INFO("converting log(weights) to weights\n"); for (f = 0; f < S2_N_FEATURE; f++) { for (s_out = s_out_ci_begin, s_in = s_in_ci_org; s_out < s_out_ci_next; s_out++, s_in++) { printf("CI %d %u <- %u :\n", f, s_out, s_in); for (cw = 0; cw < S2_N_CODEWORD; cw++) { out[s_out][f][cw] = EXP(in[f][s_in*S2_N_CODEWORD + cw]); } } if (ci_only) { /* clone the CD mixture weights from the CI ones */ for (s_out = s_out_org; s_out < s_out_next; s_out++) { /* figure out which CI weights we need */ s_in = s_out_ci_begin + state_of[s_out]; for (cw = 0; cw < S2_N_CODEWORD; cw++) { out[s_out][f][cw] = out[s_in][f][cw]; } } } else { for (s_out = s_out_org, s_in = 0; s_in < cd_n_seno; s_in++, s_out++) { printf("CD %d %u <- %u :\n", f, s_out, s_in); for (cw = 0; cw < S2_N_CODEWORD; cw++) { out[s_out][f][cw] = EXP(in[f][s_in * S2_N_CODEWORD + cw]); } } } } }
int mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mpfr_rnd_t rnd_mode) { mp_limb_t *my, *mx, *tmp; unsigned long cnt, sx, sy; int inexact, carry = 0; MPFR_TMP_DECL(marker); sx = ABS(SIZ(x)); /* number of limbs of the mantissa of x */ if (sx == 0) /* x is zero */ { MPFR_SET_ZERO(y); MPFR_SET_POS(y); return 0; /* 0 is exact */ } if (SIZ(x) * MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(y)) < 0) MPFR_CHANGE_SIGN (y); sy = MPFR_LIMB_SIZE (y); my = MPFR_MANT(y); mx = PTR(x); count_leading_zeros(cnt, mx[sx - 1]); if (sy <= sx) /* we may have to round even when sy = sx */ { unsigned long xprec = sx * GMP_NUMB_BITS; MPFR_TMP_MARK(marker); tmp = MPFR_TMP_LIMBS_ALLOC (sx); if (cnt) mpn_lshift (tmp, mx, sx, cnt); else /* FIXME: we may avoid the copy here, and directly call mpfr_round_raw on mx instead of tmp */ MPN_COPY (tmp, mx, sx); carry = mpfr_round_raw (my, tmp, xprec, (SIZ(x) < 0), MPFR_PREC(y), rnd_mode, &inexact); if (MPFR_UNLIKELY(carry)) /* result is a power of two */ my[sy - 1] = MPFR_LIMB_HIGHBIT; MPFR_TMP_FREE(marker); } else { if (cnt) mpn_lshift (my + sy - sx, mx, sx, cnt); else MPN_COPY (my + sy - sx, mx, sx); MPN_ZERO(my, sy - sx); /* no rounding necessary, since y has a larger mantissa */ inexact = 0; } /* warning: EXP(x) * GMP_NUMB_BITS may exceed the maximal exponent */ if (EXP(x) > 1 + (__gmpfr_emax - 1) / GMP_NUMB_BITS) { /* EXP(x) >= 2 + floor((__gmpfr_emax-1)/GMP_NUMB_BITS) EXP(x) >= 2 + (__gmpfr_emax - GMP_NUMB_BITS) / GMP_NUMB_BITS >= 1 + __gmpfr_emax / GMP_NUMB_BITS EXP(x) * GMP_NUMB_BITS >= __gmpfr_emax + GMP_NUMB_BITS Since 0 <= cnt <= GMP_NUMB_BITS-1, and 0 <= carry <= 1, we have then EXP(x) * GMP_NUMB_BITS - cnt + carry > __gmpfr_emax */ return mpfr_overflow (y, rnd_mode, MPFR_SIGN (y)); } else { /* Do not use MPFR_SET_EXP as the exponent may be out of range. */ MPFR_EXP (y) = EXP (x) * GMP_NUMB_BITS - (mpfr_exp_t) cnt + carry; } return mpfr_check_range (y, inexact, rnd_mode); }