double evaluation_function(int* board) { if (is_impossible(board)) { return INT_MIN; } if(heuristic == 1) { return min_possibility(board); } return ( (smoothness(board) * smoothness_constant) + (max_tile(board) * max_tile_constant) + (log(free_tiles(board)) * free_tiles_constant) + (max_placement(board) * max_placement_constant) + (monotonicity(board) * monotonicity_constant) ); }
/* Recursively perform range propagation on the polynomial "poly" * defined over the basic set "bset" and collect the results in "data". */ static isl_stat propagate_on_domain(__isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, struct range_data *data) { isl_ctx *ctx; isl_qpolynomial *save_poly = data->poly; int save_monotonicity = data->monotonicity; unsigned d; if (!bset || !poly) goto error; ctx = isl_basic_set_get_ctx(bset); d = isl_basic_set_dim(bset, isl_dim_set); isl_assert(ctx, d >= 1, goto error); if (isl_qpolynomial_is_cst(poly, NULL, NULL)) { bset = isl_basic_set_project_out(bset, isl_dim_set, 0, d); poly = isl_qpolynomial_drop_dims(poly, isl_dim_in, 0, d); return add_guarded_poly(bset, poly, data); } if (data->test_monotonicity) data->monotonicity = monotonicity(bset, poly, data); else data->monotonicity = 0; if (data->monotonicity < -1) goto error; data->poly = poly; if (isl_basic_set_foreach_bound_pair(bset, isl_dim_set, d - 1, &propagate_on_bound_pair, data) < 0) goto error; isl_basic_set_free(bset); isl_qpolynomial_free(poly); data->monotonicity = save_monotonicity; data->poly = save_poly; return isl_stat_ok; error: isl_basic_set_free(bset); isl_qpolynomial_free(poly); data->monotonicity = save_monotonicity; data->poly = save_poly; return isl_stat_error; }
void subset_points(point_t p[], const size_t n, const size_t k) { assert(monotonicity(p, n) == NON_MONOTONIC); if(k == n) return; assert(k <= n); size_t max_idx = point_max_index(p, n); if(max_idx != 1) { /* Always keep the points before and after max_idx */ const size_t n_before = max_idx - 1; const size_t s = n_before * sizeof(point_t); point_t *buf = malloc(s); memcpy(buf, p, s); memmove(p, p + max_idx - 1, sizeof(point_t) * 3); memcpy(p + 3, buf, s); free(buf); } sort_by_like(p + 3, n - 3); sort_by_t(p, k); }
point_t* select_points(log_like_function_t *log_like, const point_t starting_pts[], size_t *num_pts, const size_t max_pts) { point_t* points = malloc(sizeof(point_t) * (max_pts)); size_t i, n = *num_pts; assert(n > 0 && "num_pts must be > 0"); /* Copy already-evaluated points */ memcpy(points, starting_pts, sizeof(point_t) * n); /* Initialize the rest - for debugging */ for(i = n; i < max_pts; ++i) { points[i].t = -1; points[i].ll = -1; } /* Add additional samples until the evaluated branch lengths enclose a * maximum. */ size_t offset = 0; /* Position to maintain sort order */ double d = 0.0; /* Branch length */ monotonicity_t c = monotonicity(points, n); do { switch(c) { case NON_MONOTONIC: /* Add a point between the first and second try */ d = points[0].t + ((points[1].t - points[0].t) / 2.0); offset = 1; /* shift */ memmove(points + offset + 1, points + offset, sizeof(point_t) * (n - offset)); break; case MONO_INC: /* Double largest value */ d = points[n - 1].t * 2.0; offset = n; break; case MONO_DEC: /* Add new smallest value - order of magnitude lower */ d = points[0].t / 10.0; offset = 0; /* shift */ memmove(points + 1, points, sizeof(point_t) * n); break; case MONO_UNKNOWN: free(points); return NULL; default: assert(false); } const double l = log_like->fn(d, log_like->args); points[offset].t = d; points[offset].ll = l; bracket_likelihood_calls++; c = monotonicity(points, n++); } while(n < max_pts && c != NON_MONOTONIC); *num_pts = n; if(n < max_pts) return realloc(points, sizeof(point_t) * n); else return points; }
double estimate_ml_t(log_like_function_t *log_like, double t[], const size_t n_pts, const double tolerance, bsm_t* model, bool* success) { *success = false; size_t iter = 0; const point_t *max_pt; double *l = malloc(sizeof(double) * n_pts); /* We allocate an extra point for scratch */ point_t *points = malloc(sizeof(point_t) * (n_pts + 1)); evaluate_ll(log_like, t, n_pts, points); /* First, classify points */ monotonicity_t m = monotonicity(points, n_pts); /* If the function is no longer monotonic, start over */ if(m != NON_MONOTONIC) { free(points); size_t n = N_DEFAULT_START; point_t *start_pts = malloc(sizeof(point_t) * n); evaluate_ll(log_like, DEFAULT_START, n, start_pts); points = select_points(log_like, start_pts, &n, DEFAULT_MAX_POINTS); if(points == NULL) { free(l); *success = false; return NAN; } free(start_pts); m = monotonicity(points, n); if(m == MONO_DEC) { double ml_t = points[0].t; *success = true; free(points); free(l); return ml_t; } else if (m == MONO_INC) { *success = false; free(points); free(l); return NAN; } assert(n >= n_pts); if(n > n_pts) { /* Subset to top n_pts */ subset_points(points, n, n_pts); } /* Allocate an extra point for scratch */ points = realloc(points, sizeof(point_t) * (n_pts + 1)); } max_pt = max_point(points, n_pts); double ml_t = max_pt->t; /* Re-fit */ lcfit_bsm_rescale(max_pt->t, max_pt->ll, model); blit_points_to_arrays(points, n_pts, t, l); lcfit_fit_bsm(n_pts, t, l, model); for(iter = 0; iter < MAX_ITERS; iter++) { ml_t = lcfit_bsm_ml_t(model); if(isnan(ml_t)) { *success = false; break; } /* convergence check */ if(fabs(ml_t - max_pt->t) <= tolerance) { *success = true; break; } /* Check for nonsensical ml_t - if the value is outside the bracketed * window, give up. */ size_t max_idx = max_pt - points; if(ml_t < points[max_idx - 1].t || ml_t > points[max_idx + 1].t) { *success = false; ml_t = NAN; break; } /* Add ml_t estimate */ if(ml_t < 0) { *success = true; ml_t = 1e-8; break; } points[n_pts].t = ml_t; points[n_pts].ll = log_like->fn(ml_t, log_like->args); ml_likelihood_calls++; /* Retain top n_pts by log-likelihood */ sort_by_t(points, n_pts + 1); if(monotonicity(points, n_pts + 1) != NON_MONOTONIC) { *success = false; ml_t = NAN; break; } subset_points(points, n_pts + 1, n_pts); blit_points_to_arrays(points, n_pts, t, l); lcfit_fit_bsm(n_pts, t, l, model); max_pt = max_point(points, n_pts); } if(iter == MAX_ITERS) *success = false; free(l); free(points); return ml_t; }