// Functions to computes a set of modified reference frame probabilities // to use when the prediction of the reference frame value fails void vp9_calc_ref_probs(int *count, vp9_prob *probs) { int tot_count = count[0] + count[1] + count[2] + count[3]; probs[0] = get_prob(count[0], tot_count); tot_count -= count[0]; probs[1] = get_prob(count[1], tot_count); tot_count -= count[1]; probs[2] = get_prob(count[2], tot_count); }
void ribo_model::compute_translation_rate(rid_t t, const vector<double>& rate) { assert(rate.size() == codon_vec_len(t)+1); size_t n(rate.size()); double trate_avg(rate[0]*(1-get_prob(t,0))); for (size_t i=1; i!=n-1; ++i) trate_avg += rate[i]*get_prob(t,i-1)*(1-get_prob(t,i)); trate_avg += rate[n-1]*get_prob(t,n-2); trate_avg /= n; set_trate(t,trate_avg); }
int main() { freopen("robot_direct_prob_info.txt", "r", stdin); setbuf(stdout, NULL); int T, N, i; scanf("%d", &T); while (T--) { scanf("%d", &N); // east->west->south->north for (i = 0; i < 4; i++) { int x; scanf("%d", &x); prob[i] = x / 100.0; } double ans = 0.0; ans = get_prob(50, 50, N); printf("%f\n", ans); clear_buf(); } return 0; }
void Router::update_probs(std::vector<float>& probs, float reltol) const { POMAGMA_INFO("Updating ob probs"); const size_t item_count = m_carrier.item_count(); POMAGMA_ASSERT_EQ(probs.size(), 1 + item_count); const float max_increase = 1.0 + reltol; bool changed = true; while (changed) { changed = false; POMAGMA_DEBUG("accumulating route probabilities"); #pragma omp parallel for schedule(dynamic, 1) for (size_t i = 0; i < item_count; ++i) { Ob ob = 1 + i; float& prob = probs[ob]; float temp_prob = 0; for (const Segment& segment : iter_val(ob)) { temp_prob += get_prob(segment, probs); } if (temp_prob > prob * max_increase) { changed = true; } prob = temp_prob; } } }
std::vector<float> Router::measure_probs(float reltol) const { POMAGMA_INFO("Measuring ob probs"); const size_t item_count = m_carrier.item_count(); std::vector<float> probs(1 + item_count, 0); const float max_increase = 1.0 + reltol; bool changed = true; while (changed) { changed = false; POMAGMA_DEBUG("accumulating route probabilities"); // The following three cannot be mixed: openmp, gcc, fork. // see http://bisqwit.iki.fi/story/howto/openmp/#OpenmpAndFork //# pragma omp parallel for schedule(dynamic, 1) for (size_t i = 0; i < item_count; ++i) { Ob ob = 1 + i; float prob = 0; for (const Segment& segment : iter_val(ob)) { prob += get_prob(segment, probs); } if (prob > probs[ob] * max_increase) { //#pragma omp atomic changed = true; } probs[ob] = prob; // relaxed memory order } } return probs; }
STATIC void update_prob(board_t *b, index_t pos, stone_t color) { float_num delta = get_prob(b, pos, color) - b->prob_sum2[color-1][pos]; b->prob_sum0[color-1] += delta; b->prob_sum1[color-1][pos&block_mask] += delta; b->prob_sum2[color-1][pos] += delta; }
void Router::update_weights( const std::vector<float>& probs, const std::unordered_map<std::string, size_t>& symbol_counts, const std::unordered_map<Ob, size_t>& ob_counts, std::vector<float>& symbol_weights, std::vector<float>& ob_weights, float reltol) const { POMAGMA_INFO("Updating weights"); const size_t symbol_count = m_types.size(); const size_t ob_count = m_carrier.item_count(); POMAGMA_ASSERT_EQ(probs.size(), 1 + ob_count); POMAGMA_ASSERT_EQ(symbol_weights.size(), symbol_count); POMAGMA_ASSERT_EQ(ob_weights.size(), 1 + ob_count); const float max_increase = 1.0 + reltol; std::vector<float> temp_symbol_weights(symbol_weights.size()); std::vector<float> temp_ob_weights(ob_weights.size()); update_weights_loop : { POMAGMA_DEBUG("distributing route weight"); std::fill(temp_symbol_weights.begin(), temp_symbol_weights.end(), 0); for (size_t i = 0; i < symbol_count; ++i) { temp_symbol_weights[i] = map_get(symbol_counts, m_types[i].name, 0); } std::fill(temp_ob_weights.begin(), temp_ob_weights.end(), 0); for (const auto& pair : ob_counts) { temp_ob_weights[pair.first] = pair.second; } #pragma omp parallel for schedule(dynamic, 1) for (size_t i = 0; i < ob_count; ++i) { Ob ob = 1 + i; const float weight = ob_weights[ob] / probs[ob]; for (const Segment& segment : iter_val(ob)) { float part = weight * get_prob(segment, probs); add_weight(part, segment, temp_symbol_weights, temp_ob_weights); } } std::swap(symbol_weights, temp_symbol_weights); std::swap(ob_weights, temp_ob_weights); for (size_t i = 0; i < symbol_count; ++i) { if (symbol_weights[i] > temp_symbol_weights[i] * max_increase) { goto update_weights_loop; } } for (size_t i = 0; i < ob_count; ++i) { Ob ob = 1 + i; if (ob_weights[ob] > temp_ob_weights[ob] * max_increase) { goto update_weights_loop; } } } }
static double get_prob(int x, int y, int n) { // base cases; if (MAP[x][y]) return 0.0; if (n == 0) return 1.0; MAP[x][y] = true; double ret = 0.0; // 4 방향 탐색 for (int i = 0; i < 4; i++) { ret += get_prob(x + dx[i], y + dy[i], n - 1) * prob[i]; } MAP[x][y] = false; return ret; }
void adapt(mcmc ** chains, const unsigned int n_beta, const unsigned int n_swap) { unsigned int i; #ifdef RWM static double prob_old[100]; #endif #ifdef RWM for (i = 0; i < n_beta; i++) { prob_old[i] = get_prob(chains[i]); markov_chain_step(chains[i], 0); rmw_adapt_stepwidth(chains[i], prob_old[i]); } #endif #ifdef ADAPT for (i = 0; i < n_beta; i++) { if (get_params_accepts_sum(chains[i]) + get_params_rejects_sum( chains[i]) < 20000) { continue; } if (get_params_accepts_sum(chains[i]) * 1.0 / get_params_rejects_sum(chains[i]) < TARGET_ACCEPTANCE_RATE - 0.05) { dump_i("too few accepts, scaling down", i); gsl_vector_scale(get_steps(chains[i]), 0.99); } else if (get_params_accepts_sum(chains[i]) * 1.0 / get_params_rejects_sum(chains[i]) > TARGET_ACCEPTANCE_RATE + 0.05) { dump_i("too many accepts, scaling up", i); gsl_vector_scale(get_steps(chains[i]), 1 / 0.99); } if (get_params_accepts_sum(chains[i]) + get_params_rejects_sum( chains[i]) > 100000) { reset_accept_rejects(chains[i]); } } #endif /* avoid unused warnings if adapt is disabled */ (void) chains; i = n_beta + n_swap; }
std::vector<std::string> Router::find_routes() const { POMAGMA_INFO("Routing all obs"); const size_t item_count = m_carrier.item_count(); std::vector<float> best_probs(1 + item_count, 0); std::vector<Segment> best_segments(1 + item_count); bool changed = true; while (changed) { changed = false; POMAGMA_DEBUG("finding best local routes"); //#pragma omp parallel for schedule(dynamic, 1) for (size_t i = 0; i < item_count; ++i) { Ob ob = 1 + i; float& best_prob = best_probs[ob]; Segment& best_segment = best_segments[ob]; bool best_changed = false; for (const Segment& segment : iter_val(ob)) { float prob = get_prob(segment, best_probs); if (unlikely(std::make_pair(-prob, segment) < std::make_pair(-best_prob, best_segment))) { best_prob = prob; // relaxed memory order best_segment = segment; // relaxed memory order best_changed = true; } } if (best_changed) { //#pragma omp atomic changed = true; } } } POMAGMA_DEBUG("scheduling route building"); std::vector<Ob> schedule; schedule.reserve(item_count); for (auto iter = m_carrier.iter(); iter.ok(); iter.next()) { Ob ob = *iter; POMAGMA_ASSERT_LT(0, best_probs[ob]); schedule.push_back(ob); } std::sort(schedule.begin(), schedule.end(), [&](const Ob& x, const Ob& y) { return best_probs[x] > best_probs[y]; }); POMAGMA_DEBUG("building full routes"); std::vector<std::string> routes(1 + item_count); for (Ob ob : schedule) { const Segment& segment = best_segments[ob]; const SegmentType& type = m_types[segment.type]; switch (type.arity) { case NULLARY: { routes[ob] = type.name; } break; case UNARY: { const auto& arg = routes[segment.arg1]; POMAGMA_ASSERT(not arg.empty(), "unknown arg route"); routes[ob] = type.name + " " + arg; } break; case BINARY: { const auto& lhs = routes[segment.arg1]; const auto& rhs = routes[segment.arg2]; POMAGMA_ASSERT(not lhs.empty(), "unknown lhs route"); POMAGMA_ASSERT(not rhs.empty(), "unknown rhs route"); routes[ob] = type.name + " " + lhs + " " + rhs; } break; } } return routes; }
bool check_board(board_t *b) { static bool flag[max_len]; memset(flag, false, sizeof(bool) * max_len); for (index_t i = 0; i < b->len; i++) { if (IS_STONE(b->stones[i])) { flag[b->next_in_group[i]] = true; //check next[i] in the same group if (b->base_of_group[i] != b->base_of_group[b->next_in_group[i]]) return false; //check same color if (b->stones[i] != b->stones[b->next_in_group[i]]) return false; } } // check uniqueness of next[i] for (index_t i = 0; i < b->len; i++) { if (IS_STONE(b->stones[i]) != flag[i]) { return false; } } //check pseudo_liberties information board_t *b2 = new board_t; fork_board(b2, b); memset(b2->group_size, 0, sizeof(index_t) * b->len); for (index_t i = 0; i < b2->len; i++) { if (IS_STONE(b2->stones[i])) { index_t j = b2->base_of_group[i]; b2->group_size[j] ++; b2->pseudo_liberties[j] = 0; b2->group_liberties_sum[j] = 0; b2->group_liberties_sum_squared[j] = 0; } } for (index_t i = 0; i < b2->len; i++) { if (IS_STONE(b2->stones[i])) { update_empty_neighbour(b2, i); } } for (index_t i = 0; i < b2->len; i++) { if (IS_STONE(b2->stones[i])) { index_t p = b->base_of_group[i]; index_t q = b2->base_of_group[i]; if (b->group_size[p] != b2->group_size[q] || b->pseudo_liberties[p] != b2->pseudo_liberties[q]) { delete b2; return false; } if (b->group_liberties_sum[p] != b2->group_liberties_sum[q] || b->group_liberties_sum_squared[p] != b2->group_liberties_sum_squared[q]) { delete b2; return false; } } } delete b2; // check hash value hash_t nhash = 0; for (index_t i = 0; i < b->len; i++) { if (IS_STONE(b->stones[i])) nhash += (hash_t)b->stones[i] * p4423[i]; } if (nhash != b->hash) return false; // check list for (index_t i = 0; i < b->len; i++) { if (b->stones[i] != STONE_BORDER) { index_t j = b->list_pos[i]; if (j < 0 || j >= b->size * b->size) return false; if (b->list[j] != i) return false; int tA = b->stones[i] == STONE_EMPTY ? 0 : i == b->base_of_group[i] ? 2 : 1; int tB = j < b->empty_ptr ? 0 : j < b->group_ptr ? 1 : 2; if (tA != tB) return false; } } // check nbr3x3 nbr3x3_t new_nbr[max_len]; for (index_t i = 0; i < b->len; i++) { if (b->stones[i] != STONE_BORDER) { new_nbr[i] = recalc_nbr3x3(b, i); } } for (index_t i = 0; i < b->len; i++) { if (IS_STONE(b->stones[i]) && b->base_of_group[i] == i && find_atari(b, i) >= 0) { index_t av = find_atari(b, i); if (av < 0) return false; set_atari_bits_3x3(new_nbr[av], IN_GROUP(b, N(b, av), i), IN_GROUP(b, S(b, av), i), IN_GROUP(b, W(b, av), i), IN_GROUP(b, E(b, av), i)); } } for (index_t i = 0; i < b->len; i++) { if (b->stones[i] != STONE_BORDER) { if (new_nbr[i] != b->nbr3x3[i]) return false; } } // check prob for (int i = 0; i < 2; i++) for (int j = 0; j < b->len; j++) { double diff = get_prob(b, j, (stone_t)(i+1)) - b->prob_sum2[i][j]; if (diff > epsilon || diff < -epsilon) return false; } return true; }
/****************************************************************************** * @brief Calculate sublimation from blowing snow *****************************************************************************/ double CalcBlowingSnow(double Dt, double Tair, unsigned LastSnow, double SurfaceLiquidWater, double Wind, double Ls, double AirDens, double EactAir, double ZO, double Zrh, double snowdepth, double lag_one, double sigma_slope, double Tsnow, int iveg, int Nveg, double fe, double displacement, double roughness, double *TotalTransport) { extern parameters_struct param; extern option_struct options; /* Local variables: */ double Age; double U10, Uo, prob_occurence; double es, Ros, F; double SubFlux; double Diffusivity; double ushear; double Tk; double utshear; int p; double upper, lower, Total; double area; double sigma_w; double Zo_salt; double ratio, wind10; double Uveg, hv, Nd; double Transport; /*******************************************************************/ /* Calculate some general variables, that don't depend on wind speed. */ /* Age in hours */ Age = LastSnow * Dt / SEC_PER_HOUR; /* Saturation density of water vapor, Liston A-8 */ es = svp(Tair); Tk = Tair + CONST_TKFRZ; Ros = CONST_EPS * es / (CONST_RDAIR * Tk); /* Diffusivity in m2/s, Liston eq. A-7 */ Diffusivity = (2.06e-5) * pow(Tk / 273., 1.75); // Essery et al. 1999, eq. 6 (m*s/kg) F = (Ls / (param.BLOWING_KA * Tk)) * (Ls * Tk / CONST_RDAIR - 1.); F += 1. / (Diffusivity * Ros); /* grid cell 10 m wind speed = 50th percentile wind */ /* Wind speed at 2 m above snow was passed to this function. */ wind10 = Wind * log(10. / ZO) / log((2 + ZO) / ZO); /* Check for bare soil case. */ if (iveg == Nveg) { fe = 1500; sigma_slope = .0002; } // sigma_w/uo: ratio = (2.44 - (0.43) * lag_one) * sigma_slope; sigma_w = wind10 * ratio; Uo = wind10; /*********** Parameters for roughness above snow. *****************/ hv = (3. / 2.) * displacement; Nd = (4. / 3.) * (roughness / displacement); /*******************************************************************/ /** Begin loop through wind probability function. */ Total = 0.0; *TotalTransport = 0.0; area = 1. / (double) param.BLOWING_NUMINCS; if (snowdepth > 0.0) { if (options.BLOWING_SPATIAL_WIND && sigma_w != 0.) { for (p = 0; p < param.BLOWING_NUMINCS; p++) { SubFlux = lower = upper = 0.0; /* Find the limits of integration. */ if (p == 0) { lower = -9999; upper = Uo + sigma_w * log(2. * (p + 1) * area); } else if (p > 0 && p < param.BLOWING_NUMINCS / 2) { lower = Uo + sigma_w * log(2. * (p) * area); upper = Uo + sigma_w * log(2. * (p + 1) * area); } else if (p < (param.BLOWING_NUMINCS - 1) && p >= (double) param.BLOWING_NUMINCS / 2) { lower = Uo - sigma_w * log(2. - 2. * (p * area)); upper = Uo - sigma_w * log(2. - 2. * ((p + 1.) * area)); } else if (p == param.BLOWING_NUMINCS - 1) { lower = Uo - sigma_w * log(2. - 2. * (p * area)); upper = 9999; } if (lower > upper) { /* Could happen if lower > Uo*2 */ lower = upper; log_err("Error with probability boundaries"); } /* Find expected value of wind speed for the interval. */ U10 = Uo; if (lower >= Uo) { U10 = -0.5 * ((upper + sigma_w) * exp((-1. / sigma_w) * (upper - Uo)) - (lower + sigma_w) * exp((-1. / sigma_w) * (lower - Uo))) / area; } else if (upper <= Uo) { U10 = 0.5 * ((upper - sigma_w) * exp((1. / sigma_w) * (upper - Uo)) - (lower - sigma_w) * exp((1. / sigma_w) * (lower - Uo))) / area; } else { log_err("Problem with probability ranges: Increment = %d, " "integration limits = %f - %f", p, upper, lower); } if (U10 < 0.4) { U10 = .4; } if (U10 > 25.) { U10 = 25.; } /*******************************************************************/ /* Calculate parameters for probability of blowing snow occurence. */ /* ( Li and Pomeroy 1997) */ if (snowdepth < hv) { Uveg = U10 / sqrt(1. + 170 * Nd * (hv - snowdepth)); } else { Uveg = U10; } prob_occurence = get_prob(Tair, Age, SurfaceLiquidWater, Uveg); /*******************************************************************/ /* Calculate threshold shear stress. Send 0 for constant or */ /* 1 for variable threshold after Li and Pomeroy (1997) */ utshear = get_thresh(Tair, SurfaceLiquidWater, ZO); /* Iterate to find actual shear stress during saltation. */ shear_stress(U10, ZO, &ushear, &Zo_salt, utshear); if (ushear > utshear) { SubFlux = CalcSubFlux(EactAir, es, Zrh, AirDens, utshear, ushear, fe, Tsnow, Tair, U10, Zo_salt, F, &Transport); } else { SubFlux = 0.0; Transport = 0.0; } Total += (1. / (double) param.BLOWING_NUMINCS) * SubFlux * prob_occurence; *TotalTransport += (1. / (double) param.BLOWING_NUMINCS) * Transport * prob_occurence; } } else { U10 = Uo; /*******************************************************************/ /* Calculate parameters for probability of blowing snow occurence. */ /* ( Li and Pomeroy 1997) */ if (snowdepth < hv) { Uveg = U10 / sqrt(1. + 170 * Nd * (hv - snowdepth)); } else { Uveg = U10; } prob_occurence = get_prob(Tair, Age, SurfaceLiquidWater, Uveg); /*******************************************************************/ /* Calculate threshold shear stress. Send 0 for constant or */ /* 1 for variable threshold after Li and Pomeroy (1997) */ utshear = get_thresh(Tair, SurfaceLiquidWater, ZO); /* Iterate to find actual shear stress during saltation. */ shear_stress(Uo, ZO, &ushear, &Zo_salt, utshear); if (ushear > utshear) { SubFlux = CalcSubFlux(EactAir, es, Zrh, AirDens, utshear, ushear, fe, Tsnow, Tair, Uo, Zo_salt, F, &Transport); } else { SubFlux = 0.0; Transport = 0.0; } Total = SubFlux * prob_occurence; *TotalTransport = Transport * prob_occurence; } } if (Total < -.00005) { Total = -.00005; } return Total; }
void viterbi(HMM *hmm_ptr, int T, char *O, double *pprob, int *vpath, char *signal_file1, char *signal_file2, char *out_file, char *phmm_dir1, char *out_dir1, char *hmmerv){ /* chr *O: sequecne int *vpath: optimal path after backtracking int T: the length of sequence hmm.A[][]: transition prob hmm.B[][]: emission prob hmm.N: the number of state int i: index for start state, current state int j: index for end start int t: index for string int t1: subindex for string int state_end; double state_score; */ int i, j, t, t1, d, ss, si; double max_val, temp_val; int max_state; int **path; /* viterbi path */ double **alpha; /* viterbi array */ int *signal; /* chromosomal position for the index in X axis of array */ int *path_signal; /* 0: start of fragment, 1: end */ int temp1, temp2; double temp3, temp4; FILE *fp,*outfp; int state_end; double state_score; int *ape, *rt; int *start, *end; int flag; char state_flag[20]; int prev_state; int final_t; int sig_id = 0; /* index for signal of fragments */ int num_sig = 0; /* total numer of signals */ int temp_id; double temp_prob; int check_prob; int debug = 0; /* if ((phmm_dir = (char *)malloc(50 * sizeof(char)))==NULL){ printf("ERROR: allocation of phmm_dir\n"); exit; } if ((out_dir = (char *)malloc(50 * sizeof(char)))==NULL){ printf("ERROR: allocation of out_dir\n"); exit; } memset(phmm_dir,0,50); memset(out_dir,0,50); */ phmm_dir = phmm_dir1; out_dir = out_dir1; memset(state_flag,0,20); /***************************************************************/ /* initialize viterbi array */ /***************************************************************/ ape = (int *)ivector(T+1); rt = (int *)ivector(T+1); start = (int *)ivector(hmm_ptr->N); end = (int *)ivector(hmm_ptr->N); /*****************************************************************/ /* mark signal */ /*****************************************************************/ for (t=0; t<T; t++){ ape[t] = 0; rt[t] = 0; } fp = fopen(signal_file1, "r"); while (fscanf(fp, "%d %d %lf %lf\n", &temp1, &temp2, &temp3, &temp4) != EOF){ ape[temp1] = 1; if (temp2 > T) {temp2 = T;} ape[temp2] = 2; num_sig += 2; } fclose(fp); fp = fopen(signal_file2, "r"); while (fscanf(fp, "%d %d %lf %lf\n", &temp1, &temp2, &temp3, &temp4) != EOF){ rt[temp1] = 1; if (temp2 > T) {temp2 = T;} rt[temp2] = 2; num_sig += 4; } fclose(fp); num_sig *= 2; /***************************************************************/ /* initialize viterbi array */ /***************************************************************/ alpha = (double **)dmatrix(hmm_ptr->N, num_sig); path = (int **)imatrix(hmm_ptr->N, num_sig); signal = (int *)ivector(num_sig); path_signal = (int *)ivector(num_sig); outfp = fopen (out_file , "w"); if (num_sig > 0){ /******************************************************************/ /* initialize the first IE state */ /******************************************************************/ start[IE]=0; signal[sig_id] = 0; sig_id ++; for (i=0; i<hmm_ptr->N; i++){ alpha[i][0] = -1 * log(hmm_ptr->pi[i]); for (t=1; t<num_sig; t++){ alpha[i][t] = DBL_MAX; } } /******************************************************************/ /* do recursion to fill out rest of the columns */ /******************************************************************/ for (t = 1; t < T - 2; t++) { if (sig_id >= num_sig) { break; } flag=0; /*********************/ /* state APE start */ /*********************/ if (ape[t]==1){ flag=1; strcpy(state_flag, "APE start"); path_signal[sig_id] = 0; alpha[IE][sig_id] = DBL_MAX; path[IE][sig_id] = IE; start[IE] = sig_id; for(ss=0; ss<NO_APE; ss++){ alpha[ape_state[ss]][sig_id] = alpha[IE][sig_id-1] - log(hmm_ptr->A[IE][ape_state[ss]]); path[ape_state[ss]][sig_id] = IE; start[ape_state[ss]] = sig_id; } } /*********************/ /* state APE end */ /*********************/ if (ape[t] == 2) { flag=1; strcpy(state_flag, "APE end"); path_signal[sig_id] = 1; alpha[IE][sig_id] = DBL_MAX; path[IE][sig_id] = IE; for (ss=0; ss<NO_APE; ss++){ state_score = get_prob(ape_state[ss], signal[start[ape_state[ss]]], t, O, hmmerv); if (state_score == DBL_MAX){ alpha[ape_state[ss]][sig_id] = DBL_MAX; }else{ alpha[ape_state[ss]][sig_id] = alpha[ape_state[ss]][start[ape_state[ss]]] - state_score - log(dist_ape(t-signal[start[ape_state[ss]]]+1)); } path[ape_state[ss]][sig_id] = ape_state[ss]; } } /*********************/ /* state ID/IE start */ /*********************/ if (ape[t-1] == 2){ flag=1; strcpy(state_flag, "ID/IE start"); path_signal[sig_id] = 0; alpha[IE][sig_id] = alpha[IE][sig_id-1]; path[IE][sig_id] = IE; start[IE] = sig_id; for (si=0; si<NO_APE; si++){ temp_val = alpha[ape_state[si]][sig_id-1] - log(hmm_ptr->A[ape_state[si]][IE]); if (temp_val < alpha[IE][sig_id]){ alpha[IE][sig_id] = temp_val; path[IE][sig_id] = ape_state[si]; } } for (si=0; si<NO_APE; si++){ if (alpha[ape_state[si]][sig_id-1]==DBL_MAX){ alpha[id_state[si]][sig_id] = DBL_MAX; }else{ alpha[id_state[si]][sig_id] = alpha[ape_state[si]][sig_id-1] - log(hmm_ptr->A[ape_state[si]][id_state[si]]); } path[id_state[si]][sig_id] = ape_state[si]; start[id_state[si]] = sig_id; } } /*********************/ /* state ID/IE end */ /*********************/ if (rt[t+1] == 1 ) { flag=1; strcpy(state_flag, "ID/IE end"); path_signal[sig_id] = 1; state_score = get_prob(IE, signal[start[IE]], t, O, hmmerv); alpha[IE][sig_id] = alpha[IE][start[IE]] - state_score - log(dist_ie(t-signal[start[IE]]+1)); path[IE][sig_id] = IE; if (start[id_state[0]] >-1){ for (si=0; si<NO_APE; si++){ state_score = get_prob(id_state[si], signal[start[id_state[si]]], t, O, hmmerv); if (dist_id(t-signal[start[id_state[si]]]+1)==0){ alpha[id_state[si]][sig_id] = DBL_MAX; }else{ alpha[id_state[si]][sig_id] = alpha[id_state[si]][start[id_state[si]]] - state_score - log(dist_id(t-signal[start[id_state[si]]]+1)); } path[id_state[si]][sig_id] = id_state[si]; start[id_state[si]]=-1; } }else{ for (si=0; si<NO_APE; si++){ alpha[id_state[si]][sig_id] = DBL_MAX; path[id_state[si]][sig_id] = -1; } } } /*********************/ /* state RT1 start */ /*********************/ if (rt[t] == 1) { flag=1; strcpy(state_flag, "RT start"); path_signal[sig_id] = 0; alpha[IE][sig_id] = DBL_MAX; path[IE][sig_id] = IE; start[IE] = sig_id; for (si=0; si<NO_RT; si++){ alpha[rt_state[si]][sig_id] = alpha[IE][sig_id-1] - log(hmm_ptr->A[IE][rt_state[si]]); path[rt_state[si]][sig_id] = IE; start[rt_state[si]] = sig_id; temp_val = alpha[id_state[si]][sig_id-1] - log(hmm_ptr->A[id_state[si]][rt_state[si]]); if (temp_val < alpha[rt_state[si]][sig_id]){ alpha[rt_state[si]][sig_id] = temp_val; path[rt_state[si]][sig_id] = id_state[si]; } } } /*********************/ /* state RT1 end */ /*********************/ if (rt[t] == 2) { flag=1; strcpy(state_flag, "RT end"); path_signal[sig_id] = 1; alpha[IE][sig_id] = DBL_MAX; path[IE][sig_id] = IE; for (si=0; si<NO_RT; si++) { state_score = get_prob(rt_state[si], signal[start[rt_state[si]]], t, O, hmmerv); if (state_score == DBL_MAX){ alpha[rt_state[si]][sig_id] = DBL_MAX; }else{ alpha[rt_state[si]][sig_id] = alpha[rt_state[si]][start[rt_state[si]]] - state_score - log(dist_rt(t-signal[start[rt_state[si]]]+1)); } path[rt_state[si]][sig_id] = rt_state[si]; } } /*********************/ /* state IE start */ /*********************/ if (rt[t-1] == 2){ flag=1; strcpy(state_flag, "IE start"); path_signal[sig_id] = 0; alpha[IE][sig_id] = DBL_MAX; path[IE][sig_id] = IE; start[IE] = sig_id; for (si=0; si<NO_RT; si++){ temp_val = alpha[rt_state[si]][sig_id-1] - log(hmm_ptr->A[rt_state[si]][IE]); if (temp_val < alpha[IE][sig_id]){ alpha[IE][sig_id] = temp_val; path[IE][sig_id] = rt_state[si]; } } for (si=0; si<NO_APE; si++){ alpha[id_state[si]][sig_id]=DBL_MAX; path[id_state[si]][sig_id] = -1; } } /*********************/ /* state IE end */ /*********************/ if (ape[t+1] == 1 ) { flag=1; strcpy(state_flag, "IE end"); path_signal[sig_id] = 1; state_score = get_prob(IE, signal[start[IE]], t, O, hmmerv); if (dist_ie(t-signal[start[IE]]+1)==0){ alpha[IE][sig_id] = DBL_MAX; }else{ alpha[IE][sig_id] = alpha[IE][start[IE]] - state_score - log(dist_ie(t-signal[start[IE]]+1)); } path[IE][sig_id] = IE; } /************************/ /* print */ /************************/ if (flag==1){ final_t = sig_id; signal[sig_id] = t; if (debug==1){ printf("%d %d %s\t\t", sig_id, t, state_flag); for (i=0; i<hmm_ptr->N; i++){ if (alpha[i][sig_id] < DBL_MAX ){ printf("%lf\t", alpha[i][sig_id]); }else{ printf("-\t"); } } printf("\n\n"); printf("%d %d %s\t\t", sig_id, t, state_flag); for (i=0; i<hmm_ptr->N; i++){ printf("%d\t", path[i][sig_id]); } printf("\n\n\n"); } sig_id++; } } /***********************************************************/ /* backtrack array to find the optimal path */ /***********************************************************/ *pprob = DBL_MAX; vpath = (int *)ivector(num_sig); for (i = 0; i < hmm_ptr->N; i++){ if (alpha[i][final_t] < *pprob && alpha[i][final_t] > 0.00001){ *pprob = alpha[i][final_t]; vpath[final_t] = i; } } if (*pprob == DBL_MAX) { vpath[final_t]=0; } for(sig_id=final_t-1; sig_id>=0; sig_id--){ // skip if viterbi path or array is out of range if ( path[vpath[sig_id+1]][sig_id+1] == -1) continue; vpath[sig_id] = path[vpath[sig_id+1]][sig_id+1]; if (path_signal[sig_id] == 1 && alpha[vpath[sig_id]][sig_id] != DBL_MAX){ fprintf(outfp, "%d %d %lf\n", signal[sig_id], vpath[sig_id], alpha[vpath[sig_id]][sig_id]); } } } fclose(outfp); free_ivector(ape); free_ivector(rt); free_ivector(start); free_ivector(end); free_imatrix(path, hmm_ptr->N); free_dmatrix(alpha, hmm_ptr->N); free_ivector(signal); free_ivector(path_signal); free_ivector(vpath); }
/***************************************************************************** Function name: CalcBlowingSnow() Purpose : Calculate sublimation from blowing snow Required : double Dt; Model time step (hours) double Tair; Air temperature (C) int LastSnow; Time steps since last snowfall. double SurfaceLiquidWater; Liquid water in the surface layer (m) double Wind; Wind speed (m/s), 2 m above snow double Ls; Latent heat of sublimation (J/kg) double AirDens; Density of air (kg/m3) double Lv; Latent heat of vaporization (J/kg3) double Press; Air pressure (Pa) double EactAir; Actual vapor pressure of air (Pa) double ZO; Snow roughness height (m) Returns : BlowingMassFlux Modifies : Comments : Called from SnowPackEnergyBalance Reference: *****************************************************************************/ double CalcBlowingSnow( double Dt, double Tair, int LastSnow, double SurfaceLiquidWater, double Wind, double Ls, double AirDens, double Press, double EactAir, double ZO, double Zrh, double snowdepth, float lag_one, float sigma_slope, double Tsnow, int iveg, int Nveg, float fe, double displacement, double roughness, double *TotalTransport) { /* Local variables: */ double Age; double U10, Uo, prob_occurence; double es, Ros, F; double SubFlux; double Diffusivity; double ushear, Qsalt, hsalt, phi_s, psi_s; double Tk; double Lv; double T, ztop; double ut10, utshear; int p; double upper, lower, Total; double area; double sigma_w; double undersat_2; double b, temp2; /* SBSM scaling parameter. */ double temp, temp3; double Zo_salt; double ratio, wind10; double Uveg, hv, Nd; double Transport; int count=0; Lv = (2.501e6 - 0.002361e6 * Tsnow); /*******************************************************************/ /* Calculate some general variables, that don't depend on wind speed. */ /* Age in hours */ Age = LastSnow*(Dt); /* Saturation density of water vapor, Liston A-8 */ es = svp(Tair); Tk = Tair + KELVIN; Ros = 0.622*es/(287*Tk); /* Diffusivity in m2/s, Liston eq. A-7 */ Diffusivity = (2.06e-5) * pow(Tk/273.,1.75); // Essery et al. 1999, eq. 6 (m*s/kg) F = (Ls/(Ka*Tk))*(Ls*MW/(R*Tk) - 1.); F += 1./(Diffusivity*Ros); /* grid cell 10 m wind speed = 50th percentile wind */ /* Wind speed at 2 m above snow was passed to this function. */ wind10 = Wind*log(10./ZO)/log((2+ZO)/ZO); // fprintf(stderr,"wind=%f, Uo=%f\n",Wind, Uo); /* Check for bare soil case. */ if(iveg == Nveg) { fe = 1500; sigma_slope = .0002; } // sigma_w/uo: ratio = (2.44 - (0.43)*lag_one)*sigma_slope; // sigma_w = wind10/(.69+(1/ratio)); // Uo = sigma_w/ratio; sigma_w = wind10*ratio; Uo = wind10; /*********** Parameters for roughness above snow. *****************/ hv = (3./2.)*displacement; Nd = (4./3.)*(roughness/displacement); /*******************************************************************/ /** Begin loop through wind probability function. */ Total = 0.0; *TotalTransport = 0.0; area = 1./NUMINCS; if(snowdepth > 0.0) { if(SPATIAL_WIND && sigma_w != 0.) { for(p= 0; p< NUMINCS; p++) { SubFlux = lower = upper = 0.0; /* Find the limits of integration. */ if(p==0) { lower = -9999; upper = Uo + sigma_w*log(2.*(p+1)*area); } else if(p > 0 && p < NUMINCS/2) { lower = Uo + sigma_w*log(2.*(p)*area); upper = Uo + sigma_w*log(2.*(p+1)*area); } else if(p < (NUMINCS-1) && p >= NUMINCS/2) { lower = Uo - sigma_w*log(2.-2.*(p*area)); upper = Uo - sigma_w*log(2.-2.*((p+1.)*area)); } else if(p == NUMINCS-1) { lower = Uo - sigma_w*log(2.-2.*(p*area)); upper = 9999; } if(lower > upper) {/* Could happen if lower > Uo*2 */ lower = upper; fprintf(stderr,"Warning: Error with probability boundaries in CalcBlowingSnow()\n"); } /* Find expected value of wind speed for the interval. */ U10 = Uo; if(lower >= Uo ) U10 = -0.5*((upper+sigma_w)*exp((-1./sigma_w)*(upper - Uo)) - (lower+sigma_w)*exp((-1./sigma_w)*(lower - Uo)))/area; else if(upper <= Uo ) U10 = 0.5*((upper-sigma_w)*exp((1./sigma_w)*(upper - Uo)) - (lower-sigma_w)*exp((1./sigma_w)*(lower - Uo)))/area; else { fprintf(stderr,"ERROR in CalcBlowingSnow.c: Problem with probability ranges\n"); fprintf(stderr," Increment = %d, integration limits = %f - %f\n",p,upper, lower); return ( ERROR ); } if(U10 < 0.4) U10 = .4; if(U10 > 25.) U10 = 25.; /*******************************************************************/ /* Calculate parameters for probability of blowing snow occurence. */ /* ( Li and Pomeroy 1997) */ if(snowdepth < hv) { Uveg = U10/sqrt(1.+ 170*Nd*(hv - snowdepth)); } else Uveg = U10; // fprintf(stderr, "Uveg = %f, U10 = %f\n",Uveg, U10); prob_occurence = get_prob(Tair, Age, SurfaceLiquidWater, Uveg); // printf("prob=%f\n",prob_occurence); /*******************************************************************/ /* Calculate threshold shear stress. Send 0 for constant or */ /* 1 for variable threshold after Li and Pomeroy (1997) */ utshear = get_thresh(Tair, SurfaceLiquidWater, ZO, VAR_THRESHOLD); /* Iterate to find actual shear stress during saltation. */ shear_stress(U10, ZO, &ushear, &Zo_salt, utshear); if(ushear > utshear) { SubFlux = CalcSubFlux(EactAir, es, Zrh, AirDens, utshear,ushear, fe, Tsnow, Tair, U10, Zo_salt, F, &Transport); } else { SubFlux=0.0; Transport = 0.0; } Total += (1./NUMINCS)*SubFlux*prob_occurence; *TotalTransport += (1./NUMINCS)*Transport*prob_occurence; } } else { U10=Uo; /*******************************************************************/ /* Calculate parameters for probability of blowing snow occurence. */ /* ( Li and Pomeroy 1997) */ if(snowdepth < hv) Uveg = U10/sqrt(1.+ 170*Nd*(hv - snowdepth)); else Uveg = U10; prob_occurence = get_prob(Tair, Age, SurfaceLiquidWater, Uveg); /*******************************************************************/ /* Calculate threshold shear stress. Send 0 for constant or */ /* 1 for variable threshold after Li and Pomeroy (1997) */ utshear = get_thresh(Tair, SurfaceLiquidWater, ZO, VAR_THRESHOLD); /* Iterate to find actual shear stress during saltation. */ shear_stress(Uo, ZO, &ushear, &Zo_salt, utshear); if(ushear > utshear) { SubFlux = CalcSubFlux(EactAir, es, Zrh, AirDens, utshear,ushear, fe, Tsnow, Tair, Uo, Zo_salt, F, &Transport); } else { SubFlux=0.0; Transport = 0.0; } Total = SubFlux*prob_occurence; *TotalTransport = Transport*prob_occurence; } } if(Total < -.00005) Total = -.00005; return Total; }