int zeromap_page_range(unsigned long addr, unsigned long len, unsigned long prot) { int error; pde_t *pd; pte_t zero_pte; unsigned long end; pd = pde_offset(current->mm->pd, addr); zero_pte = mk_pte(ZERO_PAGE, prot & ~PG_RW); while (addr < end) { pte_t *tmp = alloc_pt(); if (!tmp) return -ENOMEM; *pd = mk_pde(tmp, _PDE); error = zeromap_pde_range(pd, addr, end - addr, zero_pte); if (error) break; addr = (addr + PGDIR_SIZE) & PGDIR_MASK; pd++; } }
nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data, const double *lb, const double *ub, /* bounds */ double *x, /* in: initial guess, out: minimizer */ double *minf, nlopt_stopping *stop, nlopt_opt local_opt, int Nsamples, /* #samples/iteration (0=default) */ int lds) /* random or low-discrepancy seq. (lds) */ { nlopt_result ret = NLOPT_SUCCESS; mlsl_data d; int i; pt *p; if (!Nsamples) d.N = 4; /* FIXME: what is good number of samples per iteration? */ else d.N = Nsamples; if (d.N < 1) return NLOPT_INVALID_ARGS; d.n = n; d.lb = lb; d.ub = ub; d.stop = stop; d.f = f; d.f_data = f_data; rb_tree_init(&d.pts, pt_compare); rb_tree_init(&d.lms, lm_compare); d.s = lds ? nlopt_sobol_create((unsigned) n) : NULL; nlopt_set_min_objective(local_opt, fcount, &d); nlopt_set_lower_bounds(local_opt, lb); nlopt_set_upper_bounds(local_opt, ub); nlopt_set_stopval(local_opt, stop->minf_max); d.gamma = MLSL_GAMMA; d.R_prefactor = sqrt(2./K2PI) * pow(gam(n) * MLSL_SIGMA, 1.0/n); for (i = 0; i < n; ++i) d.R_prefactor *= pow(ub[i] - lb[i], 1.0/n); /* MLSL also suggests setting some minimum distance from points to previous local minimiza and to the boundaries; I don't know how to choose this as a fixed number, so I set it proportional to R; see also the comments at top. dlm and dbound are the proportionality constants. */ d.dlm = 1.0; /* min distance/R to local minima (FIXME: good value?) */ d.dbound = 1e-6; /* min distance/R to ub/lb boundaries (good value?) */ p = alloc_pt(n); if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; } /* FIXME: how many sobol points to skip, if any? */ nlopt_sobol_skip(d.s, (unsigned) (10*n+d.N), p->x); memcpy(p->x, x, n * sizeof(double)); p->f = f(n, x, NULL, f_data); stop->nevals++; if (!rb_tree_insert(&d.pts, (rb_key) p)) { free(p); ret = NLOPT_OUT_OF_MEMORY; } if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP; else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED; else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED; else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED; while (ret == NLOPT_SUCCESS) { rb_node *node; double R; get_minf(&d, minf, x); /* sampling phase: add random/quasi-random points */ for (i = 0; i < d.N && ret == NLOPT_SUCCESS; ++i) { p = alloc_pt(n); if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; } if (d.s) nlopt_sobol_next(d.s, p->x, lb, ub); else { /* use random points instead of LDS */ int j; for (j = 0; j < n; ++j) p->x[j] = nlopt_urand(lb[j],ub[j]); } p->f = f(n, p->x, NULL, f_data); stop->nevals++; if (!rb_tree_insert(&d.pts, (rb_key) p)) { free(p); ret = NLOPT_OUT_OF_MEMORY; } if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP; else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED; else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED; else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED; else { find_closest_pt(n, &d.pts, p); find_closest_lm(n, &d.lms, p); pts_update_newpt(n, &d.pts, p); } } /* distance threshhold parameter R in MLSL */ R = d.R_prefactor * pow(log((double) d.pts.N) / d.pts.N, 1.0 / n); /* local search phase: do local opt. for promising points */ node = rb_tree_min(&d.pts); for (i = (int) (ceil(d.gamma * d.pts.N) + 0.5); node && i > 0 && ret == NLOPT_SUCCESS; --i) { p = (pt *) node->k; if (is_potential_minimizer(&d, p, R, d.dlm*R, d.dbound*R)) { nlopt_result lret; double *lm; double t = nlopt_seconds(); if (nlopt_stop_forced(stop)) { ret = NLOPT_FORCED_STOP; break; } if (nlopt_stop_evals(stop)) { ret = NLOPT_MAXEVAL_REACHED; break; } if (stop->maxtime > 0 && t - stop->start >= stop->maxtime) { ret = NLOPT_MAXTIME_REACHED; break; } lm = (double *) malloc(sizeof(double) * (n+1)); if (!lm) { ret = NLOPT_OUT_OF_MEMORY; goto done; } memcpy(lm+1, p->x, sizeof(double) * n); lret = nlopt_optimize_limited(local_opt, lm+1, lm, stop->maxeval - stop->nevals, stop->maxtime - (t - stop->start)); p->minimized = 1; if (lret < 0) { free(lm); ret = lret; goto done; } if (!rb_tree_insert(&d.lms, lm)) { free(lm); ret = NLOPT_OUT_OF_MEMORY; } else if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP; else if (*lm < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED; else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED; else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED; else pts_update_newlm(n, &d.pts, lm); } /* TODO: additional stopping criteria based e.g. on improvement in function values, etc? */ node = rb_tree_succ(node); } } get_minf(&d, minf, x); done: nlopt_sobol_destroy(d.s); rb_tree_destroy_with_keys(&d.lms); rb_tree_destroy_with_keys(&d.pts); return ret; }