static int compute_gradient_scaling_log_exp(void) { int i,k; EG_PATH_PTR path_ptr; EG_NODE_PTR eg_ptr,node_ptr; SW_INS_PTR sw_ptr; double q,r; for (i = 0; i < sw_ins_tab_size; i++) { switch_instances[i]->total_expect = 0.0; switch_instances[i]->has_first_expectation = 0; switch_instances[i]->first_expectation = 0.0; } for (i = 0; i < sorted_egraph_size; i++) { sorted_expl_graph[i]->outside = 0.0; sorted_expl_graph[i]->has_first_outside = 0; sorted_expl_graph[i]->first_outside = 0.0; } for (i = 0; i < num_roots; i++) { if (roots[i]->pid == -1) { eg_ptr = expl_graph[roots[i]->id]; if (i == failure_root_index) { eg_ptr->first_outside = log(num_goals / (1.0 - exp(inside_failure))); } else { eg_ptr->first_outside = log((double)(roots[i]->sgd_count)) - eg_ptr->inside; } eg_ptr->has_first_outside = 1; eg_ptr->outside = 1.0; } } /* sorted_expl_graph[to] must be a root node */ for (i = sorted_egraph_size - 1; i >= 0; i--) { eg_ptr = sorted_expl_graph[i]; if (eg_ptr->visited == 0) continue; /* First accumulate log-scale outside probabilities: */ if (!eg_ptr->has_first_outside) { emit_internal_error("unexpected has_first_outside[%s]", prism_goal_string(eg_ptr->id)); RET_INTERNAL_ERR; } else if (!(eg_ptr->outside > 0.0)) { emit_internal_error("unexpected outside[%s]", prism_goal_string(eg_ptr->id)); RET_INTERNAL_ERR; } else { eg_ptr->outside = eg_ptr->first_outside + log(eg_ptr->outside); } path_ptr = sorted_expl_graph[i]->path_ptr; while (path_ptr != NULL) { q = sorted_expl_graph[i]->outside + path_ptr->inside; for (k = 0; k < path_ptr->children_len; k++) { node_ptr = path_ptr->children[k]; r = q - node_ptr->inside; if (!node_ptr->has_first_outside) { node_ptr->first_outside = r; node_ptr->outside += 1.0; node_ptr->has_first_outside = 1; } else if (r - node_ptr->first_outside >= log(HUGE_PROB)) { node_ptr->outside *= exp(node_ptr->first_outside - r); node_ptr->first_outside = r; node_ptr->outside += 1.0; } else { node_ptr->outside += exp(r - node_ptr->first_outside); } } for (k = 0; k < path_ptr->sws_len; k++) { sw_ptr = path_ptr->sws[k]; if (!sw_ptr->has_first_expectation) { sw_ptr->first_expectation = q; sw_ptr->total_expect += 1.0; sw_ptr->has_first_expectation = 1; } else if (q - sw_ptr->first_expectation >= log(HUGE_PROB)) { sw_ptr->total_expect *= exp(sw_ptr->first_expectation - q); sw_ptr->first_expectation = q; sw_ptr->total_expect += 1.0; } else { sw_ptr->total_expect += exp(q - sw_ptr->first_expectation); } } path_ptr = path_ptr->next; } } /* unscale total_expect */ for (i = 0; i < sw_ins_tab_size; i++) { sw_ptr = switch_instances[i]; if (!sw_ptr->has_first_expectation) continue; if (!(sw_ptr->total_expect > 0.0)) { emit_error("unexpected expectation for %s",prism_sw_ins_string(i)); RET_ERR(err_invalid_numeric_value); } sw_ptr->total_expect = exp(sw_ptr->first_expectation + log(sw_ptr->total_expect)); } for (i=0; i<occ_switch_tab_size; i++) { sw_ptr = occ_switches[i]; while (sw_ptr!=NULL) { sw_ptr->gradient = (sw_ptr->count - sw_ptr->total_expect) * sw_ptr->inside_h; if (crf_penalty != 0.0) { sw_ptr->gradient -= sw_ptr->inside * crf_penalty; } sw_ptr = sw_ptr->next; } } return BP_TRUE; }
int compute_outside_scaling_log_exp(void) { int i,k; EG_PATH_PTR path_ptr; EG_NODE_PTR eg_ptr,node_ptr; double q,r; if (num_roots != 1) { emit_internal_error("illegal call to compute_outside"); RET_ERR(build_internal_error("no_observed_data")); } for (i = 0; i < sorted_egraph_size; i++) { sorted_expl_graph[i]->outside = 0.0; sorted_expl_graph[i]->has_first_outside = 0; sorted_expl_graph[i]->first_outside = 0.0; } eg_ptr = expl_graph[roots[0]->id]; eg_ptr->outside = 1.0; eg_ptr->has_first_outside = 1; eg_ptr->first_outside = log((double)(roots[0]->count)); /* sorted_expl_graph[to] must be a root node */ for (i = sorted_egraph_size - 1; i >= 0; i--) { eg_ptr = sorted_expl_graph[i]; /* First accumulate log-scale outside probabilities: */ if (!eg_ptr->has_first_outside) { emit_internal_error("unexpected has_first_outside[%s]",prism_goal_string(eg_ptr->id)); RET_INTERNAL_ERR; } else if (!(eg_ptr->outside > 0.0)) { emit_internal_error("unexpected outside[%s]", prism_goal_string(eg_ptr->id)); RET_INTERNAL_ERR; } else { eg_ptr->outside = eg_ptr->first_outside + log(eg_ptr->outside); } path_ptr = sorted_expl_graph[i]->path_ptr; while (path_ptr != NULL) { q = sorted_expl_graph[i]->outside + path_ptr->inside; for (k = 0; k < path_ptr->children_len; k++) { node_ptr = path_ptr->children[k]; r = q - node_ptr->inside; if (!node_ptr->has_first_outside) { node_ptr->first_outside = r; node_ptr->outside += 1.0; node_ptr->has_first_outside = 1; } else if (r - node_ptr->first_outside >= log(HUGE_PROB)) { node_ptr->outside *= exp(node_ptr->first_outside - r); node_ptr->first_outside = r; node_ptr->outside += 1.0; } else { node_ptr->outside += exp(r - node_ptr->first_outside); } } path_ptr = path_ptr->next; } } return BP_TRUE; }