/*********************************************************************** * Lester Ingber (copyright) (c) * See COPYING License in this directory * Date 1 Jan 93 ***********************************************************************/ #define USER_ID \ "/* $Id: user.c,v 2.3 1993/12/22 04:47:35 ingber Exp ingber $ */" #include "user.h" #if SELF_OPTIMIZE #else /*********************************************************************** * main * This is a sample calling program to optimize using ASA ***********************************************************************/ #if HAVE_ANSI int main(int argc, char **argv) #else int main(argc, argv) int argc; char **argv; #endif { int *exit_code; int compile_cnt; /* flags to act on some Program Options */ int *cost_curvature_0, *user_parameter_temp_flag, *user_cost_temp_flag, *user_delta_flag, *user_ratio_temp_flag; int *user_quench_param_flag, *user_quench_cost_flag; /* pointer to array storage for asa arguments */ double *parameter_lower_bound, *parameter_upper_bound, *cost_parameters, *cost_tangents, *cost_curvature; double cost_value; /* the number of parameters to optimize */ ALLOC_INT *parameter_dimension; /* pointer to array storage for parameter type flags */ int *parameter_int_real; /* valid flag for cost function */ int *cost_flag; USER_DEFINES *USER_OPTIONS; #if OPTIONS_FILE FILE *ptr_options; char read_option[80]; int read_int; LONG_INT read_long; double read_double; #endif #if ASA_TEMPLATE #if USER_ASA_OUT int n_asa, n_trajectory, index; #if HAVE_ANSI char asa_file[8] = "asa_x_y"; #else char asa_file[8]; asa_file[0] = asa_file[2] = 'a'; asa_file[1] = 's'; asa_file[3] = asa_file[5] = '_'; asa_file[4] = 'x'; asa_file[6] = 'y'; asa_file[7] = '\0'; #endif /* HAVE_ANSI */ #endif /* USER_ASA_OUT */ #endif /* ASA_TEMPLATE */ /* open the output file */ ptr_out = fopen("user_out", "w"); fprintf(ptr_out, "%s\n\n", USER_ID); /* print out compile options set by user in Makefile */ if (argc > 0) { fprintf(ptr_out, "CC = %s\n", argv[1]); for (compile_cnt = 2; compile_cnt < argc; ++compile_cnt) { fprintf(ptr_out, "\t%s\n", argv[compile_cnt]); } fprintf(ptr_out, "\n"); } #if TIME_CALC /* print starting time */ print_time("start"); #endif fflush(ptr_out); #if OPTIONAL_DATA /* Set memory to that required for use. */ if ((USER_OPTIONS->asa_data = (double *) calloc(2, sizeof(double))) == NULL) exit(9); /* Use asa_data[0] as flag, e.g., if used with SELF_OPTIMIZE. */ USER_OPTIONS->asa_data[0] = 1.0; #endif initialize_rng(); /* Initialize the users parameters, allocating space, etc. Note that the default is to have asa generate the initial cost_parameters that satisfy the user's constraints. */ if ((cost_curvature_0 = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((user_quench_param_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((user_quench_cost_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((user_parameter_temp_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((user_cost_temp_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((user_delta_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((user_ratio_temp_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((parameter_dimension = (ALLOC_INT *) calloc(1, sizeof(ALLOC_INT))) == NULL) exit(9); if ((exit_code = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((cost_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); #if SELF_OPTIMIZE #else if ((USER_OPTIONS = (USER_DEFINES *) calloc(1, sizeof(USER_DEFINES))) == NULL) exit(9); #if OPTIONS_FILE ptr_options = fopen("asa_opt", "r"); fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->LIMIT_ACCEPTANCES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->COST_PRECISION = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->MAXIMUM_COST_REPEAT = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->NUMBER_COST_SAMPLES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->TEMPERATURE_RATIO_SCALE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->COST_PARAMETER_SCALE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->USER_INITIAL_COST_TEMP = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->USER_INITIAL_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->RATIO_TEMPERATURE_SCALES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->TESTING_FREQUENCY_MODULUS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->ACTIVATE_REANNEAL = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->REANNEAL_RESCALE = read_double; fscanf(ptr_options, "%s", read_option); #if INT_LONG fscanf(ptr_options, "%ld", &read_long); #else fscanf(ptr_options, "%d", &read_long); #endif USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = read_long; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); USER_OPTIONS->DELTA_X = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->DELTA_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->CURVATURE_0 = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->QUENCH_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); USER_OPTIONS->QUENCH_COST = read_int; fclose(ptr_options); #else /* OPTIONS_FILE */ /* USER_OPTIONS->LIMIT_ACCEPTANCES = 10000; */ USER_OPTIONS->LIMIT_ACCEPTANCES = 1000; USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 1000; /* USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-6; */ USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-4; USER_OPTIONS->COST_PRECISION = 1.0E-18; USER_OPTIONS->MAXIMUM_COST_REPEAT = 5; USER_OPTIONS->NUMBER_COST_SAMPLES = 5; USER_OPTIONS->TEMPERATURE_RATIO_SCALE = 1.0E-5; USER_OPTIONS->COST_PARAMETER_SCALE = 1.0; USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = 100.0; USER_OPTIONS->USER_INITIAL_COST_TEMP = FALSE; USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = FALSE; USER_OPTIONS->USER_INITIAL_PARAMETERS = FALSE; USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = 1.0; USER_OPTIONS->RATIO_TEMPERATURE_SCALES = FALSE; USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = FALSE; USER_OPTIONS->TESTING_FREQUENCY_MODULUS = 100; USER_OPTIONS->ACTIVATE_REANNEAL = TRUE; USER_OPTIONS->REANNEAL_RESCALE = 10.0; USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = 50000; USER_OPTIONS->DELTA_X = 0.001; USER_OPTIONS->DELTA_PARAMETERS = FALSE; USER_OPTIONS->CURVATURE_0 = FALSE; USER_OPTIONS->QUENCH_PARAMETERS = FALSE; USER_OPTIONS->QUENCH_COST = FALSE; #endif /* OPTIONS_FILE */ #endif /* SELF_OPTIMIZE */ /* set flags for Program Options */ *cost_curvature_0 = USER_OPTIONS->CURVATURE_0; *user_parameter_temp_flag = USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS; *user_cost_temp_flag = USER_OPTIONS->USER_INITIAL_COST_TEMP; *user_delta_flag = USER_OPTIONS->DELTA_PARAMETERS; *user_ratio_temp_flag = USER_OPTIONS->RATIO_TEMPERATURE_SCALES; *user_quench_param_flag = USER_OPTIONS->QUENCH_PARAMETERS; *user_quench_cost_flag = USER_OPTIONS->QUENCH_COST; /* ALLOCATE STORAGE */ #if USER_ASA_OUT if ((USER_OPTIONS->asa_out_file = (char *) calloc(80, sizeof(char)) ) == NULL) exit(9); #endif /* the number of parameters for the cost function */ #if ASA_TEST *parameter_dimension = 4; #endif /* allocate parameter minimum space */ if ((parameter_lower_bound = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); /* allocate parameter maximum space */ if ((parameter_upper_bound = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); /* allocate parameter initial values; the parameter final values will be stored here later */ if ((cost_parameters = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); /* allocate the parameter types, real or integer */ if ((parameter_int_real = (int *) calloc(*parameter_dimension, sizeof(int)) ) == NULL) exit(9); /* allocate space for parameter cost_tangents - used for reannealing */ if ((cost_tangents = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); if (*cost_curvature_0 == FALSE) { /* allocate space for parameter cost_curvatures/covariance */ if ((cost_curvature = (double *) calloc((*parameter_dimension) * (*parameter_dimension), sizeof(double))) == NULL) exit(9); } else { cost_curvature = (double *) NULL; } initialize_parameters(cost_parameters, parameter_lower_bound, parameter_upper_bound, cost_tangents, cost_curvature, parameter_dimension, parameter_int_real, cost_curvature_0, user_parameter_temp_flag, user_cost_temp_flag, user_delta_flag, user_ratio_temp_flag, user_quench_param_flag, user_quench_cost_flag, USER_OPTIONS); /* optimize the cost_function, returning the results in cost_value and cost_parameters */ #if ASA_TEMPLATE #if USER_ASA_OUT /* multiple asa() quenched calls + multiple asa_out files (To get longer quenched runs, decrease SMALL_FLOAT.) */ for (n_asa = 1; n_asa <= *parameter_dimension; n_asa++) { asa_file[4] = 'A' + n_asa - 1; if (USER_OPTIONS->QUENCH_COST == TRUE) USER_OPTIONS->user_quench_cost_scale[0] = (double) n_asa; if (USER_OPTIONS->QUENCH_PARAMETERS == TRUE) for (index = 0; index < *parameter_dimension; ++index) USER_OPTIONS->user_quench_param_scale[index] = (double) n_asa; for (n_trajectory = 0; n_trajectory < 3; ++n_trajectory) { asa_file[6] = 'a' + n_trajectory; strcpy(USER_OPTIONS->asa_out_file, asa_file); #endif #endif cost_value = asa(cost_function, randflt, cost_parameters, parameter_lower_bound, parameter_upper_bound, cost_tangents, cost_curvature, parameter_dimension, parameter_int_real, cost_flag, exit_code, USER_OPTIONS); #if TIME_CALC /* print ending time */ print_time("end"); #endif #if ASA_TEMPLATE #if USER_ASA_OUT } } #endif #endif /* close all files */ fclose(ptr_out); #if OPTIONAL_DATA free(USER_OPTIONS->asa_data); #endif #if USER_ASA_OUT free(USER_OPTIONS->asa_out_file); #endif free(USER_OPTIONS); free(user_quench_param_flag); free(user_quench_cost_flag); free(user_parameter_temp_flag); free(user_cost_temp_flag); free(user_delta_flag); free(user_ratio_temp_flag); free(parameter_dimension); free(exit_code); free(cost_flag); free(parameter_lower_bound); free(parameter_upper_bound); free(cost_parameters); free(parameter_int_real); free(cost_tangents); if (*cost_curvature_0 == FALSE) free(cost_curvature); free(cost_curvature_0); exit(0); /* NOTREACHED */ } #endif /* SELF_OPTIMIZE */ #if ASA_TEST /* defines for the test problem, which assume *parameter_dimension is a multiple of 4. If this is set to a large number, you likely should set CURVATURE_0 to TRUE. */ #if __GNUC__ /* For _some_ versions of gcc the following may work */ /* #define ARRAY_LIMIT *parameter_dimension */ #define ARRAY_LIMIT 4 /* set equal to *parameter_dimension */ #else #define ARRAY_LIMIT 4 /* set equal to *parameter_dimension */ #endif #define ARR_LMT4 (ARRAY_LIMIT/4) #endif /* ASA_TEST */ /*********************************************************************** * initialize_parameters - sample parameter initialization function * This depends on the users cost function to optimize (minimum). * The routine allocates storage needed for asa. The user should * define the number of parameters and their ranges, * and make sure the initial parameters are within * the minimum and maximum ranges. The array * parameter_int_real should be REAL_TYPE (-1) for real parameters, * and INTEGER_TYPE (1) for integer values ***********************************************************************/ #if HAVE_ANSI void initialize_parameters(double *cost_parameters, double *parameter_lower_bound, double *parameter_upper_bound, double *cost_tangents, double *cost_curvature, ALLOC_INT * parameter_dimension, int *parameter_int_real, int *cost_curvature_0, int *user_parameter_temp_flag, int *user_cost_temp_flag, int *user_delta_flag, int *user_ratio_temp_flag, int *user_quench_param_flag, int *user_quench_cost_flag, USER_DEFINES * USER_OPTIONS) #else void initialize_parameters(cost_parameters, parameter_lower_bound, parameter_upper_bound, cost_tangents, cost_curvature, parameter_dimension, parameter_int_real, cost_curvature_0, user_parameter_temp_flag, user_cost_temp_flag, user_delta_flag, user_ratio_temp_flag, user_quench_param_flag, user_quench_cost_flag, USER_OPTIONS) double *cost_parameters; double *parameter_lower_bound; double *parameter_upper_bound; double *cost_tangents; double *cost_curvature; ALLOC_INT *parameter_dimension; int *parameter_int_real; int *cost_curvature_0; int *user_parameter_temp_flag; int *user_cost_temp_flag; int *user_delta_flag; int *user_ratio_temp_flag; int *user_quench_param_flag; int *user_quench_cost_flag; USER_DEFINES *USER_OPTIONS; #endif { ALLOC_INT index; #if ASA_TEST /* store some parameter ranges */ for (index = 0; index < *parameter_dimension; ++index) parameter_lower_bound[index] = -10000.0; for (index = 0; index < *parameter_dimension; ++index) parameter_upper_bound[index] = 10000.0; /* store the initial parameter types */ for (index = 0; index < *parameter_dimension; ++index) parameter_int_real[index] = REAL_TYPE; /* store the initial parameter values */ for (index = 0; index < ARR_LMT4; ++index) { cost_parameters[4 * (index + 1) - 4] = 999.0; cost_parameters[4 * (index + 1) - 3] = -1007.0; cost_parameters[4 * (index + 1) - 2] = 1001.0; cost_parameters[4 * (index + 1) - 1] = -903.0; } #endif /* If USER_INITIAL_PARAMETERS_TEMPS=TRUE, then these must be defined for all parameters. */ if (*user_parameter_temp_flag == TRUE) { if ((USER_OPTIONS->user_parameter_temperature = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); for (index = 0; index < *parameter_dimension; ++index) USER_OPTIONS->user_parameter_temperature[index] = 1.0; } /* If USER_INITIAL_COST_TEMP=TRUE, then this must be defined. */ if (*user_cost_temp_flag == TRUE) { if ((USER_OPTIONS->user_cost_temperature = (double *) calloc(1, sizeof(double))) == NULL) exit(9); USER_OPTIONS->user_cost_temperature[0] = 5.936648E+09; } /* If DELTA_PARAMETERS=TRUE, then these must be defined for all parameters that will be pseudo-differentiated. */ if (*user_delta_flag == TRUE) { if ((USER_OPTIONS->user_delta_parameter = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); for (index = 0; index < *parameter_dimension; ++index) USER_OPTIONS->user_delta_parameter[index] = 0.001; } /* If QUENCH_PARAMETERS=TRUE, then these must be defined for all parameters. */ if (*user_quench_param_flag == TRUE) { if ((USER_OPTIONS->user_quench_param_scale = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); for (index = 0; index < *parameter_dimension; ++index) USER_OPTIONS->user_quench_param_scale[index] = 1.0; } /* If QUENCH_COST=TRUE, then this must be defined. */ if (*user_quench_cost_flag == TRUE) { if ((USER_OPTIONS->user_quench_cost_scale = (double *) calloc(1, sizeof(double))) == NULL) exit(9); USER_OPTIONS->user_quench_cost_scale[0] = 1.0; } /* If RATIO_TEMPERATURE_SCALES=TRUE, then these must be defined for all parameters. */ if (*user_ratio_temp_flag == TRUE) { if ((USER_OPTIONS->user_temperature_ratio = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); for (index = 0; index < *parameter_dimension; ++index) USER_OPTIONS->user_temperature_ratio[index] = 1.0; } } /*********************************************************************** * double cost_function * This is the users cost function to optimize * (find the minimum). * cost_flag is set to true if the parameter set * does not violates any constraints * parameter_lower_bound and parameter_upper_bound may be * adaptively changed during the search. ***********************************************************************/ #if HAVE_ANSI double cost_function(double *x, double *parameter_lower_bound, double *parameter_upper_bound, double *cost_tangents, double *cost_curvature, ALLOC_INT * parameter_dimension, int *parameter_int_real, int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS) #else double cost_function(x, parameter_lower_bound, parameter_upper_bound, cost_tangents, cost_curvature, parameter_dimension, parameter_int_real, cost_flag, exit_code, USER_OPTIONS) double *x; double *parameter_lower_bound; double *parameter_upper_bound; double *cost_tangents; double *cost_curvature; ALLOC_INT *parameter_dimension; int *parameter_int_real; int *cost_flag; int *exit_code; USER_DEFINES *USER_OPTIONS; #endif { #if ASA_TEST /* ASA test problem */ /* Objective function from * %A A. Corana * %A M. Marchesi * %A C. Martini * %A S. Ridella * %T Minimizing multimodal functions of continuous variables * with the "simulated annealing" algorithm * %J ACM Trans. Mathl. Software * %V 13 * %S 3 * %P 262-279 * %D 1987 * Mark Johnson wrote this particular code. * * This function contains 1.0E20 local minima. When *parameter_dimension * is equal to 4, visiting each minimum for a millisecond would take * about the present age of the universe to visit all these minima. */ double s[ARRAY_LIMIT], t[ARRAY_LIMIT], d[ARRAY_LIMIT]; double term, summ, dj, c, deviate; LONG_INT i; #if SELF_OPTIMIZE #else static LONG_INT funevals = 0; #endif for (i = 0; i < ARRAY_LIMIT; ++i) { s[i] = 0.2; t[i] = 0.05; } for (i = 0; i < ARR_LMT4; ++i) { d[4 * (i + 1) - 4] = 1.0; d[4 * (i + 1) - 3] = 1000.0; d[4 * (i + 1) - 2] = 10.0; d[4 * (i + 1) - 1] = 100.0; } c = 0.15; summ = 0.0; for (i = 0; i < ARRAY_LIMIT; ++i) { dj = floor(fabs(x[i] / s[i]) + 0.49999999); if (x[i] < 0.0) dj = 0.0 - dj; dj = dj * s[i]; deviate = fabs(x[i] - dj); if (deviate < fabs(t[i])) { term = 0.0; if (dj < 0.0) term = t[i]; if (dj > 0.0) term = (0.0 - t[i]); term = term + dj; term = term * term * c * d[i]; } else { term = d[i] * (x[i] * x[i]); } summ = summ + term; } funevals = funevals + 1; *cost_flag = TRUE; #if SELF_OPTIMIZE #else #if TIME_CALC /* print the time every PRINT_FREQUENCY evaluations */ if ((PRINT_FREQUENCY > 0) && ((funevals % PRINT_FREQUENCY) == 0)) { fprintf(ptr_out, "funevals = %ld ", funevals); print_time(""); } #endif #endif return (summ); #endif /* ASA_TEST */ } /* Here is a good random number generator and the auxiliary routines to print the execution time */ #define SHUFFLE 256 /* size of random array */ #define MULT ((LONG_INT) 25173) #define MOD ((LONG_INT) 65536) #define INCR ((LONG_INT) 13849) #define FMOD ((double) 65536.0) static LONG_INT seed = 696969; double random_array[SHUFFLE]; /* random variables */ /*********************************************************************** * double myrand(void) - returns a random number between 0 and 1 * This routine returns the random number generator between 0 and 1 ***********************************************************************/ #if HAVE_ANSI double myrand(void) #else double myrand() #endif /* returns random number in {0,1} */ { seed = (LONG_INT) ((MULT * seed + INCR) % MOD); return ((double) seed / FMOD); } /*********************************************************************** * double randflt(void) * Shuffles random numbers in random_array[] ***********************************************************************/ #if HAVE_ANSI double randflt(void) #else double randflt() #endif /* shuffles random numbers in random_array[SHUFFLE] array */ { /* This RNG is a modified algorithm of that presented in * %A K. Binder * %A D. Stauffer * %T A simple introduction to Monte Carlo simulations and some * specialized topics * %B Applications of the Monte Carlo Method in statistical physics * %E K. Binder * %I Springer-Verlag * %C Berlin * %D 1985 * %P 1-36 * where it is stated that such algorithms have been found to be * quite satisfactory in many statistical physics applications. */ double rranf; int kranf; kranf = (int) (myrand() * SHUFFLE) % SHUFFLE; rranf = *(random_array + kranf); *(random_array + kranf) = myrand(); return (rranf); } /*********************************************************************** * initialize_rng() * This routine initializes the random number generator ***********************************************************************/ #if HAVE_ANSI void initialize_rng(void) #else void initialize_rng() #endif { int n; double x; for (n = 0; n < SHUFFLE; ++n) random_array[n] = myrand(); for (n = 0; n < 1000; ++n) /* warm up random generator */ x = randflt(); } #if TIME_CALC /*********************************************************************** * print_time * This calculates the time and runtime and prints it. ***********************************************************************/ #if HAVE_ANSI void print_time(char *message) #else void print_time(message) char *message; #endif { int who = RUSAGE_SELF; /* Check our own time */ struct rusage usage; /* get the resource usage information */ #if TIME_STD syscall(SYS_GETRUSAGE, who, &usage); #else getrusage(who, &usage); #endif /* print the usage time in reasonable form */ aux_print_time(&usage.ru_utime, message); } /*********************************************************************** * aux_print_time * auxiliary print the time routine ***********************************************************************/ #if HAVE_ANSI void aux_print_time(struct timeval *time, char *message) #else void aux_print_time(time, message) struct timeval *time; char *message; #endif { static double sx; double us, s, m, h; double ds, dm, dh; /* calculate the new microseconds, seconds, minutes, hours and the differences since the last call */ us = (double) ((int) ((double) EPS_DOUBLE + time->tv_usec)) / 1.E6; s = (double) ((int) ((double) EPS_DOUBLE + time->tv_sec)) + us; ds = s - sx; sx = s; h = (int) ((double) EPS_DOUBLE + s / 3600.); m = (int) ((double) EPS_DOUBLE + s / 60.) - 60. * h; s -= (3600. * h + 60. * m); dh = (int) ((double) EPS_DOUBLE + ds / 3600.); dm = (int) ((double) EPS_DOUBLE + ds / 60.) - 60. * dh; ds -= (3600. * dh + 60. * dm); /* print the statistics */ fprintf(ptr_out, "%s:time: %gh %gm %gs; incr: %gh %gm %gs\n", message, h, m, s, dh, dm, ds); } #endif /* TIME_CALC */ #if SELF_OPTIMIZE /*********************************************************************** * main * This is a sample calling program to self-optimize ASA ***********************************************************************/ #if HAVE_ANSI int main(int argc, char **argv) #else int main(argc, argv) int argc; char **argv; #endif { #if OPTIONS_FILE FILE *ptr_options; char read_option[80]; int read_int; LONG_INT read_long; double read_double; #endif int *recur_exit_code; int compile_cnt; int *recur_cost_curvature_0, *recur_user_parameter_temp_flag; int *recur_user_cost_temp_flag, *recur_user_delta_flag; int *recur_user_ratio_temp_flag; int *recur_user_quench_param_flag, *recur_user_quench_cost_flag; double *recur_parameter_lower_bound, *recur_parameter_upper_bound, *recur_cost_parameters, *recur_cost_tangents, *recur_cost_curvature; double recur_cost_value; ALLOC_INT *recur_parameter_dimension; int *recur_parameter_int_real; int *recur_cost_flag; int recur_v; USER_DEFINES *RECUR_USER_OPTIONS; if ((recur_cost_curvature_0 = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((recur_user_quench_param_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((recur_user_quench_cost_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((recur_user_parameter_temp_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((recur_user_cost_temp_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((recur_user_delta_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((recur_user_ratio_temp_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((recur_parameter_dimension = (ALLOC_INT *) calloc(1, sizeof(ALLOC_INT))) == NULL) exit(9); if ((recur_exit_code = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((recur_cost_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((RECUR_USER_OPTIONS = (USER_DEFINES *) calloc(1, sizeof(USER_DEFINES))) == NULL) exit(9); #if OPTIONS_FILE ptr_options = fopen("asa_opt", "r"); fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->LIMIT_ACCEPTANCES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->COST_PRECISION = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->MAXIMUM_COST_REPEAT = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->NUMBER_COST_SAMPLES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->TEMPERATURE_RATIO_SCALE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->COST_PARAMETER_SCALE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->TESTING_FREQUENCY_MODULUS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->ACTIVATE_REANNEAL = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->REANNEAL_RESCALE = read_double; fscanf(ptr_options, "%s", read_option); #if INT_LONG fscanf(ptr_options, "%ld", &read_long); #else fscanf(ptr_options, "%d", &read_long); #endif RECUR_USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = read_long; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%lf", &read_double); RECUR_USER_OPTIONS->DELTA_X = read_double; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->DELTA_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->CURVATURE_0 = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->QUENCH_PARAMETERS = read_int; fscanf(ptr_options, "%s", read_option); fscanf(ptr_options, "%d", &read_int); RECUR_USER_OPTIONS->QUENCH_COST = read_int; fclose(ptr_options); #else /* OPTIONS_FILE */ RECUR_USER_OPTIONS->LIMIT_ACCEPTANCES = 100; RECUR_USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 1000; RECUR_USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-4; RECUR_USER_OPTIONS->COST_PRECISION = 1.0E-18; RECUR_USER_OPTIONS->MAXIMUM_COST_REPEAT = 2; RECUR_USER_OPTIONS->NUMBER_COST_SAMPLES = 2; RECUR_USER_OPTIONS->TEMPERATURE_RATIO_SCALE = 1.0E-5; RECUR_USER_OPTIONS->COST_PARAMETER_SCALE = 1.0; RECUR_USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = 100.0; RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP = FALSE; RECUR_USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = FALSE; RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS = TRUE; RECUR_USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = 1.0; RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES = FALSE; RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = FALSE; RECUR_USER_OPTIONS->TESTING_FREQUENCY_MODULUS = 15; RECUR_USER_OPTIONS->ACTIVATE_REANNEAL = FALSE; RECUR_USER_OPTIONS->REANNEAL_RESCALE = 10.0; RECUR_USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = 50000; RECUR_USER_OPTIONS->DELTA_X = 1.0E-6; RECUR_USER_OPTIONS->DELTA_PARAMETERS = FALSE; RECUR_USER_OPTIONS->CURVATURE_0 = TRUE; RECUR_USER_OPTIONS->QUENCH_PARAMETERS = FALSE; RECUR_USER_OPTIONS->QUENCH_COST = FALSE; #endif /* OPTIONS_FILE */ *recur_cost_curvature_0 = RECUR_USER_OPTIONS->CURVATURE_0; *recur_user_parameter_temp_flag = RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS; *recur_user_cost_temp_flag = RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP; *recur_user_delta_flag = RECUR_USER_OPTIONS->DELTA_PARAMETERS; *recur_user_ratio_temp_flag = RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES; *recur_user_quench_param_flag = RECUR_USER_OPTIONS->QUENCH_PARAMETERS; *recur_user_quench_cost_flag = RECUR_USER_OPTIONS->QUENCH_COST; #if ASA_TEMPLATE *recur_parameter_dimension = 2; #endif if ((recur_parameter_lower_bound = (double *) calloc(*recur_parameter_dimension, sizeof(double)) ) == NULL) exit(9); if ((recur_parameter_upper_bound = (double *) calloc(*recur_parameter_dimension, sizeof(double)) ) == NULL) exit(9); if ((recur_cost_parameters = (double *) calloc(*recur_parameter_dimension, sizeof(double)) ) == NULL) exit(9); if ((recur_parameter_int_real = (int *) calloc(*recur_parameter_dimension, sizeof(int)) ) == NULL) exit(9); if ((recur_cost_tangents = (double *) calloc(*recur_parameter_dimension, sizeof(double)) ) == NULL) exit(9); if (*recur_cost_curvature_0 == FALSE) { if ((recur_cost_curvature = (double *) calloc((*recur_parameter_dimension) * (*recur_parameter_dimension), sizeof(double))) == NULL) exit(9); } else { recur_cost_curvature = (double *) NULL; } #if OPTIONAL_DATA /* Set memory to that required for use. */ if ((RECUR_USER_OPTIONS->asa_data = (double *) calloc(1, sizeof(double))) == NULL) exit(9); /* Use asa_data[0] as flag, e.g., if used with SELF_OPTIMIZE. */ RECUR_USER_OPTIONS->asa_data[0] = 0; #endif /* open the output file */ ptr_out = fopen("user_out", "w"); fprintf(ptr_out, "%s\n\n", USER_ID); /* print out compile options set by user in Makefile */ if (argc > 0) { fprintf(ptr_out, "CC = %s\n", argv[1]); for (compile_cnt = 2; compile_cnt < argc; ++compile_cnt) { fprintf(ptr_out, "\t%s\n", argv[compile_cnt]); } fprintf(ptr_out, "\n"); } #if TIME_CALC /* print starting time */ print_time("start"); #endif fflush(ptr_out); initialize_rng(); /* initialize the users parameters, allocating space, etc. Note that the default is to have asa generate the initial recur_cost_parameters that satisfy the user's constraints. */ recur_initialize_parameters(recur_cost_parameters, recur_parameter_lower_bound, recur_parameter_upper_bound, recur_cost_tangents, recur_cost_curvature, recur_parameter_dimension, recur_parameter_int_real, recur_cost_curvature_0, recur_user_parameter_temp_flag, recur_user_cost_temp_flag, recur_user_delta_flag, recur_user_ratio_temp_flag, recur_user_quench_param_flag, recur_user_quench_cost_flag, RECUR_USER_OPTIONS); #if USER_ASA_OUT if ((RECUR_USER_OPTIONS->asa_out_file = (char *) calloc(80, sizeof(char)) ) == NULL) exit(9); #if ASA_TEMPLATE strcpy(RECUR_USER_OPTIONS->asa_out_file, "asa_sfop"); #endif #endif recur_cost_value = asa(recur_cost_function, randflt, recur_cost_parameters, recur_parameter_lower_bound, recur_parameter_upper_bound, recur_cost_tangents, recur_cost_curvature, recur_parameter_dimension, recur_parameter_int_real, recur_cost_flag, recur_exit_code, RECUR_USER_OPTIONS); fprintf(ptr_out, "\n\n recur_cost_value = %g\n", recur_cost_value); for (recur_v = 0; recur_v < *recur_parameter_dimension; ++recur_v) fprintf(ptr_out, "recur_cost_parameters[%d] = %g\n", recur_v, recur_cost_parameters[recur_v]); fprintf(ptr_out, "\n\n"); #if TIME_CALC /* print ending time */ print_time("end"); #endif /* close all files */ fclose(ptr_out); #if OPTIONAL_DATA free(RECUR_USER_OPTIONS->asa_data); #endif #if USER_ASA_OUT free(RECUR_USER_OPTIONS->asa_out_file); #endif free(RECUR_USER_OPTIONS); free(recur_user_quench_param_flag); free(recur_user_quench_cost_flag); free(recur_user_parameter_temp_flag); free(recur_user_cost_temp_flag); free(recur_user_delta_flag); free(recur_user_ratio_temp_flag); free(recur_parameter_dimension); free(recur_exit_code); free(recur_cost_flag); free(recur_parameter_lower_bound); free(recur_parameter_upper_bound); free(recur_cost_parameters); free(recur_parameter_int_real); free(recur_cost_tangents); if (*recur_cost_curvature_0 == FALSE) free(recur_cost_curvature); free(recur_cost_curvature_0); exit(0); /* NOTREACHED */ } /*********************************************************************** * recur_initialize_parameters * This depends on the users cost function to optimize (minimum). * The routine allocates storage needed for asa. The user should * define the number of parameters and their ranges, * and make sure the initial parameters are within * the minimum and maximum ranges. The array * recur_parameter_int_real should be REAL_TYPE (-1) * for real parameters, ***********************************************************************/ #if HAVE_ANSI void recur_initialize_parameters(double *recur_cost_parameters, double *recur_parameter_lower_bound, double *recur_parameter_upper_bound, double *recur_cost_tangents, double *recur_cost_curvature, ALLOC_INT * recur_parameter_dimension, int *recur_parameter_int_real, int *recur_cost_curvature_0, int *recur_user_parameter_temp_flag, int *recur_user_cost_temp_flag, int *recur_user_delta_flag, int *recur_user_ratio_temp_flag, int *recur_user_quench_param_flag, int *recur_user_quench_cost_flag, USER_DEFINES * RECUR_USER_OPTIONS) #else void recur_initialize_parameters(recur_cost_parameters, recur_parameter_lower_bound, recur_parameter_upper_bound, recur_cost_tangents, recur_cost_curvature, recur_parameter_dimension, recur_parameter_int_real, recur_cost_curvature_0, recur_user_parameter_temp_flag, recur_user_cost_temp_flag, recur_user_delta_flag, recur_user_ratio_temp_flag, recur_user_quench_param_flag, recur_user_quench_cost_flag, RECUR_USER_OPTIONS) double *recur_parameter_lower_bound; double *recur_parameter_upper_bound; double *recur_cost_parameters; double *recur_cost_tangents; double *recur_cost_curvature; ALLOC_INT *recur_parameter_dimension; int *recur_parameter_int_real; int *recur_cost_curvature_0; int *recur_user_parameter_temp_flag; int *recur_user_cost_temp_flag; int *recur_user_delta_flag; int *recur_user_ratio_temp_flag; int *recur_user_quench_param_flag; int *recur_user_quench_cost_flag; USER_DEFINES *RECUR_USER_OPTIONS; #endif { ALLOC_INT index; *recur_cost_curvature_0 = RECUR_USER_OPTIONS->CURVATURE_0; *recur_user_parameter_temp_flag = RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS; *recur_user_cost_temp_flag = RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP; *recur_user_delta_flag = RECUR_USER_OPTIONS->DELTA_PARAMETERS; *recur_user_ratio_temp_flag = RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES; #if ASA_TEMPLATE /* USER_OPTIONS->TEMPERATURE_RATIO_SCALE = x[0]; USER_OPTIONS->COST_PARAMETER_SCALE = x[1]; */ /* store the initial parameter values */ recur_cost_parameters[0] = 1.0E-5; recur_cost_parameters[1] = 1.0; recur_parameter_lower_bound[0] = 1.0E-6; recur_parameter_upper_bound[0] = 1.0E-4; recur_parameter_lower_bound[1] = 0.5; recur_parameter_upper_bound[1] = 3.0; #endif /* store the initial parameter types */ for (index = 0; index < *recur_parameter_dimension; ++index) recur_parameter_int_real[index] = REAL_TYPE; /* If USER_INITIAL_PARAMETERS_TEMPS=TRUE, then these must be defined for all parameters. */ if (*recur_user_parameter_temp_flag == TRUE) { if ((RECUR_USER_OPTIONS->user_parameter_temperature = (double *) calloc(*recur_parameter_dimension, sizeof(double))) == NULL) exit(9); for (index = 0; index < *recur_parameter_dimension; ++index) RECUR_USER_OPTIONS->user_parameter_temperature[index] = 1.0; } /* If USER_INITIAL_COST_TEMP=TRUE, then this must be defined. */ if (*recur_user_cost_temp_flag == TRUE) { if ((RECUR_USER_OPTIONS->user_cost_temperature = (double *) calloc(1, sizeof(double))) == NULL) exit(9); RECUR_USER_OPTIONS->user_cost_temperature[0] = 5.936648E+09; } /* If DELTA_PARAMETERS=TRUE, then these must be defined for all parameters that will be pseudo-differentiated. */ if (*recur_user_delta_flag == TRUE) { if ((RECUR_USER_OPTIONS->user_delta_parameter = (double *) calloc(*recur_parameter_dimension, sizeof(double))) == NULL) exit(9); for (index = 0; index < *recur_parameter_dimension; ++index) RECUR_USER_OPTIONS->user_delta_parameter[index] = 0.001; } /* If QUENCH_PARAMETERS=TRUE, then these must be defined for all parameters. */ if (*recur_user_quench_param_flag == TRUE) { if ((RECUR_USER_OPTIONS->user_quench_param_scale = (double *) calloc(*recur_parameter_dimension, sizeof(double))) == NULL) exit(9); for (index = 0; index < *recur_parameter_dimension; ++index) RECUR_USER_OPTIONS->user_quench_param_scale[index] = 1.0; } /* If QUENCH_COST=TRUE, then this must be defined. */ if (*recur_user_quench_cost_flag == TRUE) { if ((RECUR_USER_OPTIONS->user_quench_cost_scale = (double *) calloc(1, sizeof(double))) == NULL) exit(9); RECUR_USER_OPTIONS->user_quench_cost_scale[0] = 1.0; } /* If RATIO_TEMPERATURE_SCALES=TRUE, then these must be defined for all parameters. */ if (*recur_user_ratio_temp_flag == TRUE) { if ((RECUR_USER_OPTIONS->user_temperature_ratio = (double *) calloc(*recur_parameter_dimension, sizeof(double))) == NULL) exit(9); for (index = 0; index < *recur_parameter_dimension; ++index) RECUR_USER_OPTIONS->user_temperature_ratio[index] = 1.0; } } /*********************************************************************** * double recur_cost_function * This is the users cost function to optimize * (find the minimum). * cost_flag is set to true if the parameter set * does not violates any constraints * recur_parameter_lower_bound and recur_parameter_upper_bound * may be adaptively changed during the search. ***********************************************************************/ #if HAVE_ANSI double recur_cost_function(double *x, double *recur_parameter_lower_bound, double *recur_parameter_upper_bound, double *recur_cost_tangents, double *recur_cost_curvature, ALLOC_INT * recur_parameter_dimension, int *recur_parameter_int_real, int *recur_cost_flag, int *recur_exit_code, USER_DEFINES * RECUR_USER_OPTIONS) #else double recur_cost_function(x, recur_parameter_lower_bound, recur_parameter_upper_bound, recur_cost_tangents, recur_cost_curvature, recur_parameter_dimension, recur_parameter_int_real, recur_cost_flag, recur_exit_code, RECUR_USER_OPTIONS) double *x; double *recur_parameter_lower_bound; double *recur_parameter_upper_bound; double *recur_cost_tangents; double *recur_cost_curvature; ALLOC_INT *recur_parameter_dimension; int *recur_parameter_int_real; int *recur_cost_flag; int *recur_exit_code; USER_DEFINES *RECUR_USER_OPTIONS; #endif { double cost_value; static LONG_INT recur_funevals = 0; int *cost_curvature_0, *user_parameter_temp_flag, *user_cost_temp_flag, *user_delta_flag, *user_ratio_temp_flag; int *exit_code; double *parameter_lower_bound, *parameter_upper_bound; double *cost_parameters; double *cost_tangents, *cost_curvature; ALLOC_INT *parameter_dimension; int *parameter_int_real; int *cost_flag; int *user_quench_param_flag, *user_quench_cost_flag; USER_DEFINES *USER_OPTIONS; recur_funevals = recur_funevals + 1; if ((USER_OPTIONS = (USER_DEFINES *) calloc(1, sizeof(USER_DEFINES))) == NULL) exit(9); /* USER_OPTIONS->LIMIT_ACCEPTANCES = 10000; */ USER_OPTIONS->LIMIT_ACCEPTANCES = 1000; USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 1000; USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-6; USER_OPTIONS->COST_PRECISION = 1.0E-18; USER_OPTIONS->MAXIMUM_COST_REPEAT = 2; USER_OPTIONS->NUMBER_COST_SAMPLES = 2; /* USER_OPTIONS->TEMPERATURE_RATIO_SCALE = 1.0E-5; */ USER_OPTIONS->TEMPERATURE_RATIO_SCALE = x[0]; /* USER_OPTIONS->COST_PARAMETER_SCALE = 1.0; */ USER_OPTIONS->COST_PARAMETER_SCALE = x[1]; USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = 100.; USER_OPTIONS->USER_INITIAL_COST_TEMP = FALSE; USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = FALSE; USER_OPTIONS->USER_INITIAL_PARAMETERS = FALSE; USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = 1.0; USER_OPTIONS->RATIO_TEMPERATURE_SCALES = FALSE; USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = FALSE; USER_OPTIONS->TESTING_FREQUENCY_MODULUS = 100; USER_OPTIONS->ACTIVATE_REANNEAL = TRUE; USER_OPTIONS->REANNEAL_RESCALE = 10.0; USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = 50000; USER_OPTIONS->DELTA_X = 0.001; USER_OPTIONS->DELTA_PARAMETERS = FALSE; USER_OPTIONS->CURVATURE_0 = TRUE; USER_OPTIONS->QUENCH_PARAMETERS = FALSE; USER_OPTIONS->QUENCH_COST = FALSE; if ((parameter_dimension = (ALLOC_INT *) calloc(1, sizeof(ALLOC_INT))) == NULL) exit(9); if ((cost_curvature_0 = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((user_quench_param_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((user_quench_cost_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((user_parameter_temp_flag = (int *) calloc(1, sizeof(int)) ) == NULL) exit(9); if ((user_cost_temp_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((user_delta_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((user_ratio_temp_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((exit_code = (int *) calloc(1, sizeof(int))) == NULL) exit(9); if ((cost_flag = (int *) calloc(1, sizeof(int))) == NULL) exit(9); #if ASA_TEST /* if using SELF_OPTIMIZE=ASA_TEST=TRUE */ *parameter_dimension = 4; #endif if ((parameter_lower_bound = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); if ((parameter_upper_bound = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); if ((cost_parameters = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); if ((parameter_int_real = (int *) calloc(*parameter_dimension, sizeof(int)) ) == NULL) exit(9); if ((cost_tangents = (double *) calloc(*parameter_dimension, sizeof(double)) ) == NULL) exit(9); *cost_curvature_0 = USER_OPTIONS->CURVATURE_0; *user_parameter_temp_flag = USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS; *user_cost_temp_flag = USER_OPTIONS->USER_INITIAL_COST_TEMP; *user_delta_flag = USER_OPTIONS->DELTA_PARAMETERS; *user_ratio_temp_flag = USER_OPTIONS->RATIO_TEMPERATURE_SCALES; *user_quench_param_flag = USER_OPTIONS->QUENCH_PARAMETERS; *user_quench_cost_flag = USER_OPTIONS->QUENCH_COST; if (*cost_curvature_0 == FALSE) { if ((cost_curvature = (double *) calloc((*parameter_dimension) * (*parameter_dimension), sizeof(double))) == NULL) exit(9); } else { cost_curvature = (double *) NULL; } #if OPTIONAL_DATA /* Set memory to that required for use. */ if ((USER_OPTIONS->asa_data = (double *) calloc(2, sizeof(double))) == NULL) exit(9); /* Use asa_data[0] as flag, e.g., if used with SELF_OPTIMIZE. */ USER_OPTIONS->asa_data[0] = 1.0; #endif initialize_parameters(cost_parameters, parameter_lower_bound, parameter_upper_bound, cost_tangents, cost_curvature, parameter_dimension, parameter_int_real, cost_curvature_0, user_parameter_temp_flag, user_cost_temp_flag, user_delta_flag, user_ratio_temp_flag, user_quench_param_flag, user_quench_cost_flag, USER_OPTIONS); /* It might be a good idea to place a loop around this call, and to average over several values of funevals returned by trajectories of cost_value. */ funevals = 0; #if USER_ASA_OUT if ((USER_OPTIONS->asa_out_file = (char *) calloc(80, sizeof(char)) ) == NULL) exit(9); #if ASA_TEMPLATE strcpy(USER_OPTIONS->asa_out_file, "asa_rcur"); #endif #endif cost_value = asa(cost_function, randflt, cost_parameters, parameter_lower_bound, parameter_upper_bound, cost_tangents, cost_curvature, parameter_dimension, parameter_int_real, cost_flag, exit_code, USER_OPTIONS); if (cost_value > .001) { *recur_cost_flag = FALSE; } else { *recur_cost_flag = TRUE; } #if 0 /* set to 1 to activate FAST EXIT */ /* Make a quick exit */ if (recur_funevals >= 10) { *recur_cost_flag = FALSE; RECUR_USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 0; fprintf(ptr_out, "FAST EXIT set at recur_funevals = 10\n\n"); } #endif /* print every RECUR_PRINT_FREQUENCY evaluations */ if ((RECUR_PRINT_FREQUENCY > 0) && ((recur_funevals % RECUR_PRINT_FREQUENCY) == 0)) { USER_OPTIONS->TEMPERATURE_RATIO_SCALE = x[0]; fprintf(ptr_out, "USER_OPTIONS->TEMPERATURE_RATIO_SCALE = %g\n", USER_OPTIONS->TEMPERATURE_RATIO_SCALE); USER_OPTIONS->COST_PARAMETER_SCALE = x[1]; fprintf(ptr_out, "USER_OPTIONS->COST_PARAMETER_SCALE = %g\n", USER_OPTIONS->COST_PARAMETER_SCALE); } #if TIME_CALC print_time(""); #endif fprintf(ptr_out, "recur_funevals = %ld, *recur_cost_flag = %d\n", recur_funevals, *recur_cost_flag); /* cost function = number generated at best cost */ #if OPTIONAL_DATA #if ASA_TEMPLATE funevals = (LONG_INT) (USER_OPTIONS->asa_data[1]); fprintf(ptr_out, "\tbest_funevals = %ld, cost_value = %g\n\n", funevals, cost_value); /* cost function = total number generated during run */ #endif #else /* OPTIONAL_DATA */ fprintf(ptr_out, "\tfunevals = %ld, cost_value = %g\n\n", funevals, cost_value); #endif fflush(ptr_out); #if OPTIONAL_DATA free(USER_OPTIONS->asa_data); #endif #if USER_ASA_OUT free(USER_OPTIONS->asa_out_file); #endif free(USER_OPTIONS); free(parameter_dimension); free(user_quench_param_flag); free(user_quench_cost_flag); free(user_parameter_temp_flag); free(user_cost_temp_flag); free(user_delta_flag); free(user_ratio_temp_flag); free(exit_code); free(cost_flag); free(parameter_lower_bound); free(parameter_upper_bound); free(cost_parameters); free(parameter_int_real); free(cost_tangents); if (*cost_curvature_0 == FALSE) free(cost_curvature); free(cost_curvature_0); return ((double) funevals); } #endif /* SELF_OPTIMIZE */