26#define OPTIM_ABORT 0x0001UL
27static unsigned long optimFlags = 0;
42 optimFlags |= OPTIM_ABORT;
44 return optimFlags & OPTIM_ABORT ? 1 : 0;
72 double (*func)(
double *x,
long *invalid)) {
73 static double *x = NULL, *best_x = NULL;
74 static long last_n_dimen = 0;
75 static long *index, *counter, *maxcount;
77 long flag, i, best_found;
81 if (last_n_dimen < n_dimen) {
90 x =
tmalloc(
sizeof(*x) * n_dimen);
91 best_x =
tmalloc(
sizeof(*best_x) * n_dimen);
92 index =
tmalloc(
sizeof(*index) * n_dimen);
93 counter =
tmalloc(
sizeof(*counter) * n_dimen);
94 maxcount =
tmalloc(
sizeof(*maxcount) * n_dimen);
95 last_n_dimen = n_dimen;
98 *best_result = DBL_MAX;
99 for (i = 0; i < n_dimen; i++) {
103 if (lower[i] >= upper[i]) {
107 maxcount[i] = (upper[i] - lower[i]) / step[i] + 1.5;
108 if (maxcount[i] <= 1)
110 step[i] = (upper[i] - lower[i]) / (maxcount[i] - 1);
116 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
117 *best_result = result;
118 for (i = 0; i < n_dimen; i++)
124 if (optimFlags & OPTIM_ABORT)
126 }
while (
advance_values(x, index, lower, step, n_dimen, counter, maxcount, n_dimen) >= 0);
129 for (i = 0; i < n_dimen; i++)
130 xReturn[i] = best_x[i];
162 double (*func)(
double *x,
long *invalid),
163 double sample_fraction,
164 double (*random_f)(
long iseed)) {
165 static double *x = NULL, *best_x = NULL;
166 static long last_n_dimen = 0;
167 static long *index, *counter, *maxcount;
169 long flag, i, best_found;
173 if (random_f == NULL)
176 if (last_n_dimen < n_dimen) {
185 x =
tmalloc(
sizeof(*x) * n_dimen);
186 best_x =
tmalloc(
sizeof(*best_x) * n_dimen);
187 index =
tmalloc(
sizeof(*index) * n_dimen);
188 counter =
tmalloc(
sizeof(*counter) * n_dimen);
189 maxcount =
tmalloc(
sizeof(*maxcount) * n_dimen);
190 last_n_dimen = n_dimen;
193 *best_result = DBL_MAX;
194 for (i = 0; i < n_dimen; i++) {
198 if (lower[i] >= upper[i]) {
202 maxcount[i] = (upper[i] - lower[i]) / step[i] + 1.5;
203 if (maxcount[i] <= 1)
205 step[i] = (upper[i] - lower[i]) / (maxcount[i] - 1);
209 if (sample_fraction >= 1) {
211 for (i = 0; i < n_dimen; i++)
212 npoints *= maxcount[i];
213 sample_fraction /= npoints;
218 if (sample_fraction < (*random_f)(1))
220 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
221 *best_result = result;
222 for (i = 0; i < n_dimen; i++)
228 if (optimFlags & OPTIM_ABORT)
230 }
while (
advance_values(x, index, lower, step, n_dimen, counter, maxcount, n_dimen) >= 0);
233 for (i = 0; i < n_dimen; i++)
234 xReturn[i] = best_x[i];
263 double (*func)(
double *x,
long *invalid),
265 double (*random_f)(
long iseed)) {
268 long flag, i, best_found = 0;
271 if (random_f == NULL)
274 x =
tmalloc(
sizeof(*x) * n_dimen);
275 xBest =
tmalloc(
sizeof(*xBest) * n_dimen);
276 for (i = 0; i < n_dimen; i++)
277 xBest[i] = xReturn[i];
278 *best_result = DBL_MAX;
280 for (i = 0; i < n_dimen; i++)
281 x[i] = lower[i] + (upper[i] - lower[i]) * (*random_f)(0);
282 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
283 *best_result = result;
284 for (i = 0; i < n_dimen; i++)
290 if (optimFlags & OPTIM_ABORT)
294 for (i = 0; i < n_dimen; i++)
295 xReturn[i] = xBest[i];
329 double (*func)(
double *x,
long *invalid),
331 double (*random_f)(
long iseed)) {
334 long flag, i, best_found = 0;
338 if (random_f == NULL)
341 x =
tmalloc(
sizeof(*x) * n_dimen);
342 xBest =
tmalloc(
sizeof(*xBest) * n_dimen);
343 for (i = 0; i < n_dimen; i++)
344 xBest[i] = xReturn[i];
345 *best_result = DBL_MAX;
347 for (i = 0; i < n_dimen; i++) {
348 x[i] = xBest[i] + 2 * stepSize[i] * (0.5 - random_f(0));
349 if (lower && x[i] < lower[i])
351 if (upper && x[i] > upper[i])
354 result = (*func)(x, &flag);
355 if (flag == 0 && result < *best_result) {
356 *best_result = result;
357 for (i = 0; i < n_dimen; i++)
363 if (optimFlags & OPTIM_ABORT)
367 for (i = 0; i < n_dimen; i++)
368 xReturn[i] = xBest[i];
int tfree(void *ptr)
Frees a memory block and records the deallocation if tracking is enabled.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
long advance_values(double *value, long *value_index, double *initial, double *step, long n_values, long *counter, long *max_count, long n_indices)
Sequences an array of values systematically to cover an n-dimensional grid.
double random_1(long iseed)
Generate a uniform random double in [0,1] using a custom seed initialization.
long randomWalkMin(double *best_result, double *xReturn, double *lower, double *upper, double *stepSize, long n_dimen, double target, double(*func)(double *x, long *invalid), long nSamples, double(*random_f)(long iseed))
Perform a random walk starting from a given point to find a function minimum.
long grid_sample_min(double *best_result, double *xReturn, double *lower, double *upper, double *step, long n_dimen, double target, double(*func)(double *x, long *invalid), double sample_fraction, double(*random_f)(long iseed))
Perform a partial (sampled) grid search to find the minimum of a function.
long optimAbort(long abort)
Set or query the abort condition for optimization routines.
long grid_search_min(double *best_result, double *xReturn, double *lower, double *upper, double *step, long n_dimen, double target, double(*func)(double *x, long *invalid))
Perform a grid search to find the minimum of a given function.
long randomSampleMin(double *best_result, double *xReturn, double *lower, double *upper, long n_dimen, double target, double(*func)(double *x, long *invalid), long nSamples, double(*random_f)(long iseed))
Randomly sample the parameter space to find a minimum.