예제 #1
0
파일: feature.c 프로젝트: edechter/PRISM
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;
}
예제 #2
0
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;
}