int update_params(void)
{
    int i;
    SW_INS_PTR ptr;
    double sum;

    for (i = 0; i < occ_switch_tab_size; i++) {
        ptr = occ_switches[i];
        sum = 0.0;
        while (ptr != NULL) {
            sum += ptr->total_expect;
            ptr = ptr->next;
        }
        if (sum != 0.0) {
            ptr = occ_switches[i];
            if (ptr->fixed > 0) continue;
            while (ptr != NULL) {
                if (ptr->fixed == 0) ptr->inside = ptr->total_expect / sum;
                if (log_scale && ptr->inside < TINY_PROB) {
                    emit_error("Parameter being zero (-inf in log scale) -- %s",
                               prism_sw_ins_string(ptr->id));
                    RET_ERR(err_underflow);
                }
                ptr = ptr->next;
            }
        }
    }

    return BP_TRUE;
}
Example #2
0
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;
}