SDDSlib
Loading...
Searching...
No Matches
gridopt.c File Reference

Functions for performing grid search and random search minimization on an N-dimensional function. More...

#include "mdb.h"

Go to the source code of this file.

Macros

#define OPTIM_ABORT   0x0001UL
 

Functions

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 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 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.
 
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.
 

Variables

static unsigned long optimFlags = 0
 

Detailed Description

Functions for performing grid search and random search minimization on an N-dimensional function.

This file provides several methods for locating the minimum of a function that may be expensive or complicated to evaluate. The methods include:

  • grid_search_min(): Systematically samples the parameter space at fixed intervals.
  • grid_sample_min(): Randomly samples a grid of points in the parameter space.
  • randomSampleMin(): Selects random points in the parameter space to find a suitable starting point.
  • randomWalkMin(): Performs a random walk starting from a given point, potentially refining a solution. Additionally, optimAbort() can signal an external abort condition to halt the search processes.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, R. Soliday, Y. Wang

Definition in file gridopt.c.

Macro Definition Documentation

◆ OPTIM_ABORT

#define OPTIM_ABORT   0x0001UL

Definition at line 26 of file gridopt.c.

Function Documentation

◆ grid_sample_min()

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.

This routine performs a grid-based search similar to grid_search_min(), but only evaluates a fraction of the points, chosen randomly. It returns the best found minimum and updates xReturn with the coordinates of that minimum.

Parameters
best_resultPointer to a double that will store the best function value found.
xReturnPointer to an array that will be updated with the coordinates of the minimum.
lowerArray specifying the lower bounds of each dimension.
upperArray specifying the upper bounds of each dimension.
stepArray specifying the step sizes for each dimension.
n_dimenThe number of dimensions.
targetThe target function value to achieve or surpass.
funcThe function to minimize.
sample_fractionThe fraction or number of points to sample from the grid.
random_fOptional random function for generating samples (default random_1).
Returns
Returns 1 if a minimum was found, otherwise 0.

Definition at line 154 of file gridopt.c.

164 {
165 static double *x = NULL, *best_x = NULL;
166 static long last_n_dimen = 0;
167 static long *index, *counter, *maxcount;
168 double result;
169 long flag, i, best_found;
170
171 optimFlags = 0;
172
173 if (random_f == NULL)
174 random_f = random_1;
175
176 if (last_n_dimen < n_dimen) {
177 if (x)
178 tfree(x);
179 if (index)
180 tfree(index);
181 if (counter)
182 tfree(counter);
183 if (maxcount)
184 tfree(maxcount);
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;
191 }
192
193 *best_result = DBL_MAX;
194 for (i = 0; i < n_dimen; i++) {
195 index[i] = i;
196 counter[i] = 0;
197 x[i] = lower[i];
198 if (lower[i] >= upper[i]) {
199 step[i] = 0;
200 maxcount[i] = 0;
201 } else {
202 maxcount[i] = (upper[i] - lower[i]) / step[i] + 1.5;
203 if (maxcount[i] <= 1)
204 maxcount[i] = 2;
205 step[i] = (upper[i] - lower[i]) / (maxcount[i] - 1);
206 }
207 }
208
209 if (sample_fraction >= 1) {
210 double npoints = 1;
211 for (i = 0; i < n_dimen; i++)
212 npoints *= maxcount[i];
213 sample_fraction /= npoints;
214 }
215
216 best_found = 0;
217 do {
218 if (sample_fraction < (*random_f)(1))
219 continue;
220 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
221 *best_result = result;
222 for (i = 0; i < n_dimen; i++)
223 best_x[i] = x[i];
224 best_found = 1;
225 if (result < target)
226 break;
227 }
228 if (optimFlags & OPTIM_ABORT)
229 break;
230 } while (advance_values(x, index, lower, step, n_dimen, counter, maxcount, n_dimen) >= 0);
231
232 if (best_found)
233 for (i = 0; i < n_dimen; i++)
234 xReturn[i] = best_x[i];
235
236 return (best_found);
237}
int tfree(void *ptr)
Frees a memory block and records the deallocation if tracking is enabled.
Definition array.c:230
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
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.
Definition counter.c:31
double random_1(long iseed)
Generate a uniform random double in [0,1] using a custom seed initialization.
Definition drand.c:175

◆ grid_search_min()

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.

Given ranges and steps for each dimension, this function systematically evaluates the target function over a grid of points. It returns the best found minimum and updates xReturn with the coordinates of that minimum.

Parameters
best_resultPointer to a double that will store the best function value found.
xReturnPointer to an array that will be updated with the coordinates of the minimum.
lowerArray specifying the lower bounds of each dimension.
upperArray specifying the upper bounds of each dimension.
stepArray specifying the step sizes for each dimension.
n_dimenThe number of dimensions in the parameter space.
targetThe target function value to achieve or surpass.
funcA pointer to the function to minimize, taking coordinates and returning a value and validity flag.
Returns
Returns 1 if a minimum was found, otherwise 0.

Definition at line 64 of file gridopt.c.

72 {
73 static double *x = NULL, *best_x = NULL;
74 static long last_n_dimen = 0;
75 static long *index, *counter, *maxcount;
76 double result;
77 long flag, i, best_found;
78
79 optimFlags = 0;
80
81 if (last_n_dimen < n_dimen) {
82 if (x)
83 tfree(x);
84 if (index)
85 tfree(index);
86 if (counter)
87 tfree(counter);
88 if (maxcount)
89 tfree(maxcount);
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;
96 }
97
98 *best_result = DBL_MAX;
99 for (i = 0; i < n_dimen; i++) {
100 index[i] = i;
101 counter[i] = 0;
102 x[i] = lower[i];
103 if (lower[i] >= upper[i]) {
104 step[i] = 0;
105 maxcount[i] = 0;
106 } else {
107 maxcount[i] = (upper[i] - lower[i]) / step[i] + 1.5;
108 if (maxcount[i] <= 1)
109 maxcount[i] = 2;
110 step[i] = (upper[i] - lower[i]) / (maxcount[i] - 1);
111 }
112 }
113
114 best_found = 0;
115 do {
116 if ((result = (*func)(x, &flag)) < *best_result && flag == 0) {
117 *best_result = result;
118 for (i = 0; i < n_dimen; i++)
119 best_x[i] = x[i];
120 best_found = 1;
121 if (result < target)
122 break;
123 }
124 if (optimFlags & OPTIM_ABORT)
125 break;
126 } while (advance_values(x, index, lower, step, n_dimen, counter, maxcount, n_dimen) >= 0);
127
128 if (best_found)
129 for (i = 0; i < n_dimen; i++)
130 xReturn[i] = best_x[i];
131
132 return (best_found);
133}

◆ optimAbort()

long optimAbort ( long abort)

Set or query the abort condition for optimization routines.

When called with a non-zero parameter, this function sets an internal flag that signals the optimization routines to abort their search. When called with zero, it returns the current state of the abort flag.

Parameters
abortIf non-zero, sets the abort condition. If zero, simply queries it.
Returns
Returns 1 if the abort flag is set, otherwise 0.

Definition at line 39 of file gridopt.c.

39 {
40 if (abort) {
41 /* if zero, then operation is a query */
42 optimFlags |= OPTIM_ABORT;
43 }
44 return optimFlags & OPTIM_ABORT ? 1 : 0;
45}

◆ randomSampleMin()

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.

This routine randomly samples points in the given parameter space (defined by lower and upper bounds) for a specified number of samples. It returns the best found minimum and updates xReturn with its coordinates.

Parameters
best_resultPointer to a double that will store the best function value found.
xReturnPointer to an array that will be updated with the coordinates of the minimum.
lowerArray specifying the lower bounds of each dimension.
upperArray specifying the upper bounds of each dimension.
n_dimenThe number of dimensions.
targetThe target function value.
funcThe function to minimize.
nSamplesThe number of random samples to try.
random_fOptional random function for sampling (default random_1).
Returns
Returns 1 if a minimum was found, otherwise 0.

Definition at line 256 of file gridopt.c.

265 {
266 double *x, *xBest;
267 double result;
268 long flag, i, best_found = 0;
269
270 optimFlags = 0;
271 if (random_f == NULL)
272 random_f = random_1;
273
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;
279 while (nSamples--) {
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++)
285 xBest[i] = x[i];
286 best_found = 1;
287 if (result < target)
288 break;
289 }
290 if (optimFlags & OPTIM_ABORT)
291 break;
292 }
293 if (best_found) {
294 for (i = 0; i < n_dimen; i++)
295 xReturn[i] = xBest[i];
296 }
297 free(x);
298 free(xBest);
299 return (best_found);
300}

◆ randomWalkMin()

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.

This function starts at a user-supplied point and randomly perturbs it within given bounds and step sizes. It evaluates the function at each new point, seeking improvements. If a better minimum is found, xReturn is updated.

Parameters
best_resultPointer to a double that will store the best found function value.
xReturnPointer to an array with the starting coordinates, updated on success.
lowerArray specifying the lower bounds for each dimension.
upperArray specifying the upper bounds for each dimension.
stepSizeArray specifying the maximum step size for random perturbations in each dimension.
n_dimenThe number of dimensions.
targetThe target function value.
funcThe function to minimize.
nSamplesThe number of random steps to take.
random_fOptional random function (default random_1).
Returns
Returns 1 if a minimum was found, otherwise 0.

Definition at line 321 of file gridopt.c.

331 {
332 double *x, *xBest;
333 double result;
334 long flag, i, best_found = 0;
335
336 optimFlags = 0;
337
338 if (random_f == NULL)
339 random_f = random_1;
340
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;
346 while (nSamples--) {
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])
350 x[i] = lower[i];
351 if (upper && x[i] > upper[i])
352 x[i] = upper[i];
353 }
354 result = (*func)(x, &flag);
355 if (flag == 0 && result < *best_result) {
356 *best_result = result;
357 for (i = 0; i < n_dimen; i++)
358 xBest[i] = x[i];
359 best_found = 1;
360 if (result < target)
361 break;
362 }
363 if (optimFlags & OPTIM_ABORT)
364 break;
365 }
366 if (best_found) {
367 for (i = 0; i < n_dimen; i++)
368 xReturn[i] = xBest[i];
369 }
370 free(x);
371 free(xBest);
372 return (best_found);
373}

Variable Documentation

◆ optimFlags

unsigned long optimFlags = 0
static

Definition at line 27 of file gridopt.c.