26#define OPTIM_ABORT 0x0001UL
27static MDB_THREAD_LOCK optimFlagsLock = MDB_THREAD_LOCK_INITIALIZER;
28static unsigned long optimFlags = 0;
30static void clearOptimAbort(
void) {
31 mdb_thread_lock(&optimFlagsLock);
32 optimFlags &= ~OPTIM_ABORT;
33 mdb_thread_unlock(&optimFlagsLock);
36static long optimAbortRequested(
void) {
39 mdb_thread_lock(&optimFlagsLock);
40 requested = (optimFlags & OPTIM_ABORT) ? 1 : 0;
41 mdb_thread_unlock(&optimFlagsLock);
58 mdb_thread_lock(&optimFlagsLock);
61 optimFlags |= OPTIM_ABORT;
63 requested = (optimFlags & OPTIM_ABORT) ? 1 : 0;
64 mdb_thread_unlock(&optimFlagsLock);
93 double (*func)(
double *x,
long *invalid)) {
94 static MDB_THREAD_LOCAL
double *x = NULL, *best_x = NULL;
95 static MDB_THREAD_LOCAL
long last_n_dimen = 0;
96 static MDB_THREAD_LOCAL
long *index = NULL, *counter = NULL, *maxcount = NULL;
98 long flag, i, best_found;
102 if (last_n_dimen < n_dimen) {
113 x =
tmalloc(
sizeof(*x) * n_dimen);
114 best_x =
tmalloc(
sizeof(*best_x) * n_dimen);
115 index =
tmalloc(
sizeof(*index) * n_dimen);
116 counter =
tmalloc(
sizeof(*counter) * n_dimen);
117 maxcount =
tmalloc(
sizeof(*maxcount) * n_dimen);
118 last_n_dimen = n_dimen;
121 *best_result = DBL_MAX;
122 for (i = 0; i < n_dimen; i++) {
126 if (lower[i] >= upper[i]) {
130 maxcount[i] = (upper[i] - lower[i]) / step[i] + 1.5;
131 if (maxcount[i] <= 1)
133 step[i] = (upper[i] - lower[i]) / (maxcount[i] - 1);
139 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
140 *best_result = result;
141 for (i = 0; i < n_dimen; i++)
147 if (optimAbortRequested())
149 }
while (
advance_values(x, index, lower, step, n_dimen, counter, maxcount, n_dimen) >= 0);
152 for (i = 0; i < n_dimen; i++)
153 xReturn[i] = best_x[i];
185 double (*func)(
double *x,
long *invalid),
186 double sample_fraction,
187 double (*random_f)(
long iseed)) {
188 static MDB_THREAD_LOCAL
double *x = NULL, *best_x = NULL;
189 static MDB_THREAD_LOCAL
long last_n_dimen = 0;
190 static MDB_THREAD_LOCAL
long *index = NULL, *counter = NULL, *maxcount = NULL;
192 long flag, i, best_found;
196 if (random_f == NULL)
199 if (last_n_dimen < n_dimen) {
210 x =
tmalloc(
sizeof(*x) * n_dimen);
211 best_x =
tmalloc(
sizeof(*best_x) * n_dimen);
212 index =
tmalloc(
sizeof(*index) * n_dimen);
213 counter =
tmalloc(
sizeof(*counter) * n_dimen);
214 maxcount =
tmalloc(
sizeof(*maxcount) * n_dimen);
215 last_n_dimen = n_dimen;
218 *best_result = DBL_MAX;
219 for (i = 0; i < n_dimen; i++) {
223 if (lower[i] >= upper[i]) {
227 maxcount[i] = (upper[i] - lower[i]) / step[i] + 1.5;
228 if (maxcount[i] <= 1)
230 step[i] = (upper[i] - lower[i]) / (maxcount[i] - 1);
234 if (sample_fraction >= 1) {
236 for (i = 0; i < n_dimen; i++)
237 npoints *= maxcount[i];
238 sample_fraction /= npoints;
243 if (sample_fraction < (*random_f)(1))
245 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
246 *best_result = result;
247 for (i = 0; i < n_dimen; i++)
253 if (optimAbortRequested())
255 }
while (
advance_values(x, index, lower, step, n_dimen, counter, maxcount, n_dimen) >= 0);
258 for (i = 0; i < n_dimen; i++)
259 xReturn[i] = best_x[i];
288 double (*func)(
double *x,
long *invalid),
290 double (*random_f)(
long iseed)) {
293 long flag, i, best_found = 0;
296 if (random_f == NULL)
299 x =
tmalloc(
sizeof(*x) * n_dimen);
300 xBest =
tmalloc(
sizeof(*xBest) * n_dimen);
301 for (i = 0; i < n_dimen; i++)
302 xBest[i] = xReturn[i];
303 *best_result = DBL_MAX;
305 for (i = 0; i < n_dimen; i++)
306 x[i] = lower[i] + (upper[i] - lower[i]) * (*random_f)(0);
307 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
308 *best_result = result;
309 for (i = 0; i < n_dimen; i++)
315 if (optimAbortRequested())
319 for (i = 0; i < n_dimen; i++)
320 xReturn[i] = xBest[i];
354 double (*func)(
double *x,
long *invalid),
356 double (*random_f)(
long iseed)) {
359 long flag, i, best_found = 0;
363 if (random_f == NULL)
366 x =
tmalloc(
sizeof(*x) * n_dimen);
367 xBest =
tmalloc(
sizeof(*xBest) * n_dimen);
368 for (i = 0; i < n_dimen; i++)
369 xBest[i] = xReturn[i];
370 *best_result = DBL_MAX;
372 for (i = 0; i < n_dimen; i++) {
373 x[i] = xBest[i] + 2 * stepSize[i] * (0.5 - random_f(0));
374 if (lower && x[i] < lower[i])
376 if (upper && x[i] > upper[i])
379 result = (*func)(x, &flag);
380 if (flag == 0 && result < *best_result) {
381 *best_result = result;
382 for (i = 0; i < n_dimen; i++)
388 if (optimAbortRequested())
392 for (i = 0; i < n_dimen; i++)
393 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.