HsASA-0.1: _darcs/pristine/asa.c
/***********************************************************************
* Adaptive Simulated Annealing (ASA)
* Lester Ingber <ingber@ingber.com>
* Copyright (c) 1993-2004 Lester Ingber. All Rights Reserved.
* The LICENSE file must be included with ASA code.
***********************************************************************/
#define ASA_ID \
"/* $Id: asa.c,v 25.15 2004/09/23 18:10:46 ingber Exp ingber $ */"
#include "asa.h"
static int asa_recursive_max = 0; /* record of max recursions */
/***********************************************************************
* asa
* This procedure implements the full ASA function optimization.
***********************************************************************/
#if HAVE_ANSI
double
asa (double (*user_cost_function)
(double *, double *, double *, double *, double *, ALLOC_INT *, int *,
int *, int *, USER_DEFINES *),
double (*user_random_generator) (LONG_INT *), LONG_INT * seed,
double *parameter_initial_final, double *parameter_minimum,
double *parameter_maximum, double *tangents, double *curvature,
ALLOC_INT * number_parameters, int *parameter_type,
int *valid_state_generated_flag, int *exit_status,
USER_DEFINES * OPTIONS)
#else
double
asa (user_cost_function,
user_random_generator,
seed,
parameter_initial_final,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type, valid_state_generated_flag, exit_status, OPTIONS)
double (*user_cost_function) ();
double (*user_random_generator) ();
LONG_INT *seed;
double *parameter_initial_final;
double *parameter_minimum;
double *parameter_maximum;
double *tangents;
double *curvature;
ALLOC_INT *number_parameters;
int *parameter_type;
int *valid_state_generated_flag;
int *exit_status;
USER_DEFINES *OPTIONS;
#endif /* HAVE_ANSI */
{
#if USER_INITIAL_COST_TEMP
#if USER_REANNEAL_COST
#else
int index_cost_constraint; /* index cost functions averaged */
#endif /* USER_REANNEAL_COST */
#else /* USER_INITIAL_COST_TEMP */
int index_cost_constraint; /* index cost functions averaged */
#endif /* USER_INITIAL_COST_TEMP */
int index_cost_repeat, /* test OPTIONS->Cost_Precision when =
OPTIONS->Maximum_Cost_Repeat */
tmp_var_int, tmp_var_int1, tmp_var_int2; /* temporary integers */
ALLOC_INT index_v, /* iteration index */
*start_sequence; /* initial OPTIONS->Sequential_Parameters
used if >= 0 */
double final_cost, /* best cost to return to user */
tmp_var_db, tmp_var_db1, tmp_var_db2; /* temporary doubles */
int *curvature_flag;
FILE *ptr_asa_out; /* file ptr to output file */
/* The 3 states that are kept track of during the annealing process */
STATE *current_generated_state, *last_saved_state, *best_generated_state;
#if ASA_SAVE
FILE *ptr_save, *ptr_comm;
int asa_read;
char asa_save_comm[100];
#if ASA_SAVE_OPT
char read_option[80];
char read_if[4], read_FALSE[6], read_comm1[3], read_ASA_SAVE[9],
read_comm2[3];
int read_int;
#if INT_LONG
LONG_INT read_long;
#endif
double read_double;
FILE *ptr_save_opt;
#endif
#endif /* ASA_SAVE */
#if ASA_PIPE_FILE
FILE *ptr_asa_pipe;
#endif
int immediate_flag; /* save Immediate_Exit */
int asa_exit_value;
double xnumber_parameters[1];
/* The array of tangents (absolute value of the numerical derivatives),
and the maximum |tangent| of the array */
double *maximum_tangent;
/* ratio of acceptances to generated points - determines when to
test/reanneal */
double *accepted_to_generated_ratio;
/* temperature parameters */
double temperature_scale, *temperature_scale_parameters;
/* relative scalings of cost and parameters to temperature_scale */
double *temperature_scale_cost;
double *current_user_parameter_temp;
double *initial_user_parameter_temp;
double *current_cost_temperature;
double *initial_cost_temperature;
double log_new_temperature_ratio; /* current *temp = initial *temp *
exp(log_new_temperature_ratio) */
ALLOC_INT *index_exit_v; /* information for asa_exit */
/* counts of generated states and acceptances */
LONG_INT *index_parameter_generations;
LONG_INT *number_generated, *best_number_generated_saved;
LONG_INT *recent_number_generated, *number_accepted;
LONG_INT *recent_number_acceptances, *index_cost_acceptances;
LONG_INT *number_acceptances_saved, *best_number_accepted_saved;
/* Flag indicates that the parameters generated were
invalid according to the cost function validity criteria. */
LONG_INT *number_invalid_generated_states;
LONG_INT repeated_invalid_states;
#if ASA_QUEUE
int queue_new; /* flag to add new entry */
int *save_queue_flag; /* save valid_state_generated_flag */
LONG_INT queue; /* index of queue */
LONG_INT queue_v; /* index of parameters in queue */
LONG_INT save_queue_test; /* test if all parameters are present */
LONG_INT save_queue; /* last filled position in queue */
LONG_INT save_queue_indx; /* current position in queue */
double *save_queue_cost, *save_queue_param; /* saved states */
ALLOC_INT queue_size_tmp;
#endif
#if MULTI_MIN
int multi_index;
int multi_test, multi_test_cmp, multi_test_dim;
int *multi_sort;
double *multi_cost;
double **multi_params;
#endif /* MULTI_MIN */
#if ASA_PARALLEL
LONG_INT *parallel_sort;
LONG_INT index_parallel, sort_index; /* count of parallel generated states */
LONG_INT parallel_generated; /* saved *recent_number_generated */
LONG_INT parallel_block_max; /* saved OPTIONS->Gener_Block_Max */
STATE *gener_block_state;
#endif
/* used to index repeated and recursive calls to asa */
/* This assumes that multiple calls (>= 1) _or_ recursive
calls are being made to asa */
static int asa_open = FALSE;
static int number_asa_open = 0;
static int recursive_asa_open = 0;
/* initializations */
if ((curvature_flag = (int *) calloc (1, sizeof (int))) == NULL) {
strcpy (exit_msg, "asa(): curvature_flag");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((maximum_tangent = (double *) calloc (1, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): maximum_tangent");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((accepted_to_generated_ratio =
(double *) calloc (1, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): accepted_to_generated_ratio");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((temperature_scale_cost =
(double *) calloc (1, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): temperature_scale_cost");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((current_cost_temperature =
(double *) calloc (1, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): current_cost_temperature");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((initial_cost_temperature =
(double *) calloc (1, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): initial_cost_temperature");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((index_exit_v = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): index_exit_v");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((start_sequence = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): start_sequence");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((number_generated =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): number_generated");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((best_number_generated_saved =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): best_number_generated_saved");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((recent_number_generated =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): recent_number_generated");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((number_accepted =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): number_accepted");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((recent_number_acceptances =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): recent_number_acceptances");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((index_cost_acceptances =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): index_cost_acceptances");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((number_acceptances_saved =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): number_acceptances_saved");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((best_number_accepted_saved =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): best_number_accepted_saved");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((number_invalid_generated_states =
(ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): number_invalid_generated_states");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((current_generated_state =
(STATE *) calloc (1, sizeof (STATE))) == NULL) {
strcpy (exit_msg, "asa(): current_generated_state");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((last_saved_state = (STATE *) calloc (1, sizeof (STATE))) == NULL) {
strcpy (exit_msg, "asa(): last_saved_state");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((best_generated_state = (STATE *) calloc (1, sizeof (STATE))) == NULL) {
strcpy (exit_msg, "asa(): best_generated_state");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
#if ASA_PARALLEL
if ((gener_block_state =
(STATE *) calloc (OPTIONS->Gener_Block_Max, sizeof (STATE))) == NULL) {
strcpy (exit_msg, "asa(): gener_block_state");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
gener_block_state_qsort = gener_block_state;
if ((parallel_sort =
(LONG_INT *) calloc (OPTIONS->Gener_Block_Max,
sizeof (LONG_INT))) == NULL) {
strcpy (exit_msg, "asa(): parallel_sort");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
#endif
/* set default */
ptr_asa_out = (FILE *) NULL;
OPTIONS->Immediate_Exit = FALSE;
if (asa_open == FALSE) {
asa_open = TRUE;
++number_asa_open;
#if ASA_PRINT
if (number_asa_open == 1) {
/* open the output file */
#if USER_ASA_OUT
if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
#if ASA_SAVE
ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");
#else
ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "w");
#endif
}
#else /* USER_ASA_OUT */
if (!strcmp (ASA_OUT, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
#if ASA_SAVE
ptr_asa_out = fopen (ASA_OUT, "a");
#else
ptr_asa_out = fopen (ASA_OUT, "w");
#endif
}
#endif /* USER_ASA_OUT */
} else {
#if USER_ASA_OUT
if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");
}
#else
if (!strcmp (ASA_OUT, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (ASA_OUT, "a");
}
#endif
fprintf (ptr_asa_out, "\n\n\t\t number_asa_open = %d\n",
number_asa_open);
}
#endif /* ASA_PRINT */
} else {
++recursive_asa_open;
#if ASA_PRINT
if (recursive_asa_open == 1) {
/* open the output file */
#if ASA_SAVE
#if USER_ASA_OUT
if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");
}
#else
if (!strcmp (ASA_OUT, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (ASA_OUT, "a");
}
#endif
#else /* ASA_SAVE */
#if USER_ASA_OUT
if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "w");
}
#else
if (!strcmp (ASA_OUT, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (ASA_OUT, "w");
}
#endif
#endif /* ASA_SAVE */
} else {
#if USER_ASA_OUT
if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");
}
#else
if (!strcmp (ASA_OUT, "STDOUT")) {
#if INCL_STDOUT
ptr_asa_out = stdout;
#endif /* INCL_STDOUT */
} else {
ptr_asa_out = fopen (ASA_OUT, "a");
}
#endif
fprintf (ptr_asa_out, "\n\n\t\t recursive_asa_open = %d\n",
recursive_asa_open);
}
#endif /* ASA_PRINT */
}
#if ASA_PIPE_FILE
ptr_asa_pipe = fopen ("asa_pipe", "a");
fprintf (ptr_asa_pipe, "%s", "%generate");
fprintf (ptr_asa_pipe, "\t%s", "accept");
fprintf (ptr_asa_pipe, "\t%s", "best_cost");
VFOR (index_v)
#if INT_ALLOC
fprintf (ptr_asa_pipe, "\t%s-%d", "param", index_v);
#else
#if INT_LONG
fprintf (ptr_asa_pipe, "\t%s-%ld", "param", index_v);
#else
fprintf (ptr_asa_pipe, "\t%s-%d", "param", index_v);
#endif
#endif
fprintf (ptr_asa_pipe, "\t%s", "cost_temp");
VFOR (index_v)
#if INT_ALLOC
fprintf (ptr_asa_pipe, "\t%s-%d", "param_temp", index_v);
#else
#if INT_LONG
fprintf (ptr_asa_pipe, "\t%s-%ld", "param_temp", index_v);
#else
fprintf (ptr_asa_pipe, "\t%s-%d", "param_temp", index_v);
#endif
#endif
fprintf (ptr_asa_pipe, "\t%s", "last_cost");
fprintf (ptr_asa_pipe, "\n");
fflush (ptr_asa_pipe);
#endif /* ASA_PIPE_FILE */
#if ASA_PRINT
/* print header information as defined by user */
print_asa_options (ptr_asa_out, OPTIONS);
fflush (ptr_asa_out);
#endif /* ASA_PRINT */
/* set indices and counts to 0 */
*best_number_generated_saved =
*number_generated =
*recent_number_generated = *recent_number_acceptances = 0;
*index_cost_acceptances =
*best_number_accepted_saved =
*number_accepted = *number_acceptances_saved = 0;
index_cost_repeat = 0;
OPTIONS->N_Accepted = *number_accepted;
OPTIONS->N_Generated = *number_generated;
#if ASA_SAMPLE
OPTIONS->N_Generated = 0;
OPTIONS->Average_Weights = 1.0;
#endif
/* do not calculate curvatures initially */
*curvature_flag = FALSE;
/* allocate storage for all parameters */
if ((current_generated_state->parameter =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): current_generated_state->parameter");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((last_saved_state->parameter =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): last_saved_state->parameter");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((best_generated_state->parameter =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): best_generated_state->parameter");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
#if ASA_PARALLEL
parallel_block_max = OPTIONS->Gener_Block_Max;
parallel_generated = OPTIONS->Gener_Block;
for (index_parallel = 0; index_parallel < parallel_block_max;
++index_parallel) {
if ((gener_block_state[index_parallel].parameter =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): gener_block_state[index_parallel].parameter");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
}
#endif
OPTIONS->Best_Cost = &(best_generated_state->cost);
OPTIONS->Best_Parameters = best_generated_state->parameter;
OPTIONS->Last_Cost = &(last_saved_state->cost);
OPTIONS->Last_Parameters = last_saved_state->parameter;
if ((initial_user_parameter_temp =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): initial_user_parameter_temp");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((index_parameter_generations =
(ALLOC_INT *) calloc (*number_parameters,
sizeof (ALLOC_INT))) == NULL) {
strcpy (exit_msg, "asa(): index_parameter_generations");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
/* set all temperatures */
if ((current_user_parameter_temp =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): current_user_parameter_temp");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
#if USER_INITIAL_PARAMETERS_TEMPS
VFOR (index_v)
current_user_parameter_temp[index_v] =
initial_user_parameter_temp[index_v] =
OPTIONS->User_Parameter_Temperature[index_v];
#else
VFOR (index_v)
current_user_parameter_temp[index_v] =
initial_user_parameter_temp[index_v] =
OPTIONS->Initial_Parameter_Temperature;
#endif
if ((temperature_scale_parameters =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): temperature_scale_parameters");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
#if ASA_QUEUE
if (OPTIONS->Queue_Size > 0) {
queue_size_tmp = OPTIONS->Queue_Size;
} else {
queue_size_tmp = 1;
}
if ((save_queue_flag =
(int *) calloc (queue_size_tmp, sizeof (int))) == NULL) {
strcpy (exit_msg, "asa(): save_queue_flag");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((save_queue_cost =
(double *) calloc (queue_size_tmp, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): save_queue_cost");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((save_queue_param =
(double *) calloc ((*number_parameters) * queue_size_tmp,
sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): save_queue_param");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
#endif /* ASA_QUEUE */
#if MULTI_MIN
if ((multi_cost =
(double *) calloc (OPTIONS->Multi_Number + 1,
sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): *multi_cost");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
multi_cost_qsort = multi_cost;
if ((multi_sort =
(int *) calloc (OPTIONS->Multi_Number + 1, sizeof (int))) == NULL) {
strcpy (exit_msg, "asa(): *multi_sort");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
if ((multi_params =
(double **) calloc (OPTIONS->Multi_Number + 1,
sizeof (double *))) == NULL) {
strcpy (exit_msg, "asa(): *multi_params");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
for (multi_index = 0; multi_index <= OPTIONS->Multi_Number; ++multi_index) {
if ((multi_params[multi_index] =
(double *) calloc (*number_parameters, sizeof (double))) == NULL) {
strcpy (exit_msg, "asa(): multi_params[multi_index]");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
}
#endif /* MULTI_MIN */
#if USER_INITIAL_COST_TEMP
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =
#endif
*initial_cost_temperature = *current_cost_temperature =
OPTIONS->User_Cost_Temperature[0];
#endif
/* set parameters to the initial parameter values */
VFOR (index_v)
last_saved_state->parameter[index_v] =
current_generated_state->parameter[index_v] =
parameter_initial_final[index_v];
#if USER_ACCEPTANCE_TEST
OPTIONS->Random_Seed = seed;
OPTIONS->Random_Seed[0] = *seed;
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
#if ASA_PRINT
#if INT_LONG
fprintf (ptr_asa_out, "Initial Random Seed = %ld\n\n", *seed);
#else
fprintf (ptr_asa_out, "Initial Random Seed = %d\n\n", *seed);
#endif
#endif /* ASA_PRINT */
/* save initial user value of OPTIONS->Sequential_Parameters */
*start_sequence = OPTIONS->Sequential_Parameters;
#if ASA_PRINT
fprintf (ptr_asa_out,
#if INT_ALLOC
"*number_parameters = %d\n\n", *number_parameters);
#else
#if INT_LONG
"*number_parameters = %ld\n\n", *number_parameters);
#else
"*number_parameters = %d\n\n", *number_parameters);
#endif
#endif
/* print the min, max, current values, and types of parameters */
fprintf (ptr_asa_out, "index_v parameter_minimum parameter_maximum\
parameter_value parameter_type \n");
#if ASA_PRINT_INTERMED
VFOR (index_v) fprintf (ptr_asa_out,
#if INT_ALLOC
" %-8d %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",
#else
#if INT_LONG
" %-8ld %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",
#else
" %-8d %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION, parameter_minimum[index_v],
G_FIELD, G_PRECISION, parameter_maximum[index_v],
G_FIELD, G_PRECISION,
current_generated_state->parameter[index_v],
parameter_type[index_v]);
fprintf (ptr_asa_out, "\n\n");
#endif /* ASA_PRINT_INTERMED */
/* Print out user-defined OPTIONS */
#if DELTA_PARAMETERS
VFOR (index_v) fprintf (ptr_asa_out,
#if INT_ALLOC
"OPTIONS->User_Delta_Parameter[%d] = %*.*g\n",
#else
#if INT_LONG
"OPTIONS->User_Delta_Parameter[%ld] = %*.*g\n",
#else
"OPTIONS->User_Delta_Parameter[%d] = %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION,
OPTIONS->User_Delta_Parameter[index_v]);
fprintf (ptr_asa_out, "\n");
#endif /* DELTA_PARAMETERS */
#if QUENCH_PARAMETERS
VFOR (index_v) fprintf (ptr_asa_out,
#if INT_ALLOC
"OPTIONS->User_Quench_Param_Scale[%d] = %*.*g\n",
#else
#if INT_LONG
"OPTIONS->User_Quench_Param_Scale[%ld] = %*.*g\n",
#else
"OPTIONS->User_Quench_Param_Scale[%d] = %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION,
OPTIONS->User_Quench_Param_Scale[index_v]);
#endif /* QUENCH_PARAMETERS */
#if QUENCH_COST
fprintf (ptr_asa_out,
"\nOPTIONS->User_Quench_Cost_Scale = %*.*g\n\n",
G_FIELD, G_PRECISION, OPTIONS->User_Quench_Cost_Scale[0]);
#endif /* QUENCH_COST */
#if USER_INITIAL_PARAMETERS_TEMPS
VFOR (index_v) fprintf (ptr_asa_out,
#if INT_ALLOC
"OPTIONS->User_Parameter_Temperature[%d] = %*.*g\n",
#else
#if INT_LONG
"OPTIONS->User_Parameter_Temperature[%ld] = %*.*g\n",
#else
"OPTIONS->User_Parameter_Temperature[%d] = %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION,
initial_user_parameter_temp[index_v]);
#endif /* USER_INITIAL_PARAMETERS_TEMPS */
#if RATIO_TEMPERATURE_SCALES
VFOR (index_v) fprintf (ptr_asa_out,
#if INT_ALLOC
"OPTIONS->User_Temperature_Ratio[%d] = %*.*g\n",
#else
#if INT_LONG
"OPTIONS->User_Temperature_Ratio[%ld] = %*.*g\n",
#else
"OPTIONS->User_Temperature_Ratio[%d] = %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION,
OPTIONS->User_Temperature_Ratio[index_v]);
#endif /* RATIO_TEMPERATURE_SCALES */
#if USER_INITIAL_COST_TEMP
fprintf (ptr_asa_out,
"OPTIONS->User_Cost_Temperature[0] = %*.*g\n",
G_FIELD, G_PRECISION, *initial_cost_temperature);
#endif /* USER_INITIAL_COST_TEMP */
fflush (ptr_asa_out);
#endif /* ASA_PRINT */
#if MULTI_MIN
#if ASA_PRINT
fprintf (ptr_asa_out, "\n");
fprintf (ptr_asa_out, "Multi_Number = %d\n", OPTIONS->Multi_Number);
fprintf (ptr_asa_out, "Multi_Specify = %d\n", OPTIONS->Multi_Specify);
#if ASA_RESOLUTION
#else
VFOR (index_v) {
fprintf (ptr_asa_out,
#if INT_ALLOC
"Multi_Grid[%d] = %*.*g\n",
#else
#if INT_LONG
"Multi_Grid[%ld] = %*.*g\n",
#else
"Multi_Grid[%d] = %*.*g\n",
#endif
#endif
index_v, G_FIELD, G_PRECISION, OPTIONS->Multi_Grid[index_v]);
}
#endif /* ASA_RESOLUTION */
fprintf (ptr_asa_out, "\n");
fflush (ptr_asa_out);
#endif /* ASA_PRINT */
#endif /* MULTI_MIN */
#if ASA_PARALLEL
#if ASA_PRINT
fprintf (ptr_asa_out,
#if INT_LONG
"Initial ASA_PARALLEL OPTIONS->\n\t Gener_Block = %ld\n\
\t Gener_Block_Max = %ld\n \t Gener_Mov_Avr= %d\n\n",
#else
"ASA_PARALLEL OPTIONS->\n\t Gener_Block = %d\n\
\t Gener_Block_Max = %d\n \t Gener_Mov_Avr= %d\n\n",
#endif
OPTIONS->Gener_Block, OPTIONS->Gener_Block_Max,
OPTIONS->Gener_Mov_Avr);
#endif
#endif /* ASA_PARALLEL */
#if ASA_SAMPLE
#if ASA_PRINT
fprintf (ptr_asa_out, "OPTIONS->Limit_Weights = %*.*g\n\n",
G_FIELD, G_PRECISION, OPTIONS->Limit_Weights);
#endif
#endif
if (OPTIONS->Asa_Recursive_Level > asa_recursive_max)
asa_recursive_max = OPTIONS->Asa_Recursive_Level;
#if ASA_SAVE
if (OPTIONS->Asa_Recursive_Level > 0)
sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);
else
sprintf (asa_save_comm, "asa_save");
if ((ptr_save = fopen (asa_save_comm, "r")) == NULL) {
asa_read = FALSE;
} else {
#if ASA_PRINT
fprintf (ptr_asa_out, "\n\n\trestart after ASA_SAVE\n\n");
#endif
fclose (ptr_save);
asa_read = TRUE;
/* give some value to avoid any problems with other OPTIONS */
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =
#endif
current_generated_state->cost
= *initial_cost_temperature = *current_cost_temperature = 3.1416;
}
#endif
tmp_var_int = cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters);
/* compute temperature scales */
tmp_var_db1 = -F_LOG ((OPTIONS->Temperature_Ratio_Scale));
tmp_var_db2 = F_LOG (OPTIONS->Temperature_Anneal_Scale);
temperature_scale =
tmp_var_db1 * F_EXP (-tmp_var_db2 / *xnumber_parameters);
/* set here in case not used */
tmp_var_db = ZERO;
#if QUENCH_PARAMETERS
#if RATIO_TEMPERATURE_SCALES
VFOR (index_v) temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP
#if QUENCH_PARAMETERS_SCALE
(-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])
#else
(-(tmp_var_db2)
#endif
/ *xnumber_parameters)
* OPTIONS->User_Temperature_Ratio[index_v];
#else
VFOR (index_v) temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP
#if QUENCH_PARAMETERS_SCALE
(-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])
#else
(-(tmp_var_db2)
#endif
/ *xnumber_parameters);
#endif /* RATIO_TEMPERATURE_SCALES */
#else /* QUENCH_PARAMETERS */
#if RATIO_TEMPERATURE_SCALES
VFOR (index_v)
temperature_scale_parameters[index_v] =
tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters)
* OPTIONS->User_Temperature_Ratio[index_v];
#else
VFOR (index_v)
temperature_scale_parameters[index_v] =
tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters);
#endif /* RATIO_TEMPERATURE_SCALES */
#endif /* QUENCH_PARAMETERS */
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Scale =
#endif
*temperature_scale_cost =
#if QUENCH_COST
#if QUENCH_COST_SCALE
tmp_var_db1 * F_EXP (-(tmp_var_db2 * OPTIONS->User_Quench_Cost_Scale[0])
#else
tmp_var_db1 * F_EXP (-(tmp_var_db2)
#endif
/ *xnumber_parameters) *
OPTIONS->Cost_Parameter_Scale_Ratio;
#else /* QUENCH_COST */
tmp_var_db1 * F_EXP (-(tmp_var_db2)
/ *xnumber_parameters) *
OPTIONS->Cost_Parameter_Scale_Ratio;
#endif /* QUENCH_COST */
/* set the initial index of parameter generations to 1 */
VFOR (index_v) index_parameter_generations[index_v] = 1;
/* test user-defined options before calling cost function */
tmp_var_int = asa_test_asa_options (seed,
parameter_initial_final,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, ptr_asa_out, OPTIONS);
if (tmp_var_int > 0) {
#if ASA_PRINT
fprintf (ptr_asa_out, "total number invalid OPTIONS = %d\n", tmp_var_int);
fflush (ptr_asa_out);
#endif
*exit_status = INVALID_USER_INPUT;
goto EXIT_ASA;
}
#if USER_INITIAL_COST_TEMP
#else
#if ASA_SAVE
if (asa_read == TRUE)
OPTIONS->Number_Cost_Samples = 1;
#endif
/* calculate the average cost over samplings of the cost function */
if (OPTIONS->Number_Cost_Samples < -1) {
tmp_var_db1 = ZERO;
tmp_var_db2 = ZERO;
tmp_var_int = -OPTIONS->Number_Cost_Samples;
} else {
tmp_var_db1 = ZERO;
tmp_var_int = OPTIONS->Number_Cost_Samples;
}
OPTIONS->Locate_Cost = 0; /* initial cost temp */
for (index_cost_constraint = 0;
index_cost_constraint < tmp_var_int; ++index_cost_constraint) {
*number_invalid_generated_states = 0;
repeated_invalid_states = 0;
OPTIONS->Sequential_Parameters = *start_sequence - 1;
do {
++(*number_invalid_generated_states);
generate_new_state (user_random_generator,
seed,
parameter_minimum,
parameter_maximum, current_user_parameter_temp,
#if USER_GENERATING_FUNCTION
initial_user_parameter_temp,
temperature_scale_parameters,
#endif
number_parameters,
parameter_type,
current_generated_state, last_saved_state, OPTIONS);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
tmp_var_db =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag, exit_status, OPTIONS);
if (cost_function_test
(tmp_var_db, current_generated_state->parameter,
parameter_minimum, parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION;
goto EXIT_ASA;
}
++repeated_invalid_states;
if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {
*exit_status = TOO_MANY_INVALID_STATES;
goto EXIT_ASA;
}
}
while (*valid_state_generated_flag == FALSE);
--(*number_invalid_generated_states);
if (OPTIONS->Number_Cost_Samples < -1) {
tmp_var_db1 += tmp_var_db;
tmp_var_db2 += (tmp_var_db * tmp_var_db);
} else {
tmp_var_db1 += fabs (tmp_var_db);
}
}
if (OPTIONS->Number_Cost_Samples < -1) {
tmp_var_db1 /= (double) tmp_var_int;
tmp_var_db2 /= (double) tmp_var_int;
tmp_var_db = sqrt (fabs ((tmp_var_db2 - tmp_var_db1 * tmp_var_db1)
* ((double) tmp_var_int
/ ((double) tmp_var_int - ONE))))
+ (double) EPS_DOUBLE;
} else {
tmp_var_db = tmp_var_db1 / tmp_var_int;
}
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =
#endif
*initial_cost_temperature = *current_cost_temperature = tmp_var_db;
#endif /* USER_INITIAL_COST_TEMP */
/* set all parameters to the initial parameter values */
VFOR (index_v)
best_generated_state->parameter[index_v] =
last_saved_state->parameter[index_v] =
current_generated_state->parameter[index_v] =
parameter_initial_final[index_v];
OPTIONS->Locate_Cost = 1; /* initial cost value */
/* if using user's initial parameters */
if (OPTIONS->User_Initial_Parameters == TRUE) {
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
#if ASA_SAVE
if (asa_read == FALSE)
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag, exit_status, OPTIONS);
if (cost_function_test
(current_generated_state->cost, current_generated_state->parameter,
parameter_minimum, parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION;
goto EXIT_ASA;
}
#if ASA_PRINT
if (*valid_state_generated_flag == FALSE)
fprintf (ptr_asa_out, "user's initial parameters generated \
FALSE *valid_state_generated_flag\n");
#endif
} else {
/* let asa generate valid initial parameters */
repeated_invalid_states = 0;
OPTIONS->Sequential_Parameters = *start_sequence - 1;
do {
++(*number_invalid_generated_states);
generate_new_state (user_random_generator,
seed,
parameter_minimum,
parameter_maximum, current_user_parameter_temp,
#if USER_GENERATING_FUNCTION
initial_user_parameter_temp,
temperature_scale_parameters,
#endif
number_parameters,
parameter_type,
current_generated_state, last_saved_state, OPTIONS);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag, exit_status, OPTIONS);
if (cost_function_test
(current_generated_state->cost,
current_generated_state->parameter, parameter_minimum,
parameter_maximum, number_parameters, xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION;
goto EXIT_ASA;
}
++repeated_invalid_states;
if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {
*exit_status = TOO_MANY_INVALID_STATES;
goto EXIT_ASA;
}
}
while (*valid_state_generated_flag == FALSE);
--(*number_invalid_generated_states);
} /* OPTIONS->User_Initial_Parameters */
/* set all states to the last one generated */
VFOR (index_v) {
#if DROPPED_PARAMETERS
/* ignore parameters that have too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
#endif
best_generated_state->parameter[index_v] =
last_saved_state->parameter[index_v] =
current_generated_state->parameter[index_v];
}
/* set all costs to the last one generated */
best_generated_state->cost = last_saved_state->cost =
current_generated_state->cost;
*accepted_to_generated_ratio = ONE;
/* do not calculate curvatures initially */
*curvature_flag = FALSE;
#if ASA_PRINT
fprintf (ptr_asa_out,
"temperature_scale = %*.*g\n",
G_FIELD, G_PRECISION, temperature_scale);
#if RATIO_TEMPERATURE_SCALES
#if ASA_PRINT_INTERMED
VFOR (index_v) {
fprintf (ptr_asa_out,
#if INT_ALLOC
"temperature_scale_parameters[%d] = %*.*g\n",
#else
#if INT_LONG
"temperature_scale_parameters[%ld] = %*.*g\n",
#else
"temperature_scale_parameters[%d] = %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION, temperature_scale_parameters[index_v]);
}
#endif
#else
fprintf (ptr_asa_out,
"temperature_scale_parameters[0] = %*.*g\n",
G_FIELD, G_PRECISION, temperature_scale_parameters[0]);
#endif /* RATIO_TEMPERATURE_SCALES */
fprintf (ptr_asa_out,
"*temperature_scale_cost = %*.*g\n",
G_FIELD, G_PRECISION, *temperature_scale_cost);
fprintf (ptr_asa_out, "\n\n");
#if ASA_PRINT_INTERMED
print_state (parameter_minimum,
parameter_maximum,
tangents,
curvature,
current_cost_temperature,
current_user_parameter_temp,
accepted_to_generated_ratio,
number_parameters,
curvature_flag,
number_accepted,
index_cost_acceptances,
number_generated,
number_invalid_generated_states,
last_saved_state, best_generated_state, ptr_asa_out, OPTIONS);
#endif
fprintf (ptr_asa_out, "\n");
fflush (ptr_asa_out);
#endif
#if ASA_SAMPLE
#if ASA_PRINT
fprintf (ptr_asa_out,
":SAMPLE: n_accept cost cost_temp bias_accept \
aver_weight\n");
fprintf (ptr_asa_out,
":SAMPLE: index param[] temp[] bias_gener[] \
range[]\n");
#endif
#endif
/* reset the current cost and the number of generations performed */
*number_invalid_generated_states = 0;
*best_number_generated_saved =
*number_generated = *recent_number_generated = 0;
OPTIONS->N_Generated = *number_generated;
VFOR (index_v) {
/* ignore parameters that have too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
index_parameter_generations[index_v] = 1;
}
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = FALSE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
#if ASA_QUEUE
#if ASA_PRINT
#if INT_ALLOC
fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %d\n", OPTIONS->Queue_Size);
#else
#if INT_LONG
fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %ld\n", OPTIONS->Queue_Size);
#else
fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %d\n", OPTIONS->Queue_Size);
#endif
#endif
VFOR (index_v) {
fprintf (ptr_asa_out,
#if INT_ALLOC
"Queue_Resolution[%d] = %*.*g\n",
#else
#if INT_LONG
"Queue_Resolution[%ld] = %*.*g\n",
#else
"Queue_Resolution[%d] = %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION, OPTIONS->Queue_Resolution[index_v]);
}
#endif /* ASA_PRINT */
/* fill arrays to check allocated memory */
for (queue = 0; queue < queue_size_tmp; ++queue) {
VFOR (index_v) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
continue;
}
queue_v = index_v + queue * (LONG_INT) (*number_parameters);
save_queue_param[queue_v] = current_generated_state->parameter[index_v];
}
save_queue_cost[queue] = current_generated_state->cost;
save_queue_flag[queue] = *valid_state_generated_flag;
}
save_queue = save_queue_indx = 0;
#endif /* ASA_QUEUE */
#if ASA_RESOLUTION
#if ASA_PRINT
VFOR (index_v) {
fprintf (ptr_asa_out,
#if INT_ALLOC
"Coarse_Resolution[%d] = %*.*g\n",
#else
#if INT_LONG
"Coarse_Resolution[%ld] = %*.*g\n",
#else
"Coarse_Resolution[%d] = %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION, OPTIONS->Coarse_Resolution[index_v]);
}
#endif /* ASA_PRINT */
#endif /* ASA_RESOLUTION */
#if MULTI_MIN
multi_sort[OPTIONS->Multi_Number] = OPTIONS->Multi_Number;
multi_cost[OPTIONS->Multi_Number] = current_generated_state->cost;
VFOR (index_v) {
multi_params[OPTIONS->Multi_Number][index_v] =
current_generated_state->parameter[index_v];
}
for (multi_index = 0; multi_index < OPTIONS->Multi_Number; ++multi_index) {
multi_sort[multi_index] = multi_index;
multi_cost[multi_index] = OPTIONS->Multi_Cost[multi_index] =
current_generated_state->cost;
VFOR (index_v) {
multi_params[multi_index][index_v] =
OPTIONS->Multi_Params[multi_index][index_v] =
current_generated_state->parameter[index_v];
}
}
#endif /* MULTI_MIN */
OPTIONS->Sequential_Parameters = *start_sequence - 1;
/* MAIN ANNEALING LOOP */
while (((*number_accepted <= OPTIONS->Limit_Acceptances)
|| (OPTIONS->Limit_Acceptances == 0))
&& ((*number_generated <= OPTIONS->Limit_Generated)
|| (OPTIONS->Limit_Generated == 0))) {
tmp_var_db1 = -F_LOG ((OPTIONS->Temperature_Ratio_Scale));
/* compute temperature scales */
tmp_var_db2 = F_LOG (OPTIONS->Temperature_Anneal_Scale);
temperature_scale = tmp_var_db1 *
F_EXP (-tmp_var_db2 / *xnumber_parameters);
#if QUENCH_PARAMETERS
#if RATIO_TEMPERATURE_SCALES
VFOR (index_v)
temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP
#if QUENCH_PARAMETERS_SCALE
(-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])
#else
(-(tmp_var_db2)
#endif
/ *xnumber_parameters)
* OPTIONS->User_Temperature_Ratio[index_v];
#else
VFOR (index_v)
temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP
#if QUENCH_PARAMETERS_SCALE
(-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])
#else
(-(tmp_var_db2)
#endif
/ *xnumber_parameters);
#endif /* RATIO_TEMPERATURE_SCALES */
#else /* QUENCH_PARAMETERS */
#if RATIO_TEMPERATURE_SCALES
VFOR (index_v)
temperature_scale_parameters[index_v] =
tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters)
* OPTIONS->User_Temperature_Ratio[index_v];
#else
VFOR (index_v)
temperature_scale_parameters[index_v] =
tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters);
#endif /* RATIO_TEMPERATURE_SCALES */
#endif /* QUENCH_PARAMETERS */
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Scale =
#endif
*temperature_scale_cost =
#if QUENCH_COST
#if QUENCH_COST_SCALE
tmp_var_db1 * F_EXP (-(tmp_var_db2 * OPTIONS->User_Quench_Cost_Scale[0])
#else
tmp_var_db1 * F_EXP (-(tmp_var_db2)
#endif
/ *xnumber_parameters) *
OPTIONS->Cost_Parameter_Scale_Ratio;
#else /* QUENCH_COST */
tmp_var_db1 * F_EXP (-(tmp_var_db2)
/ *xnumber_parameters) *
OPTIONS->Cost_Parameter_Scale_Ratio;
#endif /* QUENCH_COST */
/* CALCULATE NEW TEMPERATURES */
/* calculate new parameter temperatures */
VFOR (index_v) {
/* skip parameters with too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
log_new_temperature_ratio =
-temperature_scale_parameters[index_v] *
F_POW ((double) index_parameter_generations[index_v],
#if QUENCH_PARAMETERS
OPTIONS->User_Quench_Param_Scale[index_v]
#else /* QUENCH_PARAMETERS */
ONE
#endif /* QUENCH_PARAMETERS */
/ *xnumber_parameters);
/* check (and correct) for too large an exponent */
log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);
current_user_parameter_temp[index_v] =
initial_user_parameter_temp[index_v]
* F_EXP (log_new_temperature_ratio);
#if NO_PARAM_TEMP_TEST
if (current_user_parameter_temp[index_v] < (double) EPS_DOUBLE)
current_user_parameter_temp[index_v] = (double) EPS_DOUBLE;
#else
/* check for too small a parameter temperature */
if (current_user_parameter_temp[index_v] < (double) EPS_DOUBLE) {
*exit_status = P_TEMP_TOO_SMALL;
*index_exit_v = index_v;
goto EXIT_ASA;
}
#endif
}
/* calculate new cost temperature */
log_new_temperature_ratio =
-*temperature_scale_cost * F_POW ((double) *index_cost_acceptances,
#if QUENCH_COST
OPTIONS->User_Quench_Cost_Scale[0]
#else
ONE
#endif
/ *xnumber_parameters);
log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =
#endif
*current_cost_temperature = *initial_cost_temperature
* F_EXP (log_new_temperature_ratio);
#if NO_COST_TEMP_TEST
if (*current_cost_temperature < (double) EPS_DOUBLE)
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Curr =
#endif
*current_cost_temperature = (double) EPS_DOUBLE;
#else
/* check for too small a cost temperature */
if (*current_cost_temperature < (double) EPS_DOUBLE) {
*exit_status = C_TEMP_TOO_SMALL;
goto EXIT_ASA;
}
#endif
#if ASA_SAVE
if (asa_read == TRUE && OPTIONS->Asa_Recursive_Level == asa_recursive_max) {
if (OPTIONS->Asa_Recursive_Level > 0)
sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);
else
sprintf (asa_save_comm, "asa_save");
ptr_save = fopen (asa_save_comm, "r");
fread (number_parameters, sizeof (ALLOC_INT), 1, ptr_save);
fread (xnumber_parameters, sizeof (double), 1, ptr_save);
fread (parameter_minimum, sizeof (double),
*number_parameters, ptr_save);
fread (parameter_maximum, sizeof (double),
*number_parameters, ptr_save);
fread (tangents, sizeof (double), *number_parameters, ptr_save);
fread (current_user_parameter_temp, sizeof (double),
*number_parameters, ptr_save);
fread (initial_user_parameter_temp, sizeof (double),
*number_parameters, ptr_save);
fread (temperature_scale_parameters, sizeof (double),
*number_parameters, ptr_save);
fread (parameter_type, sizeof (int), *number_parameters, ptr_save);
fread (&index_cost_repeat, sizeof (int), 1, ptr_save);
fread (&asa_open, sizeof (int), 1, ptr_save);
fread (&number_asa_open, sizeof (int), 1, ptr_save);
fread (&recursive_asa_open, sizeof (int), 1, ptr_save);
fread (current_cost_temperature, sizeof (double), 1, ptr_save);
fread (initial_cost_temperature, sizeof (double), 1, ptr_save);
fread (temperature_scale_cost, sizeof (double), 1, ptr_save);
fread (accepted_to_generated_ratio, sizeof (double), 1, ptr_save);
fread (curvature_flag, sizeof (int), 1, ptr_save);
fread (seed, sizeof (LONG_INT), 1, ptr_save);
fread (number_generated, sizeof (LONG_INT), 1, ptr_save);
fread (number_accepted, sizeof (LONG_INT), 1, ptr_save);
fread (number_acceptances_saved, sizeof (LONG_INT), 1, ptr_save);
fread (recent_number_acceptances, sizeof (LONG_INT), 1, ptr_save);
fread (recent_number_generated, sizeof (LONG_INT), 1, ptr_save);
fread (number_invalid_generated_states, sizeof (LONG_INT), 1, ptr_save);
fread (index_cost_acceptances, sizeof (LONG_INT), 1, ptr_save);
fread (best_number_generated_saved, sizeof (LONG_INT), 1, ptr_save);
fread (best_number_accepted_saved, sizeof (LONG_INT), 1, ptr_save);
fread (index_parameter_generations, sizeof (LONG_INT),
*number_parameters, ptr_save);
fread (current_generated_state->parameter,
sizeof (double), *number_parameters, ptr_save);
fread (last_saved_state->parameter,
sizeof (double), *number_parameters, ptr_save);
fread (best_generated_state->parameter,
sizeof (double), *number_parameters, ptr_save);
fread (&(current_generated_state->cost), sizeof (double), 1, ptr_save);
fread (&(last_saved_state->cost), sizeof (double), 1, ptr_save);
fread (&(best_generated_state->cost), sizeof (double), 1, ptr_save);
fread (&(OPTIONS->Limit_Acceptances), sizeof (LONG_INT), 1, ptr_save);
fread (&(OPTIONS->Limit_Generated), sizeof (LONG_INT), 1, ptr_save);
fread (&(OPTIONS->Limit_Invalid_Generated_States), sizeof (int),
1, ptr_save);
fread (&(OPTIONS->Accepted_To_Generated_Ratio), sizeof (double),
1, ptr_save);
fread (&(OPTIONS->Cost_Precision), sizeof (double), 1, ptr_save);
fread (&(OPTIONS->Maximum_Cost_Repeat), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Number_Cost_Samples), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Temperature_Ratio_Scale), sizeof (double),
1, ptr_save);
fread (&(OPTIONS->Cost_Parameter_Scale_Ratio), sizeof (double),
1, ptr_save);
fread (&(OPTIONS->Temperature_Anneal_Scale), sizeof (double),
1, ptr_save);
fread (&(OPTIONS->Include_Integer_Parameters), sizeof (int),
1, ptr_save);
fread (&(OPTIONS->User_Initial_Parameters), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Sequential_Parameters), sizeof (ALLOC_INT), 1,
ptr_save);
fread (&(OPTIONS->Initial_Parameter_Temperature), sizeof (double), 1,
ptr_save);
fread (&(OPTIONS->Acceptance_Frequency_Modulus), sizeof (int), 1,
ptr_save);
fread (&(OPTIONS->Generated_Frequency_Modulus), sizeof (int), 1,
ptr_save);
fread (&(OPTIONS->Reanneal_Cost), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Reanneal_Parameters), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Delta_X), sizeof (double), 1, ptr_save);
fread (&(OPTIONS->User_Tangents), sizeof (int), 1, ptr_save);
#if USER_INITIAL_COST_TEMP
fread (&(OPTIONS->User_Cost_Temperature), sizeof (double), 1, ptr_save);
#endif
#if RATIO_TEMPERATURE_SCALES
fread (OPTIONS->User_Temperature_Ratio, sizeof (double),
*number_parameters, ptr_save);
#endif
#if USER_INITIAL_PARAMETERS_TEMPS
fread (OPTIONS->User_Parameter_Temperature, sizeof (double),
*number_parameters, ptr_save);
#endif
#if DELTA_PARAMETERS
fread (OPTIONS->User_Delta_Parameter, sizeof (double),
*number_parameters, ptr_save);
#endif
#if QUENCH_PARAMETERS
fread (OPTIONS->User_Quench_Param_Scale, sizeof (double),
*number_parameters, ptr_save);
#endif
#if QUENCH_COST
fread (OPTIONS->User_Quench_Cost_Scale, sizeof (double), 1, ptr_save);
#endif
fread (&(OPTIONS->N_Accepted), sizeof (LONG_INT), 1, ptr_save);
fread (&(OPTIONS->N_Generated), sizeof (LONG_INT), 1, ptr_save);
fread (&(OPTIONS->Locate_Cost), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Immediate_Exit), sizeof (int), 1, ptr_save);
#if OPTIONAL_DATA_DBL
fread (&(OPTIONS->Asa_Data_Dim_Dbl), sizeof (ALLOC_INT), 1, ptr_save);
fread (OPTIONS->Asa_Data_Dbl, sizeof (double),
OPTIONS->Asa_Data_Dim_Dbl, ptr_save);
#endif
fread (&(OPTIONS->Random_Array_Dim), sizeof (ALLOC_INT), 1, ptr_save);
fread (OPTIONS->Random_Array, sizeof (double),
OPTIONS->Random_Array_Dim, ptr_save);
fread (&(OPTIONS->Asa_Recursive_Level), sizeof (int), 1, ptr_save);
#if OPTIONAL_DATA_INT
fread (&(OPTIONS->Asa_Data_Dim_Int), sizeof (ALLOC_INT), 1, ptr_save);
fread (OPTIONS->Asa_Data_Int, sizeof (LONG_INT),
OPTIONS->Asa_Data_Dim_Int, ptr_save);
#endif
#if OPTIONAL_DATA_PTR
fread (&(OPTIONS->Asa_Data_Dim_Ptr), sizeof (ALLOC_INT), 1, ptr_save);
if (OPTIONS->Asa_Recursive_Level == 0)
fread (OPTIONS->Asa_Data_Ptr, sizeof (OPTIONAL_PTR_TYPE),
OPTIONS->Asa_Data_Dim_Ptr, ptr_save);
#if ASA_TEMPLATE_SELFOPT
if (OPTIONS->Asa_Recursive_Level == 1)
fread (OPTIONS->Asa_Data_Ptr, sizeof (RECUR_OPTIONAL_PTR_TYPE),
OPTIONS->Asa_Data_Dim_Ptr, ptr_save);
#endif
#endif
#if USER_ASA_OUT
fread (OPTIONS->Asa_Out_File, sizeof (char), 1, ptr_save);
#endif
#if USER_COST_SCHEDULE
fread (&(OPTIONS->Cost_Schedule), sizeof (char), 1, ptr_save);
#endif
#if USER_ACCEPT_ASYMP_EXP
fread (&(OPTIONS->Asymp_Exp_Param), sizeof (double), 1, ptr_save);
#endif
#if USER_ACCEPTANCE_TEST
fread (&(OPTIONS->Acceptance_Test), sizeof (char), 1, ptr_save);
fread (&(OPTIONS->User_Acceptance_Flag), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Cost_Acceptance_Flag), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Cost_Temp_Curr), sizeof (double), 1, ptr_save);
fread (&(OPTIONS->Cost_Temp_Init), sizeof (double), 1, ptr_save);
fread (&(OPTIONS->Cost_Temp_Scale), sizeof (double), 1, ptr_save);
#endif
#if USER_GENERATING_FUNCTION
fread (&(OPTIONS->Generating_Distrib), sizeof (char), 1, ptr_save);
#endif
#if USER_REANNEAL_COST
fread (&(OPTIONS->Reanneal_Cost_Function), sizeof (char), 1, ptr_save);
#endif
#if USER_REANNEAL_PARAMETERS
fread (&(OPTIONS->Reanneal_Params_Function), sizeof (char),
1, ptr_save);
#endif
#if ASA_SAMPLE
fread (&(OPTIONS->Bias_Acceptance), sizeof (double), 1, ptr_save);
fread (OPTIONS->Bias_Generated, sizeof (double),
*number_parameters, ptr_save);
fread (&(OPTIONS->Average_Weights), sizeof (double), 1, ptr_save);
fread (&(OPTIONS->Limit_Weights), sizeof (double), 1, ptr_save);
#endif
#if ASA_QUEUE
fread (save_queue, sizeof (LONG_INT), 1, ptr_save);
fread (save_queue_indx, sizeof (LONG_INT), 1, ptr_save);
fread (&(OPTIONS->Queue_Size), sizeof (ALLOC_INT), 1, ptr_save);
fread (save_queue_flag, sizeof (int), save_queue, ptr_save);
fread (save_queue_cost, sizeof (double), save_queue, ptr_save);
fread (save_queue_param, sizeof (double),
(*number_parameters) * (OPTIONS->Queue_Size), ptr_save);
#if ASA_RESOLUTION
#else
fread (OPTIONS->Queue_Resolution, sizeof (double),
*number_parameters, ptr_save);
#endif
#endif
#if ASA_RESOLUTION
fread (OPTIONS->Coarse_Resolution, sizeof (double),
*number_parameters, ptr_save);
#endif
#if FITLOC
fread (&(OPTIONS->Fit_Local), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Iter_Max), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Penalty), sizeof (double), 1, ptr_save);
#endif
#if MULTI_MIN
fread (OPTIONS->Multi_Number, sizeof (int), 1, ptr_save);
fread (OPTIONS->Multi_Grid,
sizeof (double), *number_parameters, ptr_save);
fread (&(OPTIONS->Multi_Specify), sizeof (int), 1, ptr_save);
for (multi_index = 0; multi_index < OPTIONS->Multi_Number;
++multi_index) {
fread (&(OPTIONS->Multi_Cost[multi_index]), sizeof (double), 1,
ptr_save);
fread (&(OPTIONS->Multi_Params[multi_index]), sizeof (double),
*number_parameters, ptr_save);
}
#endif
#if ASA_PARALLEL
fread (¶llel_generated, sizeof (LONG_INT), 1, ptr_save);
fread (¶llel_block_max, sizeof (LONG_INT), 1, ptr_save);
for (index_parallel = 0; index_parallel < parallel_block_max;
++index_parallel) {
fread (gener_block_state[index_parallel].parameter,
sizeof (double), *number_parameters, ptr_save);
fread (&(gener_block_state[index_parallel].cost),
sizeof (double), 1, ptr_save);
#if USER_ACCEPTANCE_TEST
fread (&
(gener_block_state[index_parallel].par_user_accept_flag),
sizeof (int), 1, ptr_save);
fread (&
(gener_block_state[index_parallel].par_cost_accept_flag),
sizeof (int), 1, ptr_save);
#endif
}
fread (&(OPTIONS->Gener_Mov_Avr), sizeof (int), 1, ptr_save);
fread (&(OPTIONS->Gener_Block), sizeof (LONG_INT), 1, ptr_save);
fread (&(OPTIONS->Gener_Block_Max), sizeof (LONG_INT), 1, ptr_save);
#endif
fclose (ptr_save);
asa_read = FALSE;
#if ASA_PRINT
print_state (parameter_minimum,
parameter_maximum,
tangents,
curvature,
current_cost_temperature,
current_user_parameter_temp,
accepted_to_generated_ratio,
number_parameters,
curvature_flag,
number_accepted,
index_cost_acceptances,
number_generated,
number_invalid_generated_states,
last_saved_state,
best_generated_state, ptr_asa_out, OPTIONS);
#endif /* ASA_PRINT */
#include "asa_opt"
#if ASA_SAVE_OPT
if ((ptr_save_opt = fopen ("asa_save_opt", "r")) == NULL) {
#if INCL_STDOUT
printf ("\n\n*** WARNING fopen asa_save_opt failed *** \n\n");
#endif /* INCL_STDOUT */
#if ASA_PRINT
fprintf (ptr_asa_out,
"\n\n*** WARNING fopen asa_save_opt failed *** \n\n");
fflush (ptr_asa_out);
#endif
} else {
fscanf (ptr_save_opt, "%s%s%s%s%s",
read_if, read_FALSE, read_comm1, read_ASA_SAVE, read_comm2);
if (strcmp (read_if, "#if") || strcmp (read_FALSE, "FALSE")
|| strcmp (read_comm1, "/*")
|| strcmp (read_ASA_SAVE, "ASA_SAVE")
|| strcmp (read_comm2, "*/")) {
#if INCL_STDOUT
printf ("\n\n*** EXIT not asa_save_opt for this version *** \n\n");
#endif /* INCL_STDOUT */
#if ASA_PRINT
fprintf (ptr_asa_out,
"\n\n*** not asa_save_opt for this version *** \n\n");
fflush (ptr_asa_out);
#endif
*exit_status = INVALID_USER_INPUT;
goto EXIT_ASA;
}
#if INT_LONG
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%ld", &read_long);
OPTIONS->Limit_Acceptances = read_long;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%ld", &read_long);
OPTIONS->Limit_Generated = read_long;
#else
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Limit_Acceptances = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Limit_Generated = read_int;
#endif
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Limit_Invalid_Generated_States = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%lf", &read_double);
OPTIONS->Accepted_To_Generated_Ratio = read_double;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%lf", &read_double);
OPTIONS->Cost_Precision = read_double;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Maximum_Cost_Repeat = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Number_Cost_Samples = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%lf", &read_double);
OPTIONS->Temperature_Ratio_Scale = read_double;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%lf", &read_double);
OPTIONS->Cost_Parameter_Scale_Ratio = read_double;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%lf", &read_double);
OPTIONS->Temperature_Anneal_Scale = read_double;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Include_Integer_Parameters = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->User_Initial_Parameters = read_int;
#if INT_ALLOC
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Sequential_Parameters = read_int;
#else
#if INT_LONG
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%ld", &read_long);
OPTIONS->Sequential_Parameters = read_long;
#else
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Sequential_Parameters = read_int;
#endif
#endif
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%lf", &read_double);
OPTIONS->Initial_Parameter_Temperature = read_double;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Acceptance_Frequency_Modulus = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Generated_Frequency_Modulus = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Reanneal_Cost = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Reanneal_Parameters = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%lf", &read_double);
OPTIONS->Delta_X = read_double;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->User_Tangents = read_int;
fscanf (ptr_save_opt, "%s", read_option);
fscanf (ptr_save_opt, "%d", &read_int);
OPTIONS->Curvature_0 = read_int;
fclose (ptr_save_opt);
}
#endif /* ASA_SAVE_OPT */
goto SAVED_ASA;
}
#endif /* ASA_SAVE */
/* GENERATE NEW PARAMETERS */
/* generate a new valid set of parameters */
#if ASA_PARALLEL
/* *** ENTER CODE TO SPAWN OFF PARALLEL GENERATED STATES *** */
/* check if need more memory allocated to gener_block_state */
if (OPTIONS->Gener_Block_Max > parallel_block_max) {
for (index_parallel = 0; index_parallel < parallel_block_max;
++index_parallel) {
free (gener_block_state[index_parallel].parameter);
}
free (gener_block_state);
if ((gener_block_state =
(STATE *) calloc (OPTIONS->Gener_Block_Max,
sizeof (STATE))) == NULL) {
strcpy (exit_msg, "asa(): gener_block_state");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
parallel_block_max = OPTIONS->Gener_Block_Max;
for (index_parallel = 0; index_parallel < parallel_block_max;
++index_parallel) {
if ((gener_block_state[index_parallel].parameter =
(double *) calloc (*number_parameters,
sizeof (double))) == NULL) {
strcpy (exit_msg,
"asa(): gener_block_state[index_parallel].parameter");
Exit_ASA (exit_msg);
*exit_status = CALLOC_FAILED;
return (-1);
}
}
}
#if ASA_TEMPLATE_PARALLEL
for (index_parallel = 0; index_parallel < OPTIONS->Gener_Block;
++index_parallel) {
#endif /* ASA_TEMPLATE_PARALLEL */
#endif /* ASA_PARALLEL */
if (OPTIONS->Locate_Cost < 0) {
OPTIONS->Locate_Cost = 12; /* generate new state from new best */
} else {
OPTIONS->Locate_Cost = 2; /* generate new state */
}
repeated_invalid_states = 0;
do {
++(*number_invalid_generated_states);
generate_new_state (user_random_generator,
seed,
parameter_minimum,
parameter_maximum, current_user_parameter_temp,
#if USER_GENERATING_FUNCTION
initial_user_parameter_temp,
temperature_scale_parameters,
#endif
number_parameters,
parameter_type,
current_generated_state,
last_saved_state, OPTIONS);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = FALSE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
#if ASA_QUEUE
/* Binary trees do not seem necessary since we are assuming
that the cost function calculation is the bottleneck.
However, see the MISC.DIR/asa_contrib file for
source code for doubly-linked and hashed lists. */
if (OPTIONS->Queue_Size == 0) {
queue_new = 1;
} else {
queue_new = 1;
for (queue = 0; queue < save_queue; ++queue) {
save_queue_test = 0;
VFOR (index_v) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
++save_queue_test;
} else {
queue_v = index_v + queue * (LONG_INT) (*number_parameters);
if (fabs
(current_generated_state->parameter[index_v] -
save_queue_param[queue_v]) <=
(OPTIONS->Queue_Resolution[index_v] + EPS_DOUBLE)) {
++save_queue_test;
}
}
}
if (save_queue_test == *number_parameters) {
tmp_var_db = save_queue_cost[queue];
*valid_state_generated_flag = save_queue_flag[queue];
queue_new = 0;
--(*number_generated);
#if ASA_PRINT_MORE
#if INT_LONG
fprintf (ptr_asa_out, "ASA_QUEUE: %ld \t %*.*g\n",
OPTIONS->N_Generated,
G_FIELD, G_PRECISION, tmp_var_db);
#else
fprintf (ptr_asa_out, "ASA_QUEUE: %d \t %*.*g\n",
OPTIONS->N_Generated,
G_FIELD, G_PRECISION, tmp_var_db);
#endif
#endif
break;
}
}
}
if (queue_new == 1) {
tmp_var_db =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (tmp_var_db,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION;
goto EXIT_ASA;
}
if (OPTIONS->Queue_Size > 0) { /* in case recursive use */
VFOR (index_v) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
continue;
}
queue_v = index_v + save_queue_indx
* (LONG_INT) (*number_parameters);
save_queue_param[queue_v] =
current_generated_state->parameter[index_v];
}
save_queue_cost[save_queue_indx] = tmp_var_db;
save_queue_flag[save_queue_indx]
= *valid_state_generated_flag;
++save_queue;
if (save_queue == (LONG_INT) OPTIONS->Queue_Size)
--save_queue;
++save_queue_indx;
if (save_queue_indx == (LONG_INT) OPTIONS->Queue_Size)
save_queue_indx = 0;
}
}
#else /* ASA_QUEUE */
tmp_var_db =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (tmp_var_db,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION;
goto EXIT_ASA;
}
#endif /* ASA_QUEUE */
current_generated_state->cost = tmp_var_db;
++repeated_invalid_states;
if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {
*exit_status = TOO_MANY_INVALID_STATES;
goto EXIT_ASA;
}
}
while (*valid_state_generated_flag == FALSE);
--(*number_invalid_generated_states);
#if ASA_PARALLEL
gener_block_state[index_parallel].cost = current_generated_state->cost;
#if USER_ACCEPTANCE_TEST
gener_block_state[index_parallel].par_user_accept_flag =
OPTIONS->User_Acceptance_Flag;
gener_block_state[index_parallel].par_cost_accept_flag =
OPTIONS->Cost_Acceptance_Flag;
#endif
VFOR (index_v) {
/* ignore parameters with too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
gener_block_state[index_parallel].parameter[index_v] =
current_generated_state->parameter[index_v];
}
#if ASA_TEMPLATE_PARALLEL
}
#endif /* ASA_TEMPLATE_PARALLEL */
/* *** EXIT CODE SPAWNING OFF PARALLEL GENERATED STATES *** */
#endif /* ASA_PARALLEL */
/* ACCEPT/REJECT NEW PARAMETERS */
#if ASA_PARALLEL
for (sort_index = 0; sort_index < OPTIONS->Gener_Block; ++sort_index)
parallel_sort[sort_index] = sort_index;
qsort (parallel_sort, OPTIONS->Gener_Block, sizeof (LONG_INT),
sort_parallel);
for (sort_index = 0; sort_index < OPTIONS->Gener_Block; ++sort_index) {
index_parallel = parallel_sort[sort_index];
current_generated_state->cost = gener_block_state[index_parallel].cost;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag =
gener_block_state[index_parallel].par_user_accept_flag;
OPTIONS->Cost_Acceptance_Flag =
gener_block_state[index_parallel].par_cost_accept_flag;
#endif
VFOR (index_v) {
/* ignore parameters with too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
current_generated_state->parameter[index_v] =
gener_block_state[index_parallel].parameter[index_v];
}
#endif /* ASA_PARALLEL */
/* decide to accept/reject the new state */
accept_new_state (user_random_generator,
seed,
parameter_minimum,
parameter_maximum, current_cost_temperature,
#if ASA_SAMPLE
current_user_parameter_temp,
#endif
number_parameters,
recent_number_acceptances,
number_accepted,
index_cost_acceptances,
number_acceptances_saved,
recent_number_generated,
number_generated,
index_parameter_generations,
current_generated_state, last_saved_state,
#if ASA_SAMPLE
ptr_asa_out,
#endif
OPTIONS);
#if ASA_PARALLEL
#else
#if ASA_PIPE_FILE
#if INT_ALLOC
fprintf (ptr_asa_pipe, "%d", *number_generated);
#else
#if INT_LONG
fprintf (ptr_asa_pipe, "%ld", *number_generated);
#else
fprintf (ptr_asa_pipe, "%d", *number_generated);
#endif
#endif
#if INT_ALLOC
fprintf (ptr_asa_pipe, "\t%d", *number_accepted);
#else
#if INT_LONG
fprintf (ptr_asa_pipe, "\t%ld", *number_accepted);
#else
fprintf (ptr_asa_pipe, "\t%d", *number_accepted);
#endif
#endif
fprintf (ptr_asa_pipe, "\t%g", best_generated_state->cost);
VFOR (index_v)
fprintf (ptr_asa_pipe, "\t%g",
best_generated_state->parameter[index_v]);
fprintf (ptr_asa_pipe, "\t%g", *current_cost_temperature);
VFOR (index_v)
fprintf (ptr_asa_pipe, "\t%g", current_user_parameter_temp[index_v]);
fprintf (ptr_asa_pipe, "\t%g", last_saved_state->cost);
fprintf (ptr_asa_pipe, "\n");
fflush (ptr_asa_pipe);
#endif /* ASA_PIPE_FILE */
#if INCL_STDOUT
#if ASA_PIPE
#if INT_ALLOC
printf ("%d", *number_generated);
#else
#if INT_LONG
printf ("%ld", *number_generated);
#else
printf ("%d", *number_generated);
#endif
#endif
#if INT_ALLOC
printf ("\t%d", *number_accepted);
#else
#if INT_LONG
printf ("\t%ld", *number_accepted);
#else
printf ("\t%d", *number_accepted);
#endif
#endif
printf ("\t%g", best_generated_state->cost);
VFOR (index_v)
printf ("\t%g", best_generated_state->parameter[index_v]);
printf ("\t%g", *current_cost_temperature);
VFOR (index_v)
printf ("\t%g", current_user_parameter_temp[index_v]);
printf ("\n");
#endif /* ASA_PIPE */
#endif /* INCL_STDOUT */
#endif /* ASA_PARALLEL */
/* calculate the ratio of acceptances to generated states */
*accepted_to_generated_ratio =
(double) (*recent_number_acceptances + 1) /
(double) (*recent_number_generated + 1);
#if MULTI_MIN
if (((OPTIONS->Multi_Specify == 0)
&& (current_generated_state->cost <= best_generated_state->cost))
|| ((OPTIONS->Multi_Specify == 1)
&& (current_generated_state->cost <
best_generated_state->cost))) {
#if ASA_RESOLUTION
VFOR (index_v) {
if (OPTIONS->Multi_Grid[index_v] <
OPTIONS->Coarse_Resolution[index_v])
OPTIONS->Multi_Grid[index_v] =
OPTIONS->Coarse_Resolution[index_v];
}
#endif /* ASA_RESOLUTION */
VFOR (index_v) {
if (OPTIONS->Multi_Grid[index_v] < EPS_DOUBLE)
OPTIONS->Multi_Grid[index_v] = EPS_DOUBLE;
}
multi_test = 0;
for (multi_index = 0; multi_index < OPTIONS->Multi_Number;
++multi_index) {
multi_test_cmp = 0;
multi_test_dim = 0;
VFOR (index_v) {
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
++multi_test_dim;
if (fabs (current_generated_state->parameter[index_v]
- OPTIONS->Multi_Params[multi_index][index_v])
< OPTIONS->Multi_Grid[index_v])
++multi_test_cmp;
}
if (multi_test_cmp == multi_test_dim)
multi_test = 1;
if (OPTIONS->Multi_Specify == 1)
break;
}
if (multi_test == 0) {
multi_cost[OPTIONS->Multi_Number] = current_generated_state->cost;
VFOR (index_v) {
multi_params[OPTIONS->Multi_Number][index_v] =
current_generated_state->parameter[index_v];
}
for (multi_index = 0; multi_index < OPTIONS->Multi_Number;
++multi_index) {
multi_cost[multi_index] = OPTIONS->Multi_Cost[multi_index];
VFOR (index_v) {
multi_params[multi_index][index_v] =
OPTIONS->Multi_Params[multi_index][index_v];
}
}
qsort (multi_sort, OPTIONS->Multi_Number + 1, sizeof (int),
multi_compare);
for (multi_index = 0; multi_index < OPTIONS->Multi_Number;
++multi_index) {
OPTIONS->Multi_Cost[multi_index] =
multi_cost[multi_sort[multi_index]];
VFOR (index_v) {
OPTIONS->Multi_Params[multi_index][index_v] =
multi_params[multi_sort[multi_index]][index_v];
}
}
}
}
#endif /* MULTI_MIN */
/* CHECK FOR NEW MINIMUM */
if (current_generated_state->cost < best_generated_state->cost) {
/* NEW MINIMUM FOUND */
OPTIONS->Locate_Cost = -1;
/* reset the recent acceptances and generated counts */
#if ASA_PARALLEL
parallel_generated = *recent_number_generated;
#endif
*recent_number_acceptances = *recent_number_generated = 0;
*best_number_generated_saved = *number_generated;
*best_number_accepted_saved = *number_accepted;
index_cost_repeat = 0;
/* copy the current state into the best_generated state */
best_generated_state->cost = current_generated_state->cost;
VFOR (index_v) {
#if DROPPED_PARAMETERS
/* ignore parameters that have too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
#endif
best_generated_state->parameter[index_v] =
current_generated_state->parameter[index_v];
}
/* printout the new minimum state and value */
#if ASA_PRINT
fprintf (ptr_asa_out,
#if INT_LONG
"best...->cost=%-*.*g \
*number_accepted=%ld *number_generated=%ld\n", G_FIELD, G_PRECISION, best_generated_state->cost,
#else
"best...->cost=%-*.*g \
*number_accepted=%d *number_generated=%d\n", G_FIELD, G_PRECISION, best_generated_state->cost,
#endif /* INT_LONG */
*number_accepted, *number_generated);
#if ASA_PARALLEL
/* print OPTIONS->Gener_Block just used */
fprintf (ptr_asa_out,
#if INT_LONG
"OPTIONS->Gener_Block = %ld\n",
#else
"OPTIONS->Gener_Block = %d\n",
#endif /* INT_LONG */
OPTIONS->Gener_Block);
#endif /* ASA_PARALLEL */
#if ASA_PRINT_MORE
#if INT_ALLOC
fprintf (ptr_asa_out, "Present Random Seed = %d\n\n", *seed);
#else
#if INT_LONG
fprintf (ptr_asa_out, "Present Random Seed = %ld\n\n", *seed);
#else
fprintf (ptr_asa_out, "Present Random Seed = %d\n\n", *seed);
#endif
#endif
print_state (parameter_minimum,
parameter_maximum,
tangents,
curvature,
current_cost_temperature,
current_user_parameter_temp,
accepted_to_generated_ratio,
number_parameters,
curvature_flag,
number_accepted,
index_cost_acceptances,
number_generated,
number_invalid_generated_states,
last_saved_state,
best_generated_state, ptr_asa_out, OPTIONS);
#endif /* ASA_PRINT_MORE */
fflush (ptr_asa_out);
#endif /* ASA_PRINT */
#if ASA_PARALLEL
/* leave index_parallel loop after new minimum */
break;
#endif /* ASA_PARALLEL */
}
#if ASA_PARALLEL
}
#endif /* ASA_PARALLEL */
#if ASA_PARALLEL
if (OPTIONS->Gener_Mov_Avr > 0) {
OPTIONS->Gener_Block = (LONG_INT)
((((double) OPTIONS->Gener_Mov_Avr - ONE)
* (double) (OPTIONS->Gener_Block) + (double) parallel_generated)
/ (double) (OPTIONS->Gener_Mov_Avr));
OPTIONS->Gener_Block = MIN (OPTIONS->Gener_Block, parallel_block_max);
}
#endif /* ASA_PARALLEL */
#if ASA_SAVE
/* These writes are put here with these tests, instead of just
after a new best state is found, to prevent any confusion with
any parallel code that might be added by users. */
if (*recent_number_acceptances == 0
&& *recent_number_generated == 0
&& *best_number_generated_saved == *number_generated
&& *best_number_accepted_saved == *number_accepted
&& OPTIONS->Asa_Recursive_Level == asa_recursive_max
&& index_cost_repeat == 0) {
if (OPTIONS->Asa_Recursive_Level > 0)
sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);
else
sprintf (asa_save_comm, "asa_save");
ptr_save = fopen (asa_save_comm, "w");
fwrite (number_parameters, sizeof (ALLOC_INT), 1, ptr_save);
fwrite (xnumber_parameters, sizeof (double), 1, ptr_save);
fwrite (parameter_minimum, sizeof (double),
*number_parameters, ptr_save);
fwrite (parameter_maximum, sizeof (double),
*number_parameters, ptr_save);
fwrite (tangents, sizeof (double), *number_parameters, ptr_save);
fwrite (current_user_parameter_temp, sizeof (double),
*number_parameters, ptr_save);
fwrite (initial_user_parameter_temp, sizeof (double),
*number_parameters, ptr_save);
fwrite (temperature_scale_parameters, sizeof (double),
*number_parameters, ptr_save);
fwrite (parameter_type, sizeof (int), *number_parameters, ptr_save);
fwrite (&index_cost_repeat, sizeof (int), 1, ptr_save);
fwrite (&asa_open, sizeof (int), 1, ptr_save);
fwrite (&number_asa_open, sizeof (int), 1, ptr_save);
fwrite (&recursive_asa_open, sizeof (int), 1, ptr_save);
fwrite (current_cost_temperature, sizeof (double), 1, ptr_save);
fwrite (initial_cost_temperature, sizeof (double), 1, ptr_save);
fwrite (temperature_scale_cost, sizeof (double), 1, ptr_save);
fwrite (accepted_to_generated_ratio, sizeof (double), 1, ptr_save);
fwrite (curvature_flag, sizeof (int), 1, ptr_save);
fwrite (seed, sizeof (LONG_INT), 1, ptr_save);
fwrite (number_generated, sizeof (LONG_INT), 1, ptr_save);
fwrite (number_accepted, sizeof (LONG_INT), 1, ptr_save);
fwrite (number_acceptances_saved, sizeof (LONG_INT), 1, ptr_save);
fwrite (recent_number_acceptances, sizeof (LONG_INT), 1, ptr_save);
fwrite (recent_number_generated, sizeof (LONG_INT), 1, ptr_save);
fwrite (number_invalid_generated_states, sizeof (LONG_INT),
1, ptr_save);
fwrite (index_cost_acceptances, sizeof (LONG_INT), 1, ptr_save);
fwrite (best_number_generated_saved, sizeof (LONG_INT), 1, ptr_save);
fwrite (best_number_accepted_saved, sizeof (LONG_INT), 1, ptr_save);
fwrite (index_parameter_generations, sizeof (LONG_INT),
*number_parameters, ptr_save);
fwrite (current_generated_state->parameter,
sizeof (double), *number_parameters, ptr_save);
fwrite (last_saved_state->parameter,
sizeof (double), *number_parameters, ptr_save);
fwrite (best_generated_state->parameter,
sizeof (double), *number_parameters, ptr_save);
fwrite (&(current_generated_state->cost), sizeof (double), 1, ptr_save);
fwrite (&(last_saved_state->cost), sizeof (double), 1, ptr_save);
fwrite (&(best_generated_state->cost), sizeof (double), 1, ptr_save);
fwrite (&(OPTIONS->Limit_Acceptances), sizeof (LONG_INT), 1, ptr_save);
fwrite (&(OPTIONS->Limit_Generated), sizeof (LONG_INT), 1, ptr_save);
fwrite (&(OPTIONS->Limit_Invalid_Generated_States), sizeof (int),
1, ptr_save);
fwrite (&(OPTIONS->Accepted_To_Generated_Ratio), sizeof (double),
1, ptr_save);
fwrite (&(OPTIONS->Cost_Precision), sizeof (double), 1, ptr_save);
fwrite (&(OPTIONS->Maximum_Cost_Repeat), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Number_Cost_Samples), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Temperature_Ratio_Scale), sizeof (double),
1, ptr_save);
fwrite (&(OPTIONS->Cost_Parameter_Scale_Ratio), sizeof (double),
1, ptr_save);
fwrite (&(OPTIONS->Temperature_Anneal_Scale), sizeof (double),
1, ptr_save);
fwrite (&(OPTIONS->Include_Integer_Parameters), sizeof (int),
1, ptr_save);
fwrite (&(OPTIONS->User_Initial_Parameters), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Sequential_Parameters), sizeof (ALLOC_INT), 1,
ptr_save);
fwrite (&(OPTIONS->Initial_Parameter_Temperature), sizeof (double), 1,
ptr_save);
fwrite (&(OPTIONS->Acceptance_Frequency_Modulus), sizeof (int), 1,
ptr_save);
fwrite (&(OPTIONS->Generated_Frequency_Modulus), sizeof (int), 1,
ptr_save);
fwrite (&(OPTIONS->Reanneal_Cost), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Reanneal_Parameters), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Delta_X), sizeof (double), 1, ptr_save);
fwrite (&(OPTIONS->User_Tangents), sizeof (int), 1, ptr_save);
#if USER_INITIAL_COST_TEMP
fwrite (&(OPTIONS->User_Cost_Temperature), sizeof (double),
1, ptr_save);
#endif
#if RATIO_TEMPERATURE_SCALES
fwrite (OPTIONS->User_Temperature_Ratio, sizeof (double),
*number_parameters, ptr_save);
#endif
#if USER_INITIAL_PARAMETERS_TEMPS
fwrite (OPTIONS->User_Parameter_Temperature, sizeof (double),
*number_parameters, ptr_save);
#endif
#if DELTA_PARAMETERS
fwrite (OPTIONS->User_Delta_Parameter, sizeof (double),
*number_parameters, ptr_save);
#endif
#if QUENCH_PARAMETERS
fwrite (OPTIONS->User_Quench_Param_Scale, sizeof (double),
*number_parameters, ptr_save);
#endif
#if QUENCH_COST
fwrite (OPTIONS->User_Quench_Cost_Scale, sizeof (double), 1, ptr_save);
#endif
fwrite (&(OPTIONS->N_Accepted), sizeof (LONG_INT), 1, ptr_save);
fwrite (&(OPTIONS->N_Generated), sizeof (LONG_INT), 1, ptr_save);
fwrite (&(OPTIONS->Locate_Cost), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Immediate_Exit), sizeof (int), 1, ptr_save);
#if OPTIONAL_DATA_DBL
fwrite (&(OPTIONS->Asa_Data_Dim_Dbl), sizeof (ALLOC_INT), 1, ptr_save);
fwrite (OPTIONS->Asa_Data_Dbl, sizeof (double),
OPTIONS->Asa_Data_Dim_Dbl, ptr_save);
#endif
fwrite (&(OPTIONS->Random_Array_Dim), sizeof (ALLOC_INT), 1, ptr_save);
fwrite (OPTIONS->Random_Array, sizeof (double),
OPTIONS->Random_Array_Dim, ptr_save);
fwrite (&(OPTIONS->Asa_Recursive_Level), sizeof (int), 1, ptr_save);
#if OPTIONAL_DATA_INT
fwrite (&(OPTIONS->Asa_Data_Dim_Int), sizeof (ALLOC_INT), 1, ptr_save);
fwrite (OPTIONS->Asa_Data_Int, sizeof (LONG_INT),
OPTIONS->Asa_Data_Dim_Int, ptr_save);
#endif
#if OPTIONAL_DATA_PTR
fwrite (&(OPTIONS->Asa_Data_Dim_Ptr), sizeof (ALLOC_INT), 1, ptr_save);
if (OPTIONS->Asa_Recursive_Level == 0)
fwrite (OPTIONS->Asa_Data_Ptr, sizeof (OPTIONAL_PTR_TYPE),
OPTIONS->Asa_Data_Dim_Ptr, ptr_save);
#if ASA_TEMPLATE_SELFOPT
if (OPTIONS->Asa_Recursive_Level == 1)
fwrite (OPTIONS->Asa_Data_Ptr, sizeof (RECUR_OPTIONAL_PTR_TYPE),
OPTIONS->Asa_Data_Dim_Ptr, ptr_save);
#endif
#endif
#if USER_ASA_OUT
fwrite (OPTIONS->Asa_Out_File, sizeof (char), 1, ptr_save);
#endif
#if USER_COST_SCHEDULE
fwrite (&(OPTIONS->Cost_Schedule), sizeof (char), 1, ptr_save);
#endif
#if USER_ACCEPT_ASYMP_EXP
fwrite (&(OPTIONS->Asymp_Exp_Param), sizeof (double), 1, ptr_save);
#endif
#if USER_ACCEPTANCE_TEST
fwrite (&(OPTIONS->Acceptance_Test), sizeof (char), 1, ptr_save);
fwrite (&(OPTIONS->User_Acceptance_Flag), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Cost_Acceptance_Flag), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Cost_Temp_Curr), sizeof (double), 1, ptr_save);
fwrite (&(OPTIONS->Cost_Temp_Init), sizeof (double), 1, ptr_save);
fwrite (&(OPTIONS->Cost_Temp_Scale), sizeof (double), 1, ptr_save);
#endif
#if USER_GENERATING_FUNCTION
fwrite (&(OPTIONS->Generating_Distrib), sizeof (char), 1, ptr_save);
#endif
#if USER_REANNEAL_COST
fwrite (&(OPTIONS->Reanneal_Cost_Function), sizeof (char), 1, ptr_save);
#endif
#if USER_REANNEAL_PARAMETERS
fwrite (&(OPTIONS->Reanneal_Params_Function), sizeof (char),
1, ptr_save);
#endif
#if ASA_SAMPLE
fwrite (&(OPTIONS->Bias_Acceptance), sizeof (double), 1, ptr_save);
fwrite (OPTIONS->Bias_Generated, sizeof (double),
*number_parameters, ptr_save);
fwrite (&(OPTIONS->Average_Weights), sizeof (double), 1, ptr_save);
fwrite (&(OPTIONS->Limit_Weights), sizeof (double), 1, ptr_save);
#endif
#if ASA_QUEUE
fwrite (save_queue, sizeof (LONG_INT), 1, ptr_save);
fwrite (save_queue_indx, sizeof (LONG_INT), 1, ptr_save);
fwrite (&(OPTIONS->Queue_Size), sizeof (ALLOC_INT), 1, ptr_save);
fwrite (save_queue_flag, sizeof (int), save_queue, ptr_save);
fwrite (save_queue_cost, sizeof (double), save_queue, ptr_save);
fwrite (save_queue_param, sizeof (double),
(*number_parameters) * (OPTIONS->Queue_Size), ptr_save);
#if ASA_RESOLUTION
#else
fwrite (OPTIONS->Queue_Resolution, sizeof (double),
*number_parameters, ptr_save);
#endif
#endif
#if ASA_RESOLUTION
fwrite (OPTIONS->Coarse_Resolution, sizeof (double),
*number_parameters, ptr_save);
#endif
#if FITLOC
fwrite (&(OPTIONS->Fit_Local), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Iter_Max), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Penalty), sizeof (double), 1, ptr_save);
#endif
#if MULTI_MIN
fwrite (OPTIONS->Multi_Number, sizeof (int), 1, ptr_save);
fwrite (OPTIONS->Multi_Grid,
sizeof (double), *number_parameters, ptr_save);
fwrite (&(OPTIONS->Multi_Specify), sizeof (int), 1, ptr_save);
for (multi_index = 0; multi_index < OPTIONS->Multi_Number;
++multi_index) {
fwrite (&(OPTIONS->Multi_Cost[multi_index]), sizeof (double), 1,
ptr_save);
fwrite (&(OPTIONS->Multi_Params[multi_index]), sizeof (double),
*number_parameters, ptr_save);
}
#endif
#if ASA_PARALLEL
fwrite (¶llel_generated, sizeof (LONG_INT), 1, ptr_save);
fwrite (¶llel_block_max, sizeof (LONG_INT), 1, ptr_save);
for (index_parallel = 0; index_parallel < parallel_block_max;
++index_parallel) {
fwrite (gener_block_state[index_parallel].parameter,
sizeof (double), *number_parameters, ptr_save);
fwrite (&(gener_block_state[index_parallel].cost),
sizeof (double), 1, ptr_save);
#if USER_ACCEPTANCE_TEST
fwrite (&
(gener_block_state[index_parallel].
par_user_accept_flag), sizeof (int), 1, ptr_save);
fwrite (&
(gener_block_state[index_parallel].
par_cost_accept_flag), sizeof (int), 1, ptr_save);
#endif
}
fwrite (&(OPTIONS->Gener_Mov_Avr), sizeof (int), 1, ptr_save);
fwrite (&(OPTIONS->Gener_Block), sizeof (LONG_INT), 1, ptr_save);
fwrite (&(OPTIONS->Gener_Block_Max), sizeof (LONG_INT), 1, ptr_save);
#endif
fclose (ptr_save);
SAVED_ASA:
;
#if SYSTEM_CALL
#if ASA_SAVE_BACKUP
#if INT_LONG
if (OPTIONS->Asa_Recursive_Level > 0)
sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.%ld",
OPTIONS->Asa_Recursive_Level,
OPTIONS->Asa_Recursive_Level, OPTIONS->N_Accepted);
else
sprintf (asa_save_comm, "/bin/cp asa_save asa_save.%ld",
OPTIONS->N_Accepted);
#else
if (OPTIONS->Asa_Recursive_Level > 0)
sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.%d",
OPTIONS->Asa_Recursive_Level,
OPTIONS->Asa_Recursive_Level, OPTIONS->N_Accepted);
else
sprintf (asa_save_comm, "/bin/cp asa_save asa_save.%d",
OPTIONS->N_Accepted);
#endif
ptr_comm = popen (asa_save_comm, "r");
pclose (ptr_comm);
#else /* ASA_SAVE_BACKUP */
/* extra protection in case run aborts during write */
if (OPTIONS->Asa_Recursive_Level > 0)
sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.old",
OPTIONS->Asa_Recursive_Level, OPTIONS->Asa_Recursive_Level);
else
sprintf (asa_save_comm, "/bin/cp asa_save asa_save.old");
ptr_comm = popen (asa_save_comm, "r");
pclose (ptr_comm);
#endif /* ASA_SAVE_BACKUP */
#endif /* SYSTEM_CALL */
}
#endif /* ASA_SAVE */
if (OPTIONS->Immediate_Exit == TRUE) {
*exit_status = IMMEDIATE_EXIT;
goto EXIT_ASA;
}
/* PERIODIC TESTING/REANNEALING/PRINTING SECTION */
if (OPTIONS->Acceptance_Frequency_Modulus == 0)
tmp_var_int1 = FALSE;
else if ((int) (*number_accepted %
((LONG_INT) OPTIONS->Acceptance_Frequency_Modulus)) == 0
&& *number_acceptances_saved == *number_accepted)
tmp_var_int1 = TRUE;
else
tmp_var_int1 = FALSE;
if (OPTIONS->Generated_Frequency_Modulus == 0)
tmp_var_int2 = FALSE;
else if ((int) (*number_generated %
((LONG_INT) OPTIONS->Generated_Frequency_Modulus)) == 0)
tmp_var_int2 = TRUE;
else
tmp_var_int2 = FALSE;
if (tmp_var_int1 == TRUE || tmp_var_int2 == TRUE
|| (*accepted_to_generated_ratio
< OPTIONS->Accepted_To_Generated_Ratio)) {
if (*accepted_to_generated_ratio
< (OPTIONS->Accepted_To_Generated_Ratio))
*recent_number_acceptances = *recent_number_generated = 0;
/* if best.cost repeats OPTIONS->Maximum_Cost_Repeat then exit */
if (OPTIONS->Maximum_Cost_Repeat != 0) {
if (fabs (last_saved_state->cost - best_generated_state->cost)
< OPTIONS->Cost_Precision) {
++index_cost_repeat;
if (index_cost_repeat == (OPTIONS->Maximum_Cost_Repeat)) {
*exit_status = COST_REPEATING;
goto EXIT_ASA;
}
} else {
index_cost_repeat = 0;
}
}
if (OPTIONS->Reanneal_Parameters == TRUE) {
OPTIONS->Locate_Cost = 3; /* reanneal parameters */
/* calculate tangents, not curvatures, to reanneal */
*curvature_flag = FALSE;
cost_derivatives (user_cost_function,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
maximum_tangent,
number_parameters,
parameter_type,
exit_status,
curvature_flag,
valid_state_generated_flag,
number_invalid_generated_states,
current_generated_state,
best_generated_state, ptr_asa_out, OPTIONS);
if (*exit_status == INVALID_COST_FUNCTION_DERIV) {
goto EXIT_ASA;
}
}
#if USER_REANNEAL_COST
#else
if (OPTIONS->Reanneal_Cost == 0 || OPTIONS->Reanneal_Cost == 1) {
;
} else {
immediate_flag = OPTIONS->Immediate_Exit;
if (OPTIONS->Reanneal_Cost < -1) {
tmp_var_int = -OPTIONS->Reanneal_Cost;
} else {
tmp_var_int = OPTIONS->Reanneal_Cost;
}
tmp_var_db1 = ZERO;
tmp_var_db2 = ZERO;
for (index_cost_constraint = 0;
index_cost_constraint < tmp_var_int; ++index_cost_constraint) {
OPTIONS->Locate_Cost = 4; /* reanneal cost */
*number_invalid_generated_states = 0;
repeated_invalid_states = 0;
OPTIONS->Sequential_Parameters = *start_sequence - 1;
do {
++(*number_invalid_generated_states);
generate_new_state (user_random_generator,
seed,
parameter_minimum,
parameter_maximum,
current_user_parameter_temp,
#if USER_GENERATING_FUNCTION
initial_user_parameter_temp,
temperature_scale_parameters,
#endif
number_parameters,
parameter_type,
current_generated_state,
last_saved_state, OPTIONS);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
#if ASA_QUEUE
if (OPTIONS->Queue_Size == 0) {
queue_new = 1;
} else {
queue_new = 1;
for (queue = 0; queue < save_queue; ++queue) {
save_queue_test = 0;
VFOR (index_v) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
++save_queue_test;
} else {
queue_v = index_v + queue
* (LONG_INT) (*number_parameters);
if (fabs
(current_generated_state->
parameter[index_v] -
save_queue_param[queue_v]) <
(OPTIONS->Queue_Resolution[index_v] + EPS_DOUBLE)) {
++save_queue_test;
}
}
}
if (save_queue_test == *number_parameters) {
tmp_var_db = save_queue_cost[queue];
*valid_state_generated_flag = save_queue_flag[queue];
queue_new = 0;
#if ASA_PRINT_MORE
#if INT_LONG
fprintf (ptr_asa_out,
"ASA_QUEUE: %ld \t %*.*g\n",
OPTIONS->N_Generated, G_FIELD,
G_PRECISION, tmp_var_db);
#else
fprintf (ptr_asa_out,
"ASA_QUEUE: %d \t %*.*g\n",
OPTIONS->N_Generated, G_FIELD,
G_PRECISION, tmp_var_db);
#endif
#endif
break;
}
}
}
if (queue_new == 1) {
tmp_var_db =
user_cost_function (current_generated_state->
parameter, parameter_minimum,
parameter_maximum, tangents,
curvature, number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test
(tmp_var_db, current_generated_state->parameter,
parameter_minimum, parameter_maximum,
number_parameters, xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION;
goto EXIT_ASA;
}
if (OPTIONS->Queue_Size > 0) {
VFOR (index_v) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
continue;
}
queue_v = index_v + save_queue
* (LONG_INT) (*number_parameters);
save_queue_param[queue_v] =
current_generated_state->parameter[index_v];
}
save_queue_cost[save_queue] = tmp_var_db;
save_queue_flag[save_queue]
= *valid_state_generated_flag;
++save_queue;
if (save_queue == (LONG_INT) OPTIONS->Queue_Size)
--save_queue;
++save_queue_indx;
if (save_queue_indx == (LONG_INT) OPTIONS->Queue_Size)
save_queue_indx = 0;
}
}
#else /* ASA_QUEUE */
tmp_var_db =
user_cost_function (current_generated_state->
parameter, parameter_minimum,
parameter_maximum, tangents,
curvature, number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test
(tmp_var_db, current_generated_state->parameter,
parameter_minimum, parameter_maximum,
number_parameters, xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION;
goto EXIT_ASA;
}
#endif /* ASA_QUEUE */
++repeated_invalid_states;
if (repeated_invalid_states >
OPTIONS->Limit_Invalid_Generated_States) {
*exit_status = TOO_MANY_INVALID_STATES;
goto EXIT_ASA;
}
}
while (*valid_state_generated_flag == FALSE);
--(*number_invalid_generated_states);
tmp_var_db1 += tmp_var_db;
tmp_var_db2 += (tmp_var_db * tmp_var_db);
}
tmp_var_db1 /= (double) tmp_var_int;
tmp_var_db2 /= (double) tmp_var_int;
tmp_var_db =
sqrt (fabs
((tmp_var_db2 -
tmp_var_db1 * tmp_var_db1) * ((double) tmp_var_int /
((double) tmp_var_int -
ONE))));
if (OPTIONS->Reanneal_Cost < -1) {
*current_cost_temperature = *initial_cost_temperature =
tmp_var_db + (double) EPS_DOUBLE;
} else {
*initial_cost_temperature = tmp_var_db + (double) EPS_DOUBLE;
}
OPTIONS->Immediate_Exit = immediate_flag;
}
#endif /* USER_REANNEAL_COST */
reanneal (parameter_minimum,
parameter_maximum,
tangents,
maximum_tangent,
current_cost_temperature,
initial_cost_temperature,
temperature_scale_cost,
current_user_parameter_temp,
initial_user_parameter_temp,
temperature_scale_parameters,
number_parameters,
parameter_type,
index_cost_acceptances,
index_parameter_generations,
last_saved_state, best_generated_state, OPTIONS);
#if ASA_PRINT_INTERMED
#if ASA_PRINT
print_state (parameter_minimum,
parameter_maximum,
tangents,
curvature,
current_cost_temperature,
current_user_parameter_temp,
accepted_to_generated_ratio,
number_parameters,
curvature_flag,
number_accepted,
index_cost_acceptances,
number_generated,
number_invalid_generated_states,
last_saved_state,
best_generated_state, ptr_asa_out, OPTIONS);
fprintf (ptr_asa_out, "\n");
fflush (ptr_asa_out);
#endif
#endif
}
}
/* FINISHED ANNEALING and MINIMIZATION */
*exit_status = NORMAL_EXIT;
EXIT_ASA:
asa_exit_value = asa_exit (user_cost_function,
&final_cost,
parameter_initial_final,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
maximum_tangent,
current_cost_temperature,
initial_user_parameter_temp,
current_user_parameter_temp,
accepted_to_generated_ratio,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status,
index_exit_v,
start_sequence,
number_accepted,
best_number_accepted_saved,
index_cost_acceptances,
number_generated,
number_invalid_generated_states,
index_parameter_generations,
best_number_generated_saved,
current_generated_state,
last_saved_state,
best_generated_state, ptr_asa_out, OPTIONS);
if (asa_exit_value == 9) {
*exit_status = CALLOC_FAILED;
return (-1);
}
free (curvature_flag);
free (maximum_tangent);
free (accepted_to_generated_ratio);
free (temperature_scale_cost);
free (current_cost_temperature);
free (initial_cost_temperature);
free (number_generated);
free (best_number_generated_saved);
free (recent_number_generated);
free (number_accepted);
free (recent_number_acceptances);
free (index_cost_acceptances);
free (number_acceptances_saved);
free (best_number_accepted_saved);
free (number_invalid_generated_states);
free (current_generated_state->parameter);
free (last_saved_state->parameter);
free (best_generated_state->parameter);
free (current_generated_state);
free (last_saved_state);
free (best_generated_state);
#if ASA_QUEUE
free (save_queue_flag);
free (save_queue_cost);
free (save_queue_param);
#endif
#if MULTI_MIN
for (multi_index = 0; multi_index <= OPTIONS->Multi_Number; ++multi_index)
free (multi_params[multi_index]);
free (multi_params);
free (multi_sort);
free (multi_cost);
#endif
#if ASA_PARALLEL
for (index_parallel = 0; index_parallel < parallel_block_max;
++index_parallel) {
free (gener_block_state[index_parallel].parameter);
}
free (gener_block_state);
free (parallel_sort);
#endif
#if ASA_PIPE_FILE
fclose (ptr_asa_pipe);
#endif
free (initial_user_parameter_temp);
free (index_exit_v);
free (start_sequence);
free (index_parameter_generations);
free (current_user_parameter_temp);
free (temperature_scale_parameters);
if (recursive_asa_open == 0)
asa_open = FALSE;
return (final_cost);
}
/***********************************************************************
* asa_exit
* This procedures copies the best parameters and cost into
* final_cost and parameter_initial_final
***********************************************************************/
#if HAVE_ANSI
int
asa_exit (double (*user_cost_function)
(double *, double *, double *, double *, double *, ALLOC_INT *,
int *, int *, int *, USER_DEFINES *), double *final_cost,
double *parameter_initial_final, double *parameter_minimum,
double *parameter_maximum, double *tangents, double *curvature,
double *maximum_tangent, double *current_cost_temperature,
double *initial_user_parameter_temp,
double *current_user_parameter_temp,
double *accepted_to_generated_ratio,
ALLOC_INT * number_parameters, int *parameter_type,
int *valid_state_generated_flag, int *exit_status,
ALLOC_INT * index_exit_v, ALLOC_INT * start_sequence,
LONG_INT * number_accepted,
LONG_INT * best_number_accepted_saved,
LONG_INT * index_cost_acceptances, LONG_INT * number_generated,
LONG_INT * number_invalid_generated_states,
LONG_INT * index_parameter_generations,
LONG_INT * best_number_generated_saved,
STATE * current_generated_state, STATE * last_saved_state,
STATE * best_generated_state, FILE * ptr_asa_out,
USER_DEFINES * OPTIONS)
#else
int
asa_exit (user_cost_function,
final_cost,
parameter_initial_final,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
maximum_tangent,
current_cost_temperature,
initial_user_parameter_temp,
current_user_parameter_temp,
accepted_to_generated_ratio,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status,
index_exit_v,
start_sequence,
number_accepted,
best_number_accepted_saved,
index_cost_acceptances,
number_generated,
number_invalid_generated_states,
index_parameter_generations,
best_number_generated_saved,
current_generated_state,
last_saved_state, best_generated_state, ptr_asa_out, OPTIONS)
double (*user_cost_function) ();
double *final_cost;
double *parameter_initial_final;
double *parameter_minimum;
double *parameter_maximum;
double *tangents;
double *curvature;
double *maximum_tangent;
double *current_cost_temperature;
double *initial_user_parameter_temp;
double *current_user_parameter_temp;
double *accepted_to_generated_ratio;
ALLOC_INT *number_parameters;
int *parameter_type;
int *valid_state_generated_flag;
int *exit_status;
ALLOC_INT *index_exit_v;
ALLOC_INT *start_sequence;
LONG_INT *number_accepted;
LONG_INT *best_number_accepted_saved;
LONG_INT *index_cost_acceptances;
LONG_INT *number_generated;
LONG_INT *number_invalid_generated_states;
LONG_INT *index_parameter_generations;
LONG_INT *best_number_generated_saved;
STATE *current_generated_state;
STATE *last_saved_state;
STATE *best_generated_state;
FILE *ptr_asa_out;
USER_DEFINES *OPTIONS;
#endif
{
ALLOC_INT index_v; /* iteration index */
int curvatureFlag;
int exit_exit_status, tmp_locate;
#if MULTI_MIN
int multi_index;
#endif
tmp_locate = OPTIONS->Locate_Cost;
/* return final function minimum and associated parameters */
*final_cost = best_generated_state->cost;
VFOR (index_v) {
parameter_initial_final[index_v] =
best_generated_state->parameter[index_v];
}
OPTIONS->N_Accepted = *best_number_accepted_saved;
OPTIONS->N_Generated = *best_number_generated_saved;
#if MULTI_MIN
for (multi_index = 0; multi_index < OPTIONS->Multi_Number; ++multi_index) {
best_generated_state->cost = OPTIONS->Multi_Cost[multi_index];
VFOR (index_v) {
best_generated_state->parameter[index_v] =
OPTIONS->Multi_Params[multi_index][index_v];
}
#if ASA_PRINT
fprintf (ptr_asa_out, "\n\t\t multi_index = %d\n", multi_index);
#endif /* ASA_PRINT */
#endif /* MULTI_MIN */
if (*exit_status != TOO_MANY_INVALID_STATES
&& *exit_status != IMMEDIATE_EXIT
&& *exit_status != INVALID_USER_INPUT
&& *exit_status != INVALID_COST_FUNCTION
&& *exit_status != INVALID_COST_FUNCTION_DERIV) {
if (OPTIONS->Curvature_0 != TRUE)
OPTIONS->Locate_Cost = 5; /* calc curvatures while exiting asa */
/* calculate curvatures and tangents at best point */
curvatureFlag = TRUE;
cost_derivatives (user_cost_function,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
maximum_tangent,
number_parameters,
parameter_type,
&exit_exit_status,
&curvatureFlag,
valid_state_generated_flag,
number_invalid_generated_states,
current_generated_state,
best_generated_state, ptr_asa_out, OPTIONS);
}
#if ASA_PRINT
if (exit_exit_status == INVALID_COST_FUNCTION_DERIV)
fprintf (ptr_asa_out, "\n\n in asa_exit: INVALID_COST_FUNCTION_DERIV");
if (*exit_status != INVALID_USER_INPUT
&& *exit_status != INVALID_COST_FUNCTION
&& *exit_status != INVALID_COST_FUNCTION_DERIV)
print_state (parameter_minimum,
parameter_maximum,
tangents,
curvature,
current_cost_temperature,
current_user_parameter_temp,
accepted_to_generated_ratio,
number_parameters,
&curvatureFlag,
number_accepted,
index_cost_acceptances,
number_generated,
number_invalid_generated_states,
last_saved_state,
best_generated_state, ptr_asa_out, OPTIONS);
#endif /* ASA_PRINT */
#if MULTI_MIN
}
best_generated_state->cost = OPTIONS->Multi_Cost[0];
VFOR (index_v) {
best_generated_state->parameter[index_v] =
OPTIONS->Multi_Params[0][index_v];
}
#endif /* MULTI_MIN */
#if ASA_PRINT
switch (*exit_status) {
case NORMAL_EXIT:
fprintf (ptr_asa_out,
"\n\n NORMAL_EXIT exit_status = %d\n", *exit_status);
break;
case P_TEMP_TOO_SMALL:
fprintf (ptr_asa_out,
"\n\n P_TEMP_TOO_SMALL exit_status = %d\n", *exit_status);
fprintf (ptr_asa_out,
#if INT_ALLOC
"current_user_parameter_temp[%d] too small = %*.*g\n",
#else
#if INT_LONG
"current_user_parameter_temp[%ld] too small = %*.*g\n",
#else
"current_user_parameter_temp[%d] too small = %*.*g\n",
#endif
#endif
*index_exit_v,
G_FIELD, G_PRECISION,
current_user_parameter_temp[*index_exit_v]);
break;
case C_TEMP_TOO_SMALL:
fprintf (ptr_asa_out,
"\n\n C_TEMP_TOO_SMALL exit_status = %d\n", *exit_status);
fprintf (ptr_asa_out,
"*current_cost_temperature too small = %*.*g\n",
G_FIELD, G_PRECISION, *current_cost_temperature);
break;
case COST_REPEATING:
fprintf (ptr_asa_out,
"\n\n COST_REPEATING exit_status = %d\n", *exit_status);
break;
case TOO_MANY_INVALID_STATES:
fprintf (ptr_asa_out,
"\n\n TOO_MANY_INVALID_STATES exit_status = %d\n",
*exit_status);
break;
case IMMEDIATE_EXIT:
fprintf (ptr_asa_out,
"\n\n IMMEDIATE_EXIT exit_status = %d\n", *exit_status);
break;
case INVALID_USER_INPUT:
fprintf (ptr_asa_out,
"\n\n INVALID_USER_INPUT exit_status = %d\n", *exit_status);
break;
case INVALID_COST_FUNCTION:
fprintf (ptr_asa_out,
"\n\n INVALID_COST_FUNCTION exit_status = %d\n", *exit_status);
break;
case INVALID_COST_FUNCTION_DERIV:
fprintf (ptr_asa_out,
"\n\n INVALID_COST_FUNCTION_DERIV exit_status = %d\n",
*exit_status);
break;
default:
fprintf (ptr_asa_out, "\n\n ERR: no exit code available = %d\n",
*exit_status);
}
switch (OPTIONS->Locate_Cost) {
case 0:
fprintf (ptr_asa_out,
" Locate_Cost = %d, initial cost temperature\n",
OPTIONS->Locate_Cost);
break;
case 1:
fprintf (ptr_asa_out,
" Locate_Cost = %d, initial cost value\n", OPTIONS->Locate_Cost);
break;
case 2:
fprintf (ptr_asa_out,
" Locate_Cost = %d, new generated state\n",
OPTIONS->Locate_Cost);
break;
case 12:
fprintf (ptr_asa_out,
" Locate_Cost = %d, new generated state just after a new best state\n",
OPTIONS->Locate_Cost);
break;
case 3:
fprintf (ptr_asa_out,
" Locate_Cost = %d, cost derivatives, reannealing parameters\n",
OPTIONS->Locate_Cost);
break;
case 4:
fprintf (ptr_asa_out,
" Locate_Cost = %d, reannealing cost temperature\n",
OPTIONS->Locate_Cost);
break;
case 5:
fprintf (ptr_asa_out,
" Locate_Cost = %d, calculating curvatures while exiting asa ()\n",
OPTIONS->Locate_Cost);
break;
case -1:
fprintf (ptr_asa_out,
" Locate_Cost = %d, exited main asa () loop by user-defined OPTIONS\n",
OPTIONS->Locate_Cost);
break;
default:
fprintf (ptr_asa_out,
" Locate_Cost = %d, no index available for Locate_Cost\n",
OPTIONS->Locate_Cost);
}
if (*exit_status != INVALID_USER_INPUT
&& *exit_status != INVALID_COST_FUNCTION
&& *exit_status != INVALID_COST_FUNCTION_DERIV) {
fprintf (ptr_asa_out,
"final_cost = best_generated_state->cost = %-*.*g\n",
G_FIELD, G_PRECISION, *final_cost);
#if INT_LONG
fprintf (ptr_asa_out,
"*number_accepted at best_generated_state->cost = %ld\n",
*best_number_accepted_saved);
fprintf (ptr_asa_out,
"*number_generated at best_generated_state->cost = %ld\n",
*best_number_generated_saved);
#else
fprintf (ptr_asa_out,
"*number_accepted at best_generated_state->cost = %d\n",
*best_number_accepted_saved);
fprintf (ptr_asa_out,
"*number_generated at best_generated_state->cost = %d\n",
*best_number_generated_saved);
#endif
}
#endif
#if ASA_TEMPLATE_SELFOPT
if (OPTIONS->Asa_Data_Dbl[0] > (double) MIN_DOUBLE)
OPTIONS->Asa_Data_Dbl[1] = (double) (*best_number_generated_saved);
#endif
/* reset OPTIONS->Sequential_Parameters */
OPTIONS->Sequential_Parameters = *start_sequence;
#if ASA_PRINT
#if TIME_CALC
/* print ending time */
print_time ("asa_end", ptr_asa_out);
#endif
fprintf (ptr_asa_out, "\n\n\n");
fflush (ptr_asa_out);
ptr_asa_out != stdout && fclose (ptr_asa_out);
#endif
return (0);
}
/***********************************************************************
* generate_new_state
* Generates a valid new state from the old state
***********************************************************************/
#if HAVE_ANSI
void
generate_new_state (double (*user_random_generator) (LONG_INT *),
LONG_INT * seed,
double *parameter_minimum,
double *parameter_maximum,
double *current_user_parameter_temp,
#if USER_GENERATING_FUNCTION
double *initial_user_parameter_temp,
double *temperature_scale_parameters,
#endif
ALLOC_INT * number_parameters,
int *parameter_type,
STATE * current_generated_state,
STATE * last_saved_state, USER_DEFINES * OPTIONS)
#else
void
generate_new_state (user_random_generator,
seed,
parameter_minimum,
parameter_maximum, current_user_parameter_temp,
#if USER_GENERATING_FUNCTION
initial_user_parameter_temp, temperature_scale_parameters,
#endif
number_parameters,
parameter_type,
current_generated_state, last_saved_state, OPTIONS)
double (*user_random_generator) ();
LONG_INT *seed;
double *parameter_minimum;
double *parameter_maximum;
double *current_user_parameter_temp;
#if USER_GENERATING_FUNCTION
double *initial_user_parameter_temp;
double *temperature_scale_parameters;
#endif
ALLOC_INT *number_parameters;
int *parameter_type;
STATE *current_generated_state;
STATE *last_saved_state;
USER_DEFINES *OPTIONS;
#endif
{
ALLOC_INT index_v;
double x;
double parameter_v, min_parameter_v, max_parameter_v, temperature_v,
parameter_range_v;
#if USER_GENERATING_FUNCTION
double init_param_temp_v;
double temp_scale_params_v;
#endif
#if ASA_RESOLUTION
double xres, xint, xminus, xplus, dx, dxminus, dxplus;
#endif
/* generate a new value for each parameter */
VFOR (index_v) {
if (OPTIONS->Sequential_Parameters >= -1) {
++OPTIONS->Sequential_Parameters;
if (OPTIONS->Sequential_Parameters == *number_parameters)
OPTIONS->Sequential_Parameters = 0;
index_v = OPTIONS->Sequential_Parameters;
}
min_parameter_v = parameter_minimum[index_v];
max_parameter_v = parameter_maximum[index_v];
parameter_range_v = max_parameter_v - min_parameter_v;
/* ignore parameters that have too small a range */
if (fabs (parameter_range_v) < (double) EPS_DOUBLE)
continue;
temperature_v = current_user_parameter_temp[index_v];
#if USER_GENERATING_FUNCTION
init_param_temp_v = initial_user_parameter_temp[index_v];
temp_scale_params_v = temperature_scale_parameters[index_v];
#endif
parameter_v = last_saved_state->parameter[index_v];
/* Handle discrete parameters. */
#if ASA_RESOLUTION
xres = OPTIONS->Coarse_Resolution[index_v];
if (xres > EPS_DOUBLE) {
min_parameter_v -= (xres / TWO);
max_parameter_v += (xres / TWO);
parameter_range_v = max_parameter_v - min_parameter_v;
}
#endif /* ASA_RESOLUTION */
if (INTEGER_PARAMETER (index_v)) {
#if ASA_RESOLUTION
if (xres > EPS_DOUBLE) {
;
} else {
#endif /* ASA_RESOLUTION */
min_parameter_v -= HALF;
max_parameter_v += HALF;
parameter_range_v = max_parameter_v - min_parameter_v;
}
#if ASA_RESOLUTION
}
#endif
/* generate a new state x within the parameter bounds */
for (;;) {
#if USER_GENERATING_FUNCTION
x = OPTIONS->Generating_Distrib (seed,
number_parameters,
index_v,
temperature_v,
init_param_temp_v,
temp_scale_params_v,
parameter_v,
parameter_range_v,
last_saved_state->parameter, OPTIONS);
#else
x = parameter_v
+ generate_asa_state (user_random_generator, seed, &temperature_v)
* parameter_range_v;
#endif /* USER_GENERATING_FUNCTION */
#if ASA_RESOLUTION
if (xres > EPS_DOUBLE) {
xint = xres * (double) ((LONG_INT) (x / xres));
xplus = xint + xres;
xminus = xint - xres;
dx = fabs (xint - x);
dxminus = fabs (xminus - x);
dxplus = fabs (xplus - x);
if (dx < dxminus && dx < dxplus)
x = xint;
else if (dxminus < dxplus)
x = xminus;
else
x = xplus;
}
#endif /* ASA_RESOLUTION */
/* exit the loop if within its valid parameter range */
if (x <= max_parameter_v - (double) EPS_DOUBLE
&& x >= min_parameter_v + (double) EPS_DOUBLE)
break;
}
/* Handle discrete parameters.
You might have to check rounding on your machine. */
if (INTEGER_PARAMETER (index_v)) {
#if ASA_RESOLUTION
if (xres > EPS_DOUBLE) {
;
} else {
#endif /* ASA_RESOLUTION */
if (x < min_parameter_v + HALF)
x = min_parameter_v + HALF + (double) EPS_DOUBLE;
if (x > max_parameter_v - HALF)
x = max_parameter_v - HALF + (double) EPS_DOUBLE;
if (x + HALF > ZERO) {
x = (double) ((LONG_INT) (x + HALF));
} else {
x = (double) ((LONG_INT) (x - HALF));
}
if (x > parameter_maximum[index_v])
x = parameter_maximum[index_v];
if (x < parameter_minimum[index_v])
x = parameter_minimum[index_v];
}
#if ASA_RESOLUTION
}
if (xres > EPS_DOUBLE) {
if (x < min_parameter_v + xres / TWO)
x = min_parameter_v + xres / TWO + (double) EPS_DOUBLE;
if (x > max_parameter_v - xres / TWO)
x = max_parameter_v - xres / TWO + (double) EPS_DOUBLE;
if (x > parameter_maximum[index_v])
x = parameter_maximum[index_v];
if (x < parameter_minimum[index_v])
x = parameter_minimum[index_v];
}
#endif /* ASA_RESOLUTION */
/* save the newly generated value */
current_generated_state->parameter[index_v] = x;
if (OPTIONS->Sequential_Parameters >= 0)
break;
}
}
/***********************************************************************
* generate_asa_state
* This function generates a single value according to the
* ASA generating function and the passed temperature
***********************************************************************/
#if HAVE_ANSI
double
generate_asa_state (double (*user_random_generator) (LONG_INT *),
LONG_INT * seed, double *temp)
#else
double
generate_asa_state (user_random_generator, seed, temp)
double (*user_random_generator) ();
LONG_INT *seed;
double *temp;
#endif
{
double x, y, z;
x = (*user_random_generator) (seed);
y = x < HALF ? -ONE : ONE;
z = y * *temp * (F_POW ((ONE + ONE / *temp), fabs (TWO * x - ONE)) - ONE);
return (z);
}
/***********************************************************************
* accept_new_state
* This procedure accepts or rejects a newly generated state,
* depending on whether the difference between new and old
* cost functions passes a statistical test. If accepted,
* the current state is updated.
***********************************************************************/
#if HAVE_ANSI
void
accept_new_state (double (*user_random_generator) (LONG_INT *),
LONG_INT * seed,
double *parameter_minimum,
double *parameter_maximum, double *current_cost_temperature,
#if ASA_SAMPLE
double *current_user_parameter_temp,
#endif
ALLOC_INT * number_parameters,
LONG_INT * recent_number_acceptances,
LONG_INT * number_accepted,
LONG_INT * index_cost_acceptances,
LONG_INT * number_acceptances_saved,
LONG_INT * recent_number_generated,
LONG_INT * number_generated,
LONG_INT * index_parameter_generations,
STATE * current_generated_state, STATE * last_saved_state,
#if ASA_SAMPLE
FILE * ptr_asa_out,
#endif
USER_DEFINES * OPTIONS)
#else
void
accept_new_state (user_random_generator,
seed,
parameter_minimum,
parameter_maximum, current_cost_temperature,
#if ASA_SAMPLE
current_user_parameter_temp,
#endif
number_parameters,
recent_number_acceptances,
number_accepted,
index_cost_acceptances,
number_acceptances_saved,
recent_number_generated,
number_generated,
index_parameter_generations,
current_generated_state, last_saved_state,
#if ASA_SAMPLE
ptr_asa_out,
#endif
OPTIONS)
double (*user_random_generator) ();
LONG_INT *seed;
double *parameter_minimum;
double *parameter_maximum;
double *current_cost_temperature;
#if ASA_SAMPLE
double *current_user_parameter_temp;
#endif
ALLOC_INT *number_parameters;
LONG_INT *recent_number_acceptances;
LONG_INT *number_accepted;
LONG_INT *index_cost_acceptances;
LONG_INT *number_acceptances_saved;
LONG_INT *recent_number_generated;
LONG_INT *number_generated;
LONG_INT *index_parameter_generations;
STATE *current_generated_state;
STATE *last_saved_state;
#if ASA_SAMPLE
FILE *ptr_asa_out;
#endif
USER_DEFINES *OPTIONS;
#endif
{
#if USER_ACCEPTANCE_TEST
#else
double delta_cost;
#if USER_ACCEPT_ASYMP_EXP
double q;
#endif
#endif
double prob_test, unif_test;
double curr_cost_temp;
ALLOC_INT index_v;
#if ASA_SAMPLE
LONG_INT active_params;
double weight_param_ind, weight_aver, range;
#endif
/* update accepted and generated count */
++*number_acceptances_saved;
++*recent_number_generated;
++*number_generated;
OPTIONS->N_Generated = *number_generated;
/* increment the parameter index generation for each parameter */
if (OPTIONS->Sequential_Parameters >= 0) {
/* ignore parameters with too small a range */
if (!PARAMETER_RANGE_TOO_SMALL (OPTIONS->Sequential_Parameters))
++index_parameter_generations[OPTIONS->Sequential_Parameters];
} else {
VFOR (index_v) {
if (!PARAMETER_RANGE_TOO_SMALL (index_v))
++index_parameter_generations[index_v];
}
}
/* effective cost function for testing acceptance criteria,
calculate the cost difference and divide by the temperature */
curr_cost_temp = *current_cost_temperature;
#if USER_ACCEPTANCE_TEST
if (OPTIONS->Cost_Acceptance_Flag == TRUE) {
if (OPTIONS->User_Acceptance_Flag == TRUE) {
unif_test = ZERO;
OPTIONS->User_Acceptance_Flag = FALSE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
} else {
unif_test = ONE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
}
} else {
OPTIONS->Acceptance_Test (current_generated_state->cost,
parameter_minimum,
parameter_maximum, *number_parameters, OPTIONS);
if (OPTIONS->User_Acceptance_Flag == TRUE) {
unif_test = ZERO;
OPTIONS->User_Acceptance_Flag = FALSE;
} else {
unif_test = ONE;
}
}
prob_test = OPTIONS->Prob_Bias;
#else /* USER_ACCEPTANCE_TEST */
#if USER_COST_SCHEDULE
curr_cost_temp =
(OPTIONS->Cost_Schedule (*current_cost_temperature, OPTIONS)
+ (double) EPS_DOUBLE);
#endif
delta_cost = (current_generated_state->cost - last_saved_state->cost)
/ (curr_cost_temp + (double) EPS_DOUBLE);
#if USER_ACCEPT_ASYMP_EXP
q = OPTIONS->Asymp_Exp_Param;
if (fabs (ONE - q) < (double) EPS_DOUBLE)
prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));
else if ((ONE - (ONE - q) * delta_cost) < (double) EPS_DOUBLE)
prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));
else
prob_test = MIN (ONE, F_POW ((ONE - (ONE - q) * delta_cost),
(ONE / (ONE - q))));
#else /* USER_ACCEPT_ASYMP_EXP */
#if USER_ACCEPT_THRESHOLD /* USER_ACCEPT_THRESHOLD */
prob_test = delta_cost <= 1.0 ? 1.0 : 0.0;
#else /* Metropolis */
prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));
#endif /* USER_ACCEPT_THRESHOLD */
#endif /* USER_ACCEPT_ASYMP_EXP */
unif_test = (*user_random_generator) (seed);
#endif /* USER_ACCEPTANCE_TEST */
#if ASA_SAMPLE
active_params = 0;
weight_aver = ZERO;
VFOR (index_v) {
/* ignore parameters with too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
++active_params;
range = parameter_maximum[index_v] - parameter_minimum[index_v];
weight_param_ind = TWO * (fabs ((last_saved_state->parameter[index_v]
-
current_generated_state->
parameter[index_v]) / range)
+ current_user_parameter_temp[index_v])
* F_LOG (ONE + ONE / current_user_parameter_temp[index_v]);
weight_aver += weight_param_ind;
OPTIONS->Bias_Generated[index_v] = ONE / weight_param_ind;
}
weight_aver /= (double) active_params;
OPTIONS->Average_Weights = weight_aver;
if (prob_test >= unif_test) {
OPTIONS->Bias_Acceptance = prob_test;
} else {
OPTIONS->Bias_Acceptance = ONE - prob_test;
}
#if ASA_PRINT
if (OPTIONS->Limit_Weights < OPTIONS->Average_Weights) {
fprintf (ptr_asa_out, ":SAMPLE#\n");
if (prob_test >= unif_test) {
fprintf (ptr_asa_out,
#if INT_LONG
":SAMPLE+ %10ld %*.*g %*.*g %*.*g %*.*g\n",
#else
":SAMPLE+ %10d %*.*g %*.*g %*.*g\n",
#endif
OPTIONS->N_Accepted,
G_FIELD, G_PRECISION, current_generated_state->cost,
G_FIELD, G_PRECISION, *current_cost_temperature,
G_FIELD, G_PRECISION, OPTIONS->Bias_Acceptance,
G_FIELD, G_PRECISION, OPTIONS->Average_Weights);
VFOR (index_v) {
/* ignore parameters with too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
range = parameter_maximum[index_v] - parameter_minimum[index_v];
fprintf (ptr_asa_out,
#if INT_ALLOC
":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",
#else
#if INT_LONG
":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",
#else
":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION,
current_generated_state->parameter[index_v], G_FIELD,
G_PRECISION, current_user_parameter_temp[index_v],
G_FIELD, G_PRECISION, OPTIONS->Bias_Generated[index_v],
G_FIELD, G_PRECISION, range);
}
} else {
fprintf (ptr_asa_out,
#if INT_LONG
":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",
#else
":SAMPLE %11d %*.*g %*.*g %*.*g\n",
#endif
OPTIONS->N_Accepted,
G_FIELD, G_PRECISION, last_saved_state->cost,
G_FIELD, G_PRECISION, *current_cost_temperature,
G_FIELD, G_PRECISION, OPTIONS->Bias_Acceptance,
G_FIELD, G_PRECISION, OPTIONS->Average_Weights);
VFOR (index_v) {
/* ignore parameters with too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
range = parameter_maximum[index_v] - parameter_minimum[index_v];
fprintf (ptr_asa_out,
#if INT_ALLOC
":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",
#else
#if INT_LONG
":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",
#else
":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION,
last_saved_state->parameter[index_v], G_FIELD,
G_PRECISION, current_user_parameter_temp[index_v],
G_FIELD, G_PRECISION, OPTIONS->Bias_Generated[index_v],
G_FIELD, G_PRECISION, range);
}
}
}
#endif
#endif /* ASA_SAMPLE */
/* accept/reject the new state */
if (prob_test >= unif_test) {
/* copy current state to the last saved state */
last_saved_state->cost = current_generated_state->cost;
VFOR (index_v) {
/* ignore parameters with too small a range */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
last_saved_state->parameter[index_v] =
current_generated_state->parameter[index_v];
}
/* update acceptance counts */
++*recent_number_acceptances;
++*number_accepted;
++*index_cost_acceptances;
*number_acceptances_saved = *number_accepted;
OPTIONS->N_Accepted = *number_accepted;
}
}
/***********************************************************************
* reanneal
* Readjust temperatures of generating and acceptance functions
***********************************************************************/
#if HAVE_ANSI
void
reanneal (double *parameter_minimum,
double *parameter_maximum,
double *tangents,
double *maximum_tangent,
double *current_cost_temperature,
double *initial_cost_temperature,
double *temperature_scale_cost,
double *current_user_parameter_temp,
double *initial_user_parameter_temp,
double *temperature_scale_parameters,
ALLOC_INT * number_parameters,
int *parameter_type,
LONG_INT * index_cost_acceptances,
LONG_INT * index_parameter_generations,
STATE * last_saved_state,
STATE * best_generated_state, USER_DEFINES * OPTIONS)
#else
void
reanneal (parameter_minimum,
parameter_maximum,
tangents,
maximum_tangent,
current_cost_temperature,
initial_cost_temperature,
temperature_scale_cost,
current_user_parameter_temp,
initial_user_parameter_temp,
temperature_scale_parameters,
number_parameters,
parameter_type,
index_cost_acceptances,
index_parameter_generations,
last_saved_state, best_generated_state, OPTIONS)
double *parameter_minimum;
double *parameter_maximum;
double *tangents;
double *maximum_tangent;
double *current_cost_temperature;
double *initial_cost_temperature;
double *temperature_scale_cost;
double *current_user_parameter_temp;
double *initial_user_parameter_temp;
double *temperature_scale_parameters;
ALLOC_INT *number_parameters;
int *parameter_type;
LONG_INT *index_cost_acceptances;
LONG_INT *index_parameter_generations;
STATE *last_saved_state;
STATE *best_generated_state;
USER_DEFINES *OPTIONS;
#endif
{
ALLOC_INT index_v;
int cost_test;
double tmp_var_db3;
double new_temperature;
double log_new_temperature_ratio;
double log_init_cur_temp_ratio;
double temperature_rescale_power;
double cost_best, cost_last;
double tmp_dbl, tmp_dbl1;
double xnumber_parameters[1];
cost_test = cost_function_test (last_saved_state->cost,
last_saved_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters);
if (OPTIONS->Reanneal_Parameters == TRUE) {
VFOR (index_v) {
if (NO_REANNEAL (index_v))
continue;
/* use the temp double to prevent overflow */
tmp_dbl = (double) index_parameter_generations[index_v];
/* skip parameters with too small range or integer parameters */
if (OPTIONS->Include_Integer_Parameters == TRUE) {
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
} else {
if (PARAMETER_RANGE_TOO_SMALL (index_v) ||
INTEGER_PARAMETER (index_v))
continue;
}
/* ignore parameters with too small tangents */
if (fabs (tangents[index_v]) < (double) EPS_DOUBLE)
continue;
/* reset the index of parameter generations appropriately */
#if USER_REANNEAL_PARAMETERS
new_temperature =
fabs (OPTIONS->
Reanneal_Params_Function (current_user_parameter_temp
[index_v], tangents[index_v],
*maximum_tangent, OPTIONS));
#else
new_temperature =
fabs (FUNCTION_REANNEAL_PARAMS
(current_user_parameter_temp[index_v], tangents[index_v],
*maximum_tangent));
#endif
if (new_temperature < initial_user_parameter_temp[index_v]) {
log_init_cur_temp_ratio =
fabs (F_LOG (((double) EPS_DOUBLE
+ initial_user_parameter_temp[index_v])
/ ((double) EPS_DOUBLE + new_temperature)));
tmp_dbl = (double) EPS_DOUBLE
+ F_POW (log_init_cur_temp_ratio
/ temperature_scale_parameters[index_v],
*xnumber_parameters
#if QUENCH_PARAMETERS
/ OPTIONS->User_Quench_Param_Scale[index_v]);
#else
);
#endif
} else {
tmp_dbl = ONE;
}
/* Reset index_parameter_generations if index reset too large,
and also reset the initial_user_parameter_temp, to achieve
the same new temperature. */
while (tmp_dbl > ((double) MAXIMUM_REANNEAL_INDEX)) {
log_new_temperature_ratio =
-temperature_scale_parameters[index_v] * F_POW (tmp_dbl,
#if QUENCH_PARAMETERS
OPTIONS->
User_Quench_Param_Scale
[index_v]
#else
ONE
#endif
/
*xnumber_parameters);
log_new_temperature_ratio =
EXPONENT_CHECK (log_new_temperature_ratio);
new_temperature =
initial_user_parameter_temp[index_v] *
F_EXP (log_new_temperature_ratio);
tmp_dbl /= (double) REANNEAL_SCALE;
temperature_rescale_power = ONE / F_POW ((double) REANNEAL_SCALE,
#if QUENCH_PARAMETERS
OPTIONS->
User_Quench_Param_Scale
[index_v]
#else
ONE
#endif
/ *xnumber_parameters);
initial_user_parameter_temp[index_v] =
new_temperature * F_POW (initial_user_parameter_temp[index_v] /
new_temperature,
temperature_rescale_power);
}
/* restore from temporary double */
index_parameter_generations[index_v] = (LONG_INT) tmp_dbl;
}
}
if (OPTIONS->Reanneal_Cost == 0) {
;
} else if (OPTIONS->Reanneal_Cost < -1) {
*index_cost_acceptances = 1;
} else {
/* reanneal : Reset the current cost temp and rescale the
index of cost acceptances. */
cost_best = best_generated_state->cost;
cost_last = last_saved_state->cost;
#if USER_REANNEAL_COST
cost_test = OPTIONS->Reanneal_Cost_Function (&cost_best,
&cost_last,
initial_cost_temperature,
current_cost_temperature,
OPTIONS);
tmp_dbl1 = *current_cost_temperature;
#else
cost_test = TRUE;
if (OPTIONS->Reanneal_Cost == 1) {
/* (re)set the initial cost_temperature */
tmp_dbl = MAX (fabs (cost_last), fabs (cost_best));
tmp_dbl = MAX (tmp_dbl, fabs (cost_best - cost_last));
tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);
*initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);
}
tmp_dbl = (double) *index_cost_acceptances;
tmp_dbl1 = MAX (fabs (cost_last - cost_best), *current_cost_temperature);
tmp_dbl1 = MAX ((double) EPS_DOUBLE, tmp_dbl1);
tmp_dbl1 = MIN (tmp_dbl1, *initial_cost_temperature);
#endif /* USER_REANNEAL_COST */
if (cost_test == TRUE && (*current_cost_temperature > tmp_dbl1)) {
tmp_var_db3 =
fabs (F_LOG (((double) EPS_DOUBLE + *initial_cost_temperature) /
(tmp_dbl1)));
tmp_dbl = (double) EPS_DOUBLE + F_POW (tmp_var_db3
/ *temperature_scale_cost,
*xnumber_parameters
#if QUENCH_COST
/
OPTIONS->
User_Quench_Cost_Scale[0]);
#else
);
#endif
} else {
log_init_cur_temp_ratio =
fabs (F_LOG (((double) EPS_DOUBLE + *initial_cost_temperature) /
((double) EPS_DOUBLE + *current_cost_temperature)));
tmp_dbl = (double) EPS_DOUBLE
+ F_POW (log_init_cur_temp_ratio
/ *temperature_scale_cost, *xnumber_parameters
#if QUENCH_COST
/ OPTIONS->User_Quench_Cost_Scale[0]
#else
#endif
);
}
/* reset index_cost_temperature if index reset too large */
while (tmp_dbl > ((double) MAXIMUM_REANNEAL_INDEX)) {
log_new_temperature_ratio = -*temperature_scale_cost * F_POW (tmp_dbl,
#if QUENCH_COST
OPTIONS->
User_Quench_Cost_Scale
[0]
#else
ONE
#endif
/
*xnumber_parameters);
log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);
new_temperature =
*initial_cost_temperature * F_EXP (log_new_temperature_ratio);
tmp_dbl /= (double) REANNEAL_SCALE;
temperature_rescale_power = ONE / F_POW ((double) REANNEAL_SCALE,
#if QUENCH_COST
OPTIONS->
User_Quench_Cost_Scale[0]
#else
ONE
#endif
/ *xnumber_parameters);
*initial_cost_temperature =
new_temperature * F_POW (*initial_cost_temperature /
new_temperature, temperature_rescale_power);
}
*index_cost_acceptances = (LONG_INT) tmp_dbl;
#if USER_ACCEPTANCE_TEST
OPTIONS->Cost_Temp_Init = *initial_cost_temperature;
#endif
}
}
/***********************************************************************
* cost_derivatives
* This procedure calculates the derivatives of the cost function
* with respect to its parameters. The first derivatives are
* used as a sensitivity measure for reannealing. The second
* derivatives are calculated only if *curvature_flag=TRUE;
* these are a measure of the covariance of the fit when a
* minimum is found.
***********************************************************************/
/* Calculate the numerical derivatives of the best
generated state found so far */
/* In this implementation of ASA, no checks are made for
*valid_state_generated_flag=FALSE for differential neighbors
to the current best state. */
/* Assuming no information is given about the metric of the parameter
space, use simple Cartesian space to calculate curvatures. */
#if HAVE_ANSI
void
cost_derivatives (double (*user_cost_function)
(double *, double *, double *, double *, double *,
ALLOC_INT *, int *, int *, int *, USER_DEFINES *),
double *parameter_minimum, double *parameter_maximum,
double *tangents, double *curvature,
double *maximum_tangent, ALLOC_INT * number_parameters,
int *parameter_type, int *exit_status,
int *curvature_flag, int *valid_state_generated_flag,
LONG_INT * number_invalid_generated_states,
STATE * current_generated_state,
STATE * best_generated_state, FILE * ptr_asa_out,
USER_DEFINES * OPTIONS)
#else
void
cost_derivatives (user_cost_function,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
maximum_tangent,
number_parameters,
parameter_type,
exit_status,
curvature_flag,
valid_state_generated_flag,
number_invalid_generated_states,
current_generated_state,
best_generated_state, ptr_asa_out, OPTIONS)
double (*user_cost_function) ();
double *parameter_minimum;
double *parameter_maximum;
double *tangents;
double *curvature;
double *maximum_tangent;
ALLOC_INT *number_parameters;
int *parameter_type;
int *exit_status;
int *curvature_flag;
int *valid_state_generated_flag;
LONG_INT *number_invalid_generated_states;
STATE *current_generated_state;
STATE *best_generated_state;
FILE *ptr_asa_out;
USER_DEFINES *OPTIONS;
#endif
{
ALLOC_INT index_v, index_vv, index_v_vv, index_vv_v;
LONG_INT saved_num_invalid_gen_states;
#if ASA_PRINT
LONG_INT tmp_saved;
#endif
double parameter_v, parameter_vv, parameter_v_offset, parameter_vv_offset;
double recent_best_cost;
double new_cost_state_1, new_cost_state_2, new_cost_state_3;
double delta_parameter_v, delta_parameter_vv;
int immediate_flag;
double xnumber_parameters[1];
if (OPTIONS->Curvature_0 == TRUE)
*curvature_flag = FALSE;
if (OPTIONS->Curvature_0 == -1)
*curvature_flag = TRUE;
/* save Immediate_Exit flag */
immediate_flag = OPTIONS->Immediate_Exit;
/* save the best cost */
recent_best_cost = best_generated_state->cost;
/* copy the best state into the current state */
VFOR (index_v) {
/* ignore parameters with too small ranges */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
current_generated_state->parameter[index_v] =
best_generated_state->parameter[index_v];
}
saved_num_invalid_gen_states = (*number_invalid_generated_states);
/* set parameters (& possibly constraints) to best state */
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag, exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
if (OPTIONS->User_Tangents == TRUE) {
*valid_state_generated_flag = FALSE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag, exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
} else {
/* calculate tangents */
VFOR (index_v) {
if (NO_REANNEAL (index_v)) {
tangents[index_v] = ZERO;
continue;
}
/* skip parameters with too small range or integer parameters */
if (OPTIONS->Include_Integer_Parameters == TRUE) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
tangents[index_v] = ZERO;
continue;
}
} else {
if (PARAMETER_RANGE_TOO_SMALL (index_v) ||
INTEGER_PARAMETER (index_v)) {
tangents[index_v] = ZERO;
continue;
}
}
/* save the v_th parameter and delta_parameter */
parameter_v = best_generated_state->parameter[index_v];
#if DELTA_PARAMETERS
delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];
#else
delta_parameter_v = OPTIONS->Delta_X;
#endif
parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;
if (parameter_v_offset > parameter_maximum[index_v] ||
parameter_v_offset < parameter_minimum[index_v]) {
delta_parameter_v = -delta_parameter_v;
parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;
}
/* generate the first sample point */
current_generated_state->parameter[index_v] = parameter_v_offset;
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag, exit_status, OPTIONS);
if (cost_function_test
(current_generated_state->cost,
current_generated_state->parameter, parameter_minimum,
parameter_maximum, number_parameters, xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_1 = current_generated_state->cost;
/* restore the parameter state */
current_generated_state->parameter[index_v] = parameter_v;
/* calculate the numerical derivative */
tangents[index_v] = (new_cost_state_1 - recent_best_cost)
/ (delta_parameter_v * parameter_v + (double) EPS_DOUBLE);
}
}
/* find the maximum |tangent| from all tangents */
*maximum_tangent = 0;
VFOR (index_v) {
if (NO_REANNEAL (index_v))
continue;
/* ignore too small ranges and integer parameters types */
if (OPTIONS->Include_Integer_Parameters == TRUE) {
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
} else {
if (PARAMETER_RANGE_TOO_SMALL (index_v)
|| INTEGER_PARAMETER (index_v))
continue;
}
/* find the maximum |tangent| (from all tangents) */
if (fabs (tangents[index_v]) > *maximum_tangent) {
*maximum_tangent = fabs (tangents[index_v]);
}
}
if (*curvature_flag == TRUE || *curvature_flag == -1) {
/* calculate diagonal curvatures */
VFOR (index_v) {
if (NO_REANNEAL (index_v)) {
index_v_vv = ROW_COL_INDEX (index_v, index_v);
curvature[index_v_vv] = ZERO;
continue;
}
/* skip parameters with too small range or integer parameters */
if (OPTIONS->Include_Integer_Parameters == TRUE) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
index_v_vv = ROW_COL_INDEX (index_v, index_v);
curvature[index_v_vv] = ZERO;
continue;
}
} else {
if (PARAMETER_RANGE_TOO_SMALL (index_v) ||
INTEGER_PARAMETER (index_v)) {
index_v_vv = ROW_COL_INDEX (index_v, index_v);
curvature[index_v_vv] = ZERO;
continue;
}
}
/* save the v_th parameter and delta_parameter */
parameter_v = best_generated_state->parameter[index_v];
#if DELTA_PARAMETERS
delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];
#else
delta_parameter_v = OPTIONS->Delta_X;
#endif
if (parameter_v + delta_parameter_v * fabs (parameter_v)
> parameter_maximum[index_v]) {
/* generate the first sample point */
current_generated_state->parameter[index_v] =
parameter_v - TWO * delta_parameter_v * fabs (parameter_v);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_1 = current_generated_state->cost;
/* generate the second sample point */
current_generated_state->parameter[index_v] =
parameter_v - delta_parameter_v * fabs (parameter_v);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_2 = current_generated_state->cost;
/* restore the parameter state */
current_generated_state->parameter[index_v] = parameter_v;
/* index_v_vv: row index_v, column index_v */
index_v_vv = ROW_COL_INDEX (index_v, index_v);
/* calculate and store the curvature */
curvature[index_v_vv] =
(recent_best_cost - TWO * new_cost_state_2
+ new_cost_state_1) / (delta_parameter_v * delta_parameter_v
* parameter_v * parameter_v +
(double) EPS_DOUBLE);
} else if (parameter_v - delta_parameter_v * fabs (parameter_v)
< parameter_minimum[index_v]) {
/* generate the first sample point */
current_generated_state->parameter[index_v] =
parameter_v + TWO * delta_parameter_v * fabs (parameter_v);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_1 = current_generated_state->cost;
/* generate the second sample point */
current_generated_state->parameter[index_v] =
parameter_v + delta_parameter_v * fabs (parameter_v);
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_2 = current_generated_state->cost;
/* restore the parameter state */
current_generated_state->parameter[index_v] = parameter_v;
/* index_v_vv: row index_v, column index_v */
index_v_vv = ROW_COL_INDEX (index_v, index_v);
/* calculate and store the curvature */
curvature[index_v_vv] =
(recent_best_cost - TWO * new_cost_state_2
+ new_cost_state_1) / (delta_parameter_v * delta_parameter_v
* parameter_v * parameter_v +
(double) EPS_DOUBLE);
} else {
/* generate the first sample point */
parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;
current_generated_state->parameter[index_v] = parameter_v_offset;
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_1 = current_generated_state->cost;
/* generate the second sample point */
current_generated_state->parameter[index_v] =
(ONE - delta_parameter_v) * parameter_v;
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_2 = current_generated_state->cost;
/* restore the parameter state */
current_generated_state->parameter[index_v] = parameter_v;
/* index_v_vv: row index_v, column index_v */
index_v_vv = ROW_COL_INDEX (index_v, index_v);
/* calculate and store the curvature */
curvature[index_v_vv] =
(new_cost_state_2 - TWO * recent_best_cost
+ new_cost_state_1) / (delta_parameter_v * delta_parameter_v
* parameter_v * parameter_v +
(double) EPS_DOUBLE);
}
}
/* calculate off-diagonal curvatures */
VFOR (index_v) {
/* save the v_th parameter and delta_x */
parameter_v = current_generated_state->parameter[index_v];
#if DELTA_PARAMETERS
delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];
#else
delta_parameter_v = OPTIONS->Delta_X;
#endif
VFOR (index_vv) {
/* index_v_vv: row index_v, column index_vv */
index_v_vv = ROW_COL_INDEX (index_v, index_vv);
index_vv_v = ROW_COL_INDEX (index_vv, index_v);
if (NO_REANNEAL (index_vv) || NO_REANNEAL (index_v)) {
curvature[index_vv_v] = curvature[index_v_vv] = ZERO;
continue;
}
/* calculate only the upper diagonal */
if (index_v <= index_vv)
continue;
/* skip parms with too small range or integer parameters */
if (OPTIONS->Include_Integer_Parameters == TRUE) {
if (PARAMETER_RANGE_TOO_SMALL (index_v) ||
PARAMETER_RANGE_TOO_SMALL (index_vv)) {
curvature[index_vv_v] = curvature[index_v_vv] = ZERO;
continue;
}
} else {
if (INTEGER_PARAMETER (index_v) ||
INTEGER_PARAMETER (index_vv) ||
PARAMETER_RANGE_TOO_SMALL (index_v) ||
PARAMETER_RANGE_TOO_SMALL (index_vv)) {
curvature[index_vv_v] = curvature[index_v_vv] = ZERO;
continue;
}
}
/* save the vv_th parameter and delta_parameter */
parameter_vv = current_generated_state->parameter[index_vv];
#if DELTA_PARAMETERS
delta_parameter_vv = OPTIONS->User_Delta_Parameter[index_vv];
#else
delta_parameter_vv = OPTIONS->Delta_X;
#endif
/* generate first sample point */
parameter_v_offset = current_generated_state->parameter[index_v] =
(ONE + delta_parameter_v) * parameter_v;
parameter_vv_offset = current_generated_state->parameter[index_vv] =
(ONE + delta_parameter_vv) * parameter_vv;
if (parameter_v_offset > parameter_maximum[index_v] ||
parameter_v_offset < parameter_minimum[index_v]) {
delta_parameter_v = -delta_parameter_v;
current_generated_state->parameter[index_v] =
(ONE + delta_parameter_v) * parameter_v;
}
if (parameter_vv_offset > parameter_maximum[index_vv] ||
parameter_vv_offset < parameter_minimum[index_vv]) {
delta_parameter_vv = -delta_parameter_vv;
current_generated_state->parameter[index_vv] =
(ONE + delta_parameter_vv) * parameter_vv;
}
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_1 = current_generated_state->cost;
/* restore the v_th parameter */
current_generated_state->parameter[index_v] = parameter_v;
/* generate second sample point */
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_2 = current_generated_state->cost;
/* restore the vv_th parameter */
current_generated_state->parameter[index_vv] = parameter_vv;
/* generate third sample point */
current_generated_state->parameter[index_v] =
(ONE + delta_parameter_v) * parameter_v;
*valid_state_generated_flag = TRUE;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
current_generated_state->cost =
user_cost_function (current_generated_state->parameter,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, OPTIONS);
if (cost_function_test (current_generated_state->cost,
current_generated_state->parameter,
parameter_minimum,
parameter_maximum, number_parameters,
xnumber_parameters) == 0) {
*exit_status = INVALID_COST_FUNCTION_DERIV;
return;
}
if (*valid_state_generated_flag == FALSE)
++(*number_invalid_generated_states);
new_cost_state_3 = current_generated_state->cost;
/* restore the v_th parameter */
current_generated_state->parameter[index_v] = parameter_v;
/* calculate and store the curvature */
curvature[index_vv_v] = curvature[index_v_vv] =
(new_cost_state_1 - new_cost_state_2
- new_cost_state_3 + recent_best_cost)
/ (delta_parameter_v * delta_parameter_vv
* parameter_v * parameter_vv + (double) EPS_DOUBLE);
}
}
}
/* restore Immediate_Exit flag */
OPTIONS->Immediate_Exit = immediate_flag;
/* restore the best cost function value */
current_generated_state->cost = recent_best_cost;
#if ASA_PRINT
tmp_saved = *number_invalid_generated_states - saved_num_invalid_gen_states;
if (tmp_saved > 0)
#if INT_LONG
fprintf (ptr_asa_out,
"Generated %ld invalid states when calculating the derivatives\n",
tmp_saved);
#else
fprintf (ptr_asa_out,
"Generated %d invalid states when calculating the derivatives\n",
tmp_saved);
#endif
#endif /* ASA_PRINT */
*number_invalid_generated_states = saved_num_invalid_gen_states;
#if USER_ACCEPTANCE_TEST
OPTIONS->User_Acceptance_Flag = TRUE;
OPTIONS->Cost_Acceptance_Flag = FALSE;
#endif
}
/***********************************************************************
* asa_test_asa_options
* Tests user's selected options
***********************************************************************/
#if HAVE_ANSI
int
asa_test_asa_options (LONG_INT * seed,
double *parameter_initial_final,
double *parameter_minimum,
double *parameter_maximum,
double *tangents,
double *curvature,
ALLOC_INT * number_parameters,
int *parameter_type,
int *valid_state_generated_flag,
int *exit_status,
FILE * ptr_asa_out, USER_DEFINES * OPTIONS)
#else
int
asa_test_asa_options (seed,
parameter_initial_final,
parameter_minimum,
parameter_maximum,
tangents,
curvature,
number_parameters,
parameter_type,
valid_state_generated_flag,
exit_status, ptr_asa_out, OPTIONS)
LONG_INT *seed;
double *parameter_initial_final;
double *parameter_minimum;
double *parameter_maximum;
double *tangents;
double *curvature;
ALLOC_INT *number_parameters;
int *parameter_type;
int *valid_state_generated_flag;
int *exit_status;
FILE *ptr_asa_out;
USER_DEFINES *OPTIONS;
#endif /* HAVE_ANSI */
{
int invalid, index_v;
invalid = 0;
if (seed == NULL) {
strcpy (exit_msg, "*** seed == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (parameter_initial_final == NULL) {
strcpy (exit_msg, "*** parameter_initial_final == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (parameter_minimum == NULL) {
strcpy (exit_msg, "*** parameter_minimum == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (parameter_maximum == NULL) {
strcpy (exit_msg, "*** parameter_maximum == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (tangents == NULL) {
strcpy (exit_msg, "*** tangents == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Curvature_0 == FALSE || OPTIONS->Curvature_0 == -1) {
if (curvature == NULL) {
strcpy (exit_msg, "*** curvature == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
}
if (number_parameters == NULL) {
strcpy (exit_msg, "*** number_parameters == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (parameter_type == NULL) {
strcpy (exit_msg, "*** parameter_type == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (valid_state_generated_flag == NULL) {
strcpy (exit_msg, "*** valid_state_generated_flag == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (exit_status == NULL) {
strcpy (exit_msg, "*** exit_status == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS == NULL) {
strcpy (exit_msg, "*** OPTIONS == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
VFOR (index_v) if (parameter_minimum[index_v] > parameter_maximum[index_v]) {
strcpy (exit_msg, "*** parameter_minimum[] > parameter_maximum[] ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
VFOR (index_v)
if (parameter_initial_final[index_v] < parameter_minimum[index_v]) {
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
strcpy (exit_msg, "*** parameter_initial[] < parameter_minimum[] ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
VFOR (index_v)
if (parameter_initial_final[index_v] > parameter_maximum[index_v]) {
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
strcpy (exit_msg, "*** parameter_initial[] > parameter_maximum[] ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
if (*number_parameters < 1) {
strcpy (exit_msg, "*** *number_parameters < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
VFOR (index_v)
if (parameter_type[index_v] != -2 && parameter_type[index_v] != 2
&& parameter_type[index_v] != -1 && parameter_type[index_v] != 1) {
strcpy (exit_msg,
"*** parameter_type[] != -2 && parameter_type[] != 2 && parameter_type[] != -1 && parameter_type[] != 1 ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
if (OPTIONS_FILE != FALSE && OPTIONS_FILE != TRUE) {
strcpy (exit_msg,
"*** OPTIONS_FILE != FALSE && OPTIONS_FILE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS_FILE_DATA != FALSE && OPTIONS_FILE_DATA != TRUE) {
strcpy (exit_msg,
"*** OPTIONS_FILE_DATA != FALSE && OPTIONS_FILE_DATA != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (RECUR_OPTIONS_FILE != FALSE && RECUR_OPTIONS_FILE != TRUE) {
strcpy (exit_msg,
"*** RECUR_OPTIONS_FILE != FALSE && RECUR_OPTIONS_FILE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (RECUR_OPTIONS_FILE_DATA != FALSE && RECUR_OPTIONS_FILE_DATA != TRUE) {
strcpy (exit_msg,
"*** RECUR_OPTIONS_FILE_DATA != FALSE && RECUR_OPTIONS_FILE_DATA != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (COST_FILE != FALSE && COST_FILE != TRUE) {
strcpy (exit_msg, "*** COST_FILE != FALSE && COST_FILE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_LIB != FALSE && ASA_LIB != TRUE) {
strcpy (exit_msg, "*** ASA_LIB != FALSE && ASA_LIB != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (MY_TEMPLATE != FALSE && MY_TEMPLATE != TRUE) {
strcpy (exit_msg, "*** MY_TEMPLATE != FALSE && MY_TEMPLATE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_LIB != FALSE && ASA_TEMPLATE_LIB != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_LIB != FALSE && ASA_TEMPLATE_LIB != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (HAVE_ANSI != FALSE && HAVE_ANSI != TRUE) {
strcpy (exit_msg, "*** HAVE_ANSI != FALSE && HAVE_ANSI != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (IO_PROTOTYPES != FALSE && IO_PROTOTYPES != TRUE) {
strcpy (exit_msg,
"*** IO_PROTOTYPES != FALSE && IO_PROTOTYPES != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (TIME_CALC != FALSE && TIME_CALC != TRUE) {
strcpy (exit_msg, "*** TIME_CALC != FALSE && TIME_CALC != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (TIME_STD != FALSE && TIME_STD != TRUE) {
strcpy (exit_msg, "*** TIME_STD != FALSE && TIME_STD != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (TIME_GETRUSAGE != FALSE && TIME_GETRUSAGE != TRUE) {
strcpy (exit_msg,
"*** TIME_GETRUSAGE != FALSE && TIME_GETRUSAGE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (INT_LONG != FALSE && INT_LONG != TRUE) {
strcpy (exit_msg, "*** INT_LONG != FALSE && INT_LONG != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (INT_ALLOC != FALSE && INT_ALLOC != TRUE) {
strcpy (exit_msg, "*** INT_ALLOC != FALSE && INT_ALLOC != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (SMALL_FLOAT < ZERO) {
strcpy (exit_msg, "*** SMALL_FLOAT < ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (MIN_DOUBLE < ZERO) {
strcpy (exit_msg, "*** MIN_DOUBLE < ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (MAX_DOUBLE < ZERO) {
strcpy (exit_msg, "*** MAX_DOUBLE < ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (EPS_DOUBLE < ZERO) {
strcpy (exit_msg, "*** EPS_DOUBLE < ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (CHECK_EXPONENT != FALSE && CHECK_EXPONENT != TRUE) {
strcpy (exit_msg,
"*** CHECK_EXPONENT != FALSE && CHECK_EXPONENT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (NO_PARAM_TEMP_TEST != FALSE && NO_PARAM_TEMP_TEST != TRUE) {
strcpy (exit_msg,
"*** NO_PARAM_TEMP_TEST != FALSE && NO_PARAM_TEMP_TEST != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (NO_COST_TEMP_TEST != FALSE && NO_COST_TEMP_TEST != TRUE) {
strcpy (exit_msg,
"*** NO_COST_TEMP_TEST != FALSE && NO_COST_TEMP_TEST != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (SELF_OPTIMIZE != FALSE && SELF_OPTIMIZE != TRUE) {
strcpy (exit_msg,
"*** SELF_OPTIMIZE != FALSE && SELF_OPTIMIZE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEST != FALSE && ASA_TEST != TRUE) {
strcpy (exit_msg, "*** ASA_TEST != FALSE && ASA_TEST != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEST_POINT != FALSE && ASA_TEST_POINT != TRUE) {
strcpy (exit_msg,
"*** ASA_TEST_POINT != FALSE && ASA_TEST_POINT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE != FALSE) {
strcpy (exit_msg, "*** ASA_TEMPLATE != FALSE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_ASA_OUT_PID != FALSE && ASA_TEMPLATE_ASA_OUT_PID != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_ASA_OUT_PID != FALSE && ASA_TEMPLATE_ASA_OUT_PID != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_MULTIPLE != FALSE && ASA_TEMPLATE_MULTIPLE != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_MULTIPLE != FALSE && ASA_TEMPLATE_MULTIPLE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_SELFOPT != FALSE && ASA_TEMPLATE_SELFOPT != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_SELFOPT != FALSE && ASA_TEMPLATE_SELFOPT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_SAMPLE != FALSE && ASA_TEMPLATE_SAMPLE != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_SAMPLE != FALSE && ASA_TEMPLATE_SAMPLE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_QUEUE != FALSE && ASA_TEMPLATE_QUEUE != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_QUEUE != FALSE && ASA_TEMPLATE_QUEUE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_PARALLEL != FALSE && ASA_TEMPLATE_PARALLEL != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_PARALLEL != FALSE && ASA_TEMPLATE_PARALLEL != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_TEMPLATE_SAVE != FALSE && ASA_TEMPLATE_SAVE != TRUE) {
strcpy (exit_msg,
"*** ASA_TEMPLATE_SAVE != FALSE && ASA_TEMPLATE_SAVE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_INITIAL_COST_TEMP != FALSE && USER_INITIAL_COST_TEMP != TRUE) {
strcpy (exit_msg,
"*** USER_INITIAL_COST_TEMP != FALSE && USER_INITIAL_COST_TEMP != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (RATIO_TEMPERATURE_SCALES != FALSE && RATIO_TEMPERATURE_SCALES != TRUE) {
strcpy (exit_msg,
"*** RATIO_TEMPERATURE_SCALES != FALSE && RATIO_TEMPERATURE_SCALES != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_INITIAL_PARAMETERS_TEMPS != FALSE
&& USER_INITIAL_PARAMETERS_TEMPS != TRUE) {
strcpy (exit_msg,
"*** USER_INITIAL_PARAMETERS_TEMPS != FALSE && USER_INITIAL_PARAMETERS_TEMPS != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (DELTA_PARAMETERS != FALSE && DELTA_PARAMETERS != TRUE) {
strcpy (exit_msg,
"*** DELTA_PARAMETERS != FALSE && DELTA_PARAMETERS != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (QUENCH_PARAMETERS != FALSE && QUENCH_PARAMETERS != TRUE) {
strcpy (exit_msg,
"*** QUENCH_PARAMETERS != FALSE && QUENCH_PARAMETERS != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (QUENCH_COST != FALSE && QUENCH_COST != TRUE) {
strcpy (exit_msg, "*** QUENCH_COST != FALSE && QUENCH_COST != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (QUENCH_PARAMETERS_SCALE != FALSE && QUENCH_PARAMETERS_SCALE != TRUE) {
strcpy (exit_msg,
"*** QUENCH_PARAMETERS_SCALE != FALSE && QUENCH_PARAMETERS_SCALE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (QUENCH_COST_SCALE != FALSE && QUENCH_COST_SCALE != TRUE) {
strcpy (exit_msg,
"*** QUENCH_COST_SCALE != FALSE && QUENCH_COST_SCALE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONAL_DATA_DBL != FALSE && OPTIONAL_DATA_DBL != TRUE) {
strcpy (exit_msg,
"*** OPTIONAL_DATA_DBL != FALSE && OPTIONAL_DATA_DBL != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONAL_DATA_INT != FALSE && OPTIONAL_DATA_INT != TRUE) {
strcpy (exit_msg,
"*** OPTIONAL_DATA_INT != FALSE && OPTIONAL_DATA_INT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONAL_DATA_PTR != FALSE && OPTIONAL_DATA_PTR != TRUE) {
strcpy (exit_msg,
"*** OPTIONAL_DATA_PTR != FALSE && OPTIONAL_DATA_PTR != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_COST_SCHEDULE != FALSE && USER_COST_SCHEDULE != TRUE) {
strcpy (exit_msg,
"*** USER_COST_SCHEDULE != FALSE && USER_COST_SCHEDULE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_ACCEPT_ASYMP_EXP != FALSE && USER_ACCEPT_ASYMP_EXP != TRUE) {
strcpy (exit_msg,
"*** USER_ACCEPT_ASYMP_EXP != FALSE && USER_ACCEPT_ASYMP_EXP != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_ACCEPT_THRESHOLD != FALSE && USER_ACCEPT_THRESHOLD != TRUE) {
strcpy (exit_msg,
"*** USER_ACCEPT_THRESHOLD != FALSE && USER_ACCEPT_THRESHOLD != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_ACCEPTANCE_TEST != FALSE && USER_ACCEPTANCE_TEST != TRUE) {
strcpy (exit_msg,
"*** USER_ACCEPTANCE_TEST != FALSE && USER_ACCEPTANCE_TEST != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_GENERATING_FUNCTION != FALSE && USER_GENERATING_FUNCTION != TRUE) {
strcpy (exit_msg,
"*** USER_GENERATING_FUNCTION != FALSE && USER_GENERATING_FUNCTION != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_REANNEAL_COST != FALSE && USER_REANNEAL_COST != TRUE) {
strcpy (exit_msg,
"*** USER_REANNEAL_COST != FALSE && USER_REANNEAL_COST != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_REANNEAL_PARAMETERS != FALSE && USER_REANNEAL_PARAMETERS != TRUE) {
strcpy (exit_msg,
"*** USER_REANNEAL_PARAMETERS != FALSE && USER_REANNEAL_PARAMETERS != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (MAXIMUM_REANNEAL_INDEX < 1) {
strcpy (exit_msg, "*** MAXIMUM_REANNEAL_INDEX < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (REANNEAL_SCALE < ZERO) {
strcpy (exit_msg, "*** REANNEAL_SCALE < ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_SAMPLE != FALSE && ASA_SAMPLE != TRUE) {
strcpy (exit_msg, "*** ASA_SAMPLE != FALSE && ASA_SAMPLE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_QUEUE != FALSE && ASA_QUEUE != TRUE) {
strcpy (exit_msg, "*** ASA_QUEUE != FALSE && ASA_QUEUE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_RESOLUTION != FALSE && ASA_RESOLUTION != TRUE) {
strcpy (exit_msg,
"*** ASA_RESOLUTION != FALSE && ASA_RESOLUTION != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (FITLOC != FALSE && FITLOC != TRUE) {
strcpy (exit_msg, "*** FITLOC != FALSE && FITLOC != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (FITLOC_ROUND != FALSE && FITLOC_ROUND != TRUE) {
strcpy (exit_msg,
"*** FITLOC_ROUND != FALSE && FITLOC_ROUND != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (FITLOC_PRINT != FALSE && FITLOC_PRINT != TRUE) {
strcpy (exit_msg,
"*** FITLOC_PRINT != FALSE && FITLOC_PRINT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (MULTI_MIN != FALSE && MULTI_MIN != TRUE) {
strcpy (exit_msg, "*** MULTI_MIN != FALSE && MULTI_MIN != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#if MULTI_MIN
if (OPTIONS->Multi_Number <= 0) {
strcpy (exit_msg, "*** OPTIONS->Multi_Number <= 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
VFOR (index_v) {
if (((OPTIONS->Multi_Grid[index_v]) != (OPTIONS->Multi_Grid[index_v]))
|| OPTIONS->Multi_Grid[index_v] < 0) {
strcpy (exit_msg,
"*** (OPTIONS->Multi_Grid[]) != (OPTIONS->Multi_Grid[]) || OPTIONS->Multi_Grid[] < 0 ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
}
if (OPTIONS->Multi_Specify != 0 && OPTIONS->Multi_Specify != 1) {
strcpy (exit_msg,
"*** OPTIONS->Multi_Specify != 0 && OPTIONS->Multi_Specify != 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
if (ASA_PARALLEL != FALSE && ASA_PARALLEL != TRUE) {
strcpy (exit_msg,
"*** ASA_PARALLEL != FALSE && ASA_PARALLEL != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_SAVE != FALSE && ASA_SAVE != TRUE) {
strcpy (exit_msg, "*** ASA_SAVE != FALSE && ASA_SAVE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_SAVE_OPT != FALSE && ASA_SAVE_OPT != TRUE) {
strcpy (exit_msg,
"*** ASA_SAVE_OPT != FALSE && ASA_SAVE_OPT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_SAVE_BACKUP != FALSE && ASA_SAVE_BACKUP != TRUE) {
strcpy (exit_msg,
"*** ASA_SAVE_BACKUP != FALSE && ASA_SAVE_BACKUP != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_PIPE != FALSE && ASA_PIPE != TRUE) {
strcpy (exit_msg, "*** ASA_PIPE != FALSE && ASA_PIPE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_PIPE_FILE != FALSE && ASA_PIPE_FILE != TRUE) {
strcpy (exit_msg,
"*** ASA_PIPE_FILE != FALSE && ASA_PIPE_FILE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (SYSTEM_CALL != FALSE && SYSTEM_CALL != TRUE) {
strcpy (exit_msg, "*** SYSTEM_CALL != FALSE && SYSTEM_CALL != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (FDLIBM_POW != FALSE && FDLIBM_POW != TRUE) {
strcpy (exit_msg, "*** FDLIBM_POW != FALSE && FDLIBM_POW != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (FDLIBM_LOG != FALSE && FDLIBM_LOG != TRUE) {
strcpy (exit_msg, "*** FDLIBM_LOG != FALSE && FDLIBM_LOG != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (FDLIBM_EXP != FALSE && FDLIBM_EXP != TRUE) {
strcpy (exit_msg, "*** FDLIBM_EXP != FALSE && FDLIBM_EXP != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_PRINT != FALSE && ASA_PRINT != TRUE) {
strcpy (exit_msg, "*** ASA_PRINT != FALSE && ASA_PRINT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (USER_ASA_OUT != FALSE && USER_ASA_OUT != TRUE) {
strcpy (exit_msg,
"*** USER_ASA_OUT != FALSE && USER_ASA_OUT != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_PRINT_INTERMED != FALSE && ASA_PRINT_INTERMED != TRUE) {
strcpy (exit_msg,
"*** ASA_PRINT_INTERMED != FALSE && ASA_PRINT_INTERMED != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (ASA_PRINT_MORE != FALSE && ASA_PRINT_MORE != TRUE) {
strcpy (exit_msg,
"*** ASA_PRINT_MORE != FALSE && ASA_PRINT_MORE != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (G_FIELD < 0) {
strcpy (exit_msg, "*** G_FIELD < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (G_PRECISION < 0) {
strcpy (exit_msg, "*** G_PRECISION < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Limit_Acceptances < 0) {
strcpy (exit_msg, "*** Limit_Acceptances < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Limit_Generated < 0) {
strcpy (exit_msg, "*** Limit_Generated < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Limit_Invalid_Generated_States < 0) {
strcpy (exit_msg, "*** Limit_Invalid_Generated_States < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Accepted_To_Generated_Ratio <= ZERO) {
strcpy (exit_msg, "*** Accepted_To_Generated_Ratio <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Cost_Precision <= ZERO) {
strcpy (exit_msg, "*** Cost_Precision <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Maximum_Cost_Repeat < 0) {
strcpy (exit_msg, "*** Maximum_Cost_Repeat < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Number_Cost_Samples == 0 || OPTIONS->Number_Cost_Samples == -1) {
strcpy (exit_msg,
"*** Number_Cost_Samples == 0 || Number_Cost_Samples == -1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Temperature_Ratio_Scale <= ZERO) {
strcpy (exit_msg, "*** Temperature_Ratio_Scale <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Cost_Parameter_Scale_Ratio <= ZERO) {
strcpy (exit_msg, "*** Cost_Parameter_Scale_Ratio <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Temperature_Anneal_Scale <= ZERO) {
strcpy (exit_msg, "*** Temperature_Anneal_Scale <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#if USER_INITIAL_COST_TEMP
if (OPTIONS->User_Cost_Temperature[0] <= ZERO) {
strcpy (exit_msg, "*** User_Cost_Temperature[0] <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
if (OPTIONS->Include_Integer_Parameters != FALSE
&& OPTIONS->Include_Integer_Parameters != TRUE) {
strcpy (exit_msg, "");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->User_Initial_Parameters != FALSE
&& OPTIONS->User_Initial_Parameters != TRUE) {
strcpy (exit_msg,
"*** User_Initial_Parameters != FALSE && User_Initial_Parameters != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Sequential_Parameters >= *number_parameters) {
strcpy (exit_msg, "*** Sequential_Parameters >= *number_parameters ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Initial_Parameter_Temperature <= ZERO) {
strcpy (exit_msg, "*** Initial_Parameter_Temperature <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#if RATIO_TEMPERATURE_SCALES
VFOR (index_v) if (OPTIONS->User_Temperature_Ratio[index_v] <= ZERO) {
strcpy (exit_msg, "*** User_Temperature_Ratio[] <= ZERO ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
#endif
#if USER_INITIAL_PARAMETERS_TEMPS
VFOR (index_v) if (OPTIONS->User_Parameter_Temperature[index_v] <= ZERO) {
strcpy (exit_msg, "*** User_Parameter_Temperature[] <= ZERO ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
#endif
if (OPTIONS->Acceptance_Frequency_Modulus < 0) {
strcpy (exit_msg, "*** Acceptance_Frequency_Modulus < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Generated_Frequency_Modulus < 0) {
strcpy (exit_msg, "*** Generated_Frequency_Modulus < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Reanneal_Cost == -1) {
strcpy (exit_msg, "*** Reanneal_Cost == -1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Reanneal_Parameters != FALSE
&& OPTIONS->Reanneal_Parameters != TRUE) {
strcpy (exit_msg,
"*** Reanneal_Parameters != FALSE && Reanneal_Parameters != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Delta_X <= ZERO) {
strcpy (exit_msg, "*** Delta_X <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#if DELTA_PARAMETERS
VFOR (index_v) if (OPTIONS->User_Delta_Parameter[index_v] <= ZERO) {
strcpy (exit_msg, "*** User_Delta_Parameter[] <= ZERO ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
#endif
if (OPTIONS->User_Tangents != FALSE && OPTIONS->User_Tangents != TRUE) {
strcpy (exit_msg,
"*** User_Tangents != FALSE && User_Tangents != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Curvature_0 != -1 && OPTIONS->Curvature_0 != FALSE
&& OPTIONS->Curvature_0 != TRUE) {
strcpy (exit_msg,
"*** Curvature_0 -1 && Curvature_0 != FALSE && Curvature_0 != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#if QUENCH_PARAMETERS
VFOR (index_v) if (OPTIONS->User_Quench_Param_Scale[index_v] <= ZERO) {
strcpy (exit_msg, "*** User_Quench_Param_Scale[] <= ZERO ***");
print_string_index (ptr_asa_out, exit_msg, index_v);
++invalid;
}
#endif
#if QUENCH_COST
if (OPTIONS->User_Quench_Cost_Scale[0] <= ZERO) {
strcpy (exit_msg, "*** User_Quench_Cost_Scale[0] <= ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if OPTIONAL_DATA_DBL
if (OPTIONS->Asa_Data_Dim_Dbl < 1) {
strcpy (exit_msg, "*** Asa_Data_Dim_Dbl < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Asa_Data_Dbl == NULL) {
strcpy (exit_msg, "*** Asa_Data_Dbl == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if ASA_SAVE
if (OPTIONS->Random_Array_Dim < 1) {
strcpy (exit_msg, "*** Random_Array_Dim < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Random_Array == NULL) {
strcpy (exit_msg, "*** Random_Array == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if OPTIONAL_DATA_INT
if (OPTIONS->Asa_Data_Dim_Int < 1) {
strcpy (exit_msg, "*** Asa_Data_Dim_Int < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Asa_Data_Int == NULL) {
strcpy (exit_msg, "*** Asa_Data_Int == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if OPTIONAL_DATA_PTR
if (OPTIONS->Asa_Data_Dim_Ptr < 1) {
strcpy (exit_msg, "*** Asa_Data_Dim_Ptr < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Asa_Data_Ptr == NULL) {
strcpy (exit_msg, "*** Asa_Data_Ptr == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if USER_ASA_OUT
if (OPTIONS->Asa_Out_File == NULL) {
strcpy (exit_msg, "*** Asa_Out_File == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if USER_COST_SCHEDULE
if (OPTIONS->Cost_Schedule == NULL) {
strcpy (exit_msg, "*** Cost_Schedule == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if USER_ACCEPTANCE_TEST
if (OPTIONS->Acceptance_Test == NULL) {
strcpy (exit_msg, "*** Acceptance_Test == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->User_Acceptance_Flag != FALSE
&& OPTIONS->User_Acceptance_Flag != TRUE) {
strcpy (exit_msg,
"*** User_Acceptance_Flag != FALSE && User_Acceptance_Flag != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Cost_Acceptance_Flag != FALSE
&& OPTIONS->Cost_Acceptance_Flag != TRUE) {
strcpy (exit_msg,
"*** Cost_Acceptance_Flag != FALSE && Cost_Acceptance_Flag != TRUE ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if USER_GENERATING_FUNCTION
if (OPTIONS->Generating_Distrib == NULL) {
strcpy (exit_msg, "*** Generating_Distrib == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if USER_REANNEAL_COST
if (OPTIONS->Reanneal_Cost_Function == NULL) {
strcpy (exit_msg, "*** Reanneal_Cost_Function == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if USER_REANNEAL_PARAMETERS
if (OPTIONS->Reanneal_Params_Function == NULL) {
strcpy (exit_msg, "*** Reanneal_Params_Function == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if ASA_SAMPLE
if (OPTIONS->Bias_Generated == NULL) {
strcpy (exit_msg, "*** Bias_Generated == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Limit_Weights < ZERO) {
strcpy (exit_msg, "*** Limit_Weights < ZERO ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if ASA_QUEUE
if (OPTIONS->Queue_Size < 0) {
strcpy (exit_msg, "*** Queue_Size < 0 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Queue_Size > 0) {
if (OPTIONS->Queue_Resolution == NULL) {
strcpy (exit_msg, "*** Queue_Resolution == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
}
#endif
#if ASA_RESOLUTION
if (OPTIONS->Coarse_Resolution == NULL) {
strcpy (exit_msg, "*** Coarse_Resolution == NULL ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
#if ASA_PARALLEL
if (OPTIONS->Gener_Block < 1) {
strcpy (exit_msg, "*** Gener_Block < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Gener_Block_Max < 1) {
strcpy (exit_msg, "*** Gener_Block_Max < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
if (OPTIONS->Gener_Mov_Avr < 1) {
strcpy (exit_msg, "*** Gener_Mov_Avr < 1 ***");
print_string (ptr_asa_out, exit_msg);
++invalid;
}
#endif
return (invalid);
}
/***********************************************************************
* cost_function_test
* Tests user's returned cost function values and parameters
***********************************************************************/
#if HAVE_ANSI
int
cost_function_test (double cost,
double *parameter,
double *parameter_minimum,
double *parameter_maximum,
ALLOC_INT * number_parameters, double *xnumber_parameters)
#else
int
cost_function_test (cost,
parameter,
parameter_minimum, parameter_maximum,
number_parameters, xnumber_parameters)
double cost;
double *parameter;
double *parameter_minimum;
double *parameter_maximum;
ALLOC_INT *number_parameters;
double *xnumber_parameters;
#endif /* HAVE_ANSI */
{
ALLOC_INT index_v;
int test_flag;
test_flag = 1;
if (((cost) != (cost)) || (cost < -MAX_DOUBLE || cost > MAX_DOUBLE))
test_flag = 0;
*xnumber_parameters = (double) *number_parameters;
VFOR (index_v) {
if (PARAMETER_RANGE_TOO_SMALL (index_v)) {
*xnumber_parameters -= 1.0;
continue;
}
if (parameter[index_v] < parameter_minimum[index_v] ||
parameter[index_v] > parameter_maximum[index_v]) {
test_flag = 0;
}
}
return (test_flag);
}
/***********************************************************************
* print_string
* This prints the designated string
***********************************************************************/
#if HAVE_ANSI
void
print_string (FILE * ptr_asa_out, char *string)
#else
void
print_string (ptr_asa_out, string)
FILE *ptr_asa_out;
char *string;
#endif /* HAVE_ANSI */
{
#if INCL_STDOUT
printf ("\n\n%s\n\n", string);
#endif /* INCL_STDOUT */
#if ASA_PRINT
fprintf (ptr_asa_out, "\n\n%s\n\n", string);
#else
#endif
}
/***********************************************************************
* print_string_index
* This prints the designated string and index
***********************************************************************/
#if HAVE_ANSI
void
print_string_index (FILE * ptr_asa_out, char *string, ALLOC_INT index)
#else
void
print_string_index (ptr_asa_out, string, index)
FILE *ptr_asa_out;
char *string;
ALLOC_INT index;
#endif /* HAVE_ANSI */
{
#if INCL_STDOUT
#if INT_ALLOC
printf ("\n\n%s index = %d\n\n", string, index);
#else /* INT_ALLOC */
#if INT_LONG
printf ("\n\n%s index = %ld\n\n", string, index);
#else /* INT_LONG */
printf ("\n\n%s index = %ld\n\n", string, index);
#endif /* INT_LONG */
#endif /* INT_ALLOC */
#endif /* INCL_STDOUT */
#if ASA_PRINT
#if INT_ALLOC
fprintf (ptr_asa_out, "\n\n%s index = %d\n\n", string, index);
#else /* INT_ALLOC */
#if INT_LONG
fprintf (ptr_asa_out, "\n\n%s index = %ld\n\n", string, index);
#else /* INT_LONG */
fprintf (ptr_asa_out, "\n\n%s index = %d\n\n", string, index);
#endif /* INT_LONG */
#endif /* INT_ALLOC */
#else /* ASA_PRINT */
;
#endif /* ASA_PRINT */
}
#if ASA_PRINT
/***********************************************************************
* print_state
* Prints a description of the current state of the system
***********************************************************************/
void
print_state (double *parameter_minimum,
double *parameter_maximum,
double *tangents,
double *curvature,
double *current_cost_temperature,
double *current_user_parameter_temp,
double *accepted_to_generated_ratio,
ALLOC_INT * number_parameters,
int *curvature_flag,
LONG_INT * number_accepted,
LONG_INT * index_cost_acceptances,
LONG_INT * number_generated,
LONG_INT * number_invalid_generated_states,
STATE * last_saved_state,
STATE * best_generated_state,
FILE * ptr_asa_out, USER_DEFINES * OPTIONS)
{
ALLOC_INT index_v;
ALLOC_INT index_vv, index_v_vv;
fprintf (ptr_asa_out, "\n");
#if TIME_CALC
print_time ("", ptr_asa_out);
#endif
if (OPTIONS->Curvature_0 == TRUE)
*curvature_flag = FALSE;
if (OPTIONS->Curvature_0 == -1)
*curvature_flag = TRUE;
#if INT_LONG
fprintf (ptr_asa_out,
"*index_cost_acceptances = %ld, *current_cost_temperature = %*.*g\n",
*index_cost_acceptances,
G_FIELD, G_PRECISION, *current_cost_temperature);
fprintf (ptr_asa_out, "*accepted_to_generated_ratio = %*.*g,\
*number_invalid... = %ld\n", G_FIELD, G_PRECISION, *accepted_to_generated_ratio, (*number_invalid_generated_states));
fprintf (ptr_asa_out,
"*number_generated = %ld, *number_accepted = %ld\n",
*number_generated, *number_accepted);
#else
fprintf (ptr_asa_out,
"*index_cost_acceptances = %d, *current_cost_temperature = %*.*g\n",
*index_cost_acceptances,
G_FIELD, G_PRECISION, *current_cost_temperature);
fprintf (ptr_asa_out, "*accepted_to_generated_ratio = %*.*g,\
*number_invalid... = %d\n", G_FIELD, G_PRECISION, *accepted_to_generated_ratio, *number_invalid_generated_states);
fprintf (ptr_asa_out,
"*number_generated = %d, *number_accepted = %d\n",
*number_generated, *number_accepted);
#endif
fprintf (ptr_asa_out, "best...->cost = %*.*g,\
last...->cost = %*.*g\n", G_FIELD, G_PRECISION, best_generated_state->cost, G_FIELD, G_PRECISION, last_saved_state->cost);
/* Note that tangents will not be calculated until reanneal
is called, and therefore their listing in the printout only
is relevant then */
fprintf (ptr_asa_out,
"index_v best...->parameter current_parameter_temp\ttangent\n");
VFOR (index_v) {
/* ignore too small ranges */
#if DROPPED_PARAMETERS
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
#endif
fprintf (ptr_asa_out,
#if INT_ALLOC
"%d\t%*.*g\t\t%*.*g\t%*.*g\n",
#else
#if INT_LONG
"%ld\t%*.*g\t\t%*.*g\t%*.*g\n",
#else
"%d\t%*.*g\t\t%*.*g\t%*.*g\n",
#endif
#endif
index_v,
G_FIELD, G_PRECISION, best_generated_state->parameter[index_v],
G_FIELD, G_PRECISION, current_user_parameter_temp[index_v],
G_FIELD, G_PRECISION, tangents[index_v]);
}
if (*curvature_flag == TRUE) {
/* print curvatures */
VFOR (index_v) {
/* ignore too small ranges */
if (PARAMETER_RANGE_TOO_SMALL (index_v))
continue;
fprintf (ptr_asa_out, "\n");
VFOR (index_vv) {
/* only print upper diagonal of matrix */
if (index_v < index_vv)
continue;
/* ignore too small ranges (index_vv) */
if (PARAMETER_RANGE_TOO_SMALL (index_vv))
continue;
/* index_v_vv: row index_v, column index_vv */
index_v_vv = ROW_COL_INDEX (index_v, index_vv);
if (index_v == index_vv) {
fprintf (ptr_asa_out,
#if INT_ALLOC
"curvature[%d][%d] = %*.*g\n",
#else
#if INT_LONG
"curvature[%ld][%ld] = %*.*g\n",
#else
"curvature[%d][%d] = %*.*g\n",
#endif
#endif
index_v, index_vv,
G_FIELD, G_PRECISION, curvature[index_v_vv]);
} else {
fprintf (ptr_asa_out,
#if INT_ALLOC
"curvature[%d][%d] = %*.*g \t = curvature[%d][%d]\n",
#else
#if INT_LONG
"curvature[%ld][%ld] = %*.*g \t = curvature[%ld][%ld]\n",
#else
"curvature[%d][%d] = %*.*g \t = curvature[%d][%d]\n",
#endif
#endif
index_v, index_vv,
G_FIELD, G_PRECISION, curvature[index_v_vv],
index_vv, index_v);
}
}
}
}
fprintf (ptr_asa_out, "\n");
fflush (ptr_asa_out);
}
/***********************************************************************
* print_asa_options
* Prints user's selected options
***********************************************************************/
void
print_asa_options (FILE * ptr_asa_out, USER_DEFINES * OPTIONS)
{
fprintf (ptr_asa_out, "\t\tADAPTIVE SIMULATED ANNEALING\n\n");
fprintf (ptr_asa_out, "%s\n\n", ASA_ID);
fprintf (ptr_asa_out, "OPTIONS_FILE = %d\n", (int) OPTIONS_FILE);
fprintf (ptr_asa_out, "OPTIONS_FILE_DATA = %d\n", (int) OPTIONS_FILE_DATA);
fprintf (ptr_asa_out, "RECUR_OPTIONS_FILE = %d\n",
(int) RECUR_OPTIONS_FILE);
fprintf (ptr_asa_out, "RECUR_OPTIONS_FILE_DATA = %d\n",
(int) RECUR_OPTIONS_FILE_DATA);
fprintf (ptr_asa_out, "COST_FILE = %d\n", (int) COST_FILE);
fprintf (ptr_asa_out, "ASA_LIB = %d\n", (int) ASA_LIB);
fprintf (ptr_asa_out, "HAVE_ANSI = %d\n", (int) HAVE_ANSI);
fprintf (ptr_asa_out, "IO_PROTOTYPES = %d\n", (int) IO_PROTOTYPES);
fprintf (ptr_asa_out, "TIME_CALC = %d\n", (int) TIME_CALC);
fprintf (ptr_asa_out, "TIME_STD = %d\n", (int) TIME_STD);
fprintf (ptr_asa_out, "TIME_GETRUSAGE = %d\n", (int) TIME_GETRUSAGE);
fprintf (ptr_asa_out, "INT_LONG = %d\n", (int) INT_LONG);
fprintf (ptr_asa_out, "INT_ALLOC = %d\n", (int) INT_ALLOC);
fprintf (ptr_asa_out, "SMALL_FLOAT = %*.*g\n",
G_FIELD, G_PRECISION, (double) SMALL_FLOAT);
fprintf (ptr_asa_out, "MIN_DOUBLE = %*.*g\n",
G_FIELD, G_PRECISION, (double) MIN_DOUBLE);
fprintf (ptr_asa_out, "MAX_DOUBLE = %*.*g\n",
G_FIELD, G_PRECISION, (double) MAX_DOUBLE);
fprintf (ptr_asa_out, "EPS_DOUBLE = %*.*g\n",
G_FIELD, G_PRECISION, (double) EPS_DOUBLE);
fprintf (ptr_asa_out, "CHECK_EXPONENT = %d\n", (int) CHECK_EXPONENT);
fprintf (ptr_asa_out, "NO_PARAM_TEMP_TEST = %d\n",
(int) NO_PARAM_TEMP_TEST);
fprintf (ptr_asa_out, "NO_COST_TEMP_TEST = %d\n", (int) NO_COST_TEMP_TEST);
fprintf (ptr_asa_out, "SELF_OPTIMIZE = %d\n", (int) SELF_OPTIMIZE);
fprintf (ptr_asa_out, "ASA_TEST = %d\n", (int) ASA_TEST);
fprintf (ptr_asa_out, "ASA_TEST_POINT = %d\n", (int) ASA_TEST_POINT);
fprintf (ptr_asa_out, "ASA_TEMPLATE = %d\n", (int) ASA_TEMPLATE);
fprintf (ptr_asa_out, "MY_TEMPLATE = %d\n", (int) MY_TEMPLATE);
fprintf (ptr_asa_out, "ASA_TEMPLATE_LIB = %d\n", (int) ASA_TEMPLATE_LIB);
fprintf (ptr_asa_out, "ASA_TEMPLATE_ASA_OUT_PID = %d\n",
(int) ASA_TEMPLATE_ASA_OUT_PID);
fprintf (ptr_asa_out, "ASA_TEMPLATE_MULTIPLE = %d\n",
(int) ASA_TEMPLATE_MULTIPLE);
fprintf (ptr_asa_out, "ASA_TEMPLATE_SELFOPT = %d\n",
(int) ASA_TEMPLATE_SELFOPT);
fprintf (ptr_asa_out, "ASA_TEMPLATE_SAMPLE = %d\n",
(int) ASA_TEMPLATE_SAMPLE);
fprintf (ptr_asa_out, "ASA_TEMPLATE_QUEUE = %d\n",
(int) ASA_TEMPLATE_QUEUE);
fprintf (ptr_asa_out, "ASA_TEMPLATE_PARALLEL = %d\n",
(int) ASA_TEMPLATE_PARALLEL);
fprintf (ptr_asa_out, "ASA_TEMPLATE_SAVE = %d\n", (int) ASA_TEMPLATE_SAVE);
fprintf (ptr_asa_out, "USER_INITIAL_COST_TEMP = %d\n",
(int) USER_INITIAL_COST_TEMP);
fprintf (ptr_asa_out, "RATIO_TEMPERATURE_SCALES = %d\n",
(int) RATIO_TEMPERATURE_SCALES);
fprintf (ptr_asa_out, "USER_INITIAL_PARAMETERS_TEMPS = %d\n",
(int) USER_INITIAL_PARAMETERS_TEMPS);
fprintf (ptr_asa_out, "DELTA_PARAMETERS = %d\n", (int) DELTA_PARAMETERS);
fprintf (ptr_asa_out, "QUENCH_PARAMETERS = %d\n", (int) QUENCH_PARAMETERS);
fprintf (ptr_asa_out, "QUENCH_COST = %d\n", (int) QUENCH_COST);
fprintf (ptr_asa_out, "QUENCH_PARAMETERS_SCALE = %d\n",
(int) QUENCH_PARAMETERS_SCALE);
fprintf (ptr_asa_out, "QUENCH_COST_SCALE = %d\n", (int) QUENCH_COST_SCALE);
fprintf (ptr_asa_out, "OPTIONAL_DATA_DBL = %d\n", (int) OPTIONAL_DATA_DBL);
fprintf (ptr_asa_out, "OPTIONAL_DATA_INT = %d\n", (int) OPTIONAL_DATA_INT);
fprintf (ptr_asa_out, "OPTIONAL_DATA_PTR = %d\n", (int) OPTIONAL_DATA_PTR);
fprintf (ptr_asa_out, "USER_COST_SCHEDULE = %d\n",
(int) USER_COST_SCHEDULE);
fprintf (ptr_asa_out, "USER_ACCEPT_ASYMP_EXP = %d\n",
(int) USER_ACCEPT_ASYMP_EXP);
fprintf (ptr_asa_out, "USER_ACCEPT_THRESHOLD = %d\n",
(int) USER_ACCEPT_THRESHOLD);
fprintf (ptr_asa_out, "USER_ACCEPTANCE_TEST = %d\n",
(int) USER_ACCEPTANCE_TEST);
fprintf (ptr_asa_out, "USER_GENERATING_FUNCTION = %d\n",
(int) USER_GENERATING_FUNCTION);
fprintf (ptr_asa_out, "USER_REANNEAL_COST = %d\n",
(int) USER_REANNEAL_COST);
fprintf (ptr_asa_out, "USER_REANNEAL_PARAMETERS = %d\n",
(int) USER_REANNEAL_PARAMETERS);
#if INT_LONG
fprintf (ptr_asa_out, "MAXIMUM_REANNEAL_INDEX = %ld\n",
(LONG_INT) MAXIMUM_REANNEAL_INDEX);
#else
fprintf (ptr_asa_out, "MAXIMUM_REANNEAL_INDEX = %d\n",
(LONG_INT) MAXIMUM_REANNEAL_INDEX);
#endif
fprintf (ptr_asa_out, "REANNEAL_SCALE = %*.*g\n",
G_FIELD, G_PRECISION, (double) REANNEAL_SCALE);
fprintf (ptr_asa_out, "ASA_SAMPLE = %d\n", (int) ASA_SAMPLE);
fprintf (ptr_asa_out, "ASA_QUEUE = %d\n", (int) ASA_QUEUE);
fprintf (ptr_asa_out, "ASA_RESOLUTION = %d\n", (int) ASA_RESOLUTION);
fprintf (ptr_asa_out, "FITLOC = %d\n", (int) FITLOC);
fprintf (ptr_asa_out, "FITLOC_ROUND = %d\n", (int) FITLOC_ROUND);
fprintf (ptr_asa_out, "FITLOC_PRINT = %d\n", (int) FITLOC_PRINT);
fprintf (ptr_asa_out, "MULTI_MIN = %d\n", (int) MULTI_MIN);
fprintf (ptr_asa_out, "ASA_PARALLEL = %d\n", (int) ASA_PARALLEL);
fprintf (ptr_asa_out, "FDLIBM_POW = %d\n", (int) FDLIBM_POW);
fprintf (ptr_asa_out, "FDLIBM_LOG = %d\n", (int) FDLIBM_LOG);
fprintf (ptr_asa_out, "FDLIBM_EXP = %d\n\n", (int) FDLIBM_EXP);
fprintf (ptr_asa_out, "ASA_PRINT = %d\n", (int) ASA_PRINT);
fprintf (ptr_asa_out, "USER_OUT = %s\n", USER_OUT);
#if USER_ASA_OUT
fprintf (ptr_asa_out, "ASA_OUT = %s\n", OPTIONS->Asa_Out_File);
#else
fprintf (ptr_asa_out, "ASA_OUT = %s\n", ASA_OUT);
#endif
fprintf (ptr_asa_out, "USER_ASA_OUT = %d\n", (int) USER_ASA_OUT);
fprintf (ptr_asa_out, "ASA_PRINT_INTERMED = %d\n",
(int) ASA_PRINT_INTERMED);
fprintf (ptr_asa_out, "ASA_PRINT_MORE = %d\n", (int) ASA_PRINT_MORE);
fprintf (ptr_asa_out, "INCL_STDOUT = %d\n", (int) INCL_STDOUT);
fprintf (ptr_asa_out, "G_FIELD = %d\n", (int) G_FIELD);
fprintf (ptr_asa_out, "G_PRECISION = %d\n", (int) G_PRECISION);
fprintf (ptr_asa_out, "ASA_SAVE = %d\n", (int) ASA_SAVE);
fprintf (ptr_asa_out, "ASA_SAVE_OPT = %d\n", (int) ASA_SAVE_OPT);
fprintf (ptr_asa_out, "ASA_SAVE_BACKUP = %d\n", (int) ASA_SAVE_BACKUP);
fprintf (ptr_asa_out, "ASA_PIPE = %d\n", (int) ASA_PIPE);
fprintf (ptr_asa_out, "ASA_PIPE_FILE = %d\n", (int) ASA_PIPE_FILE);
fprintf (ptr_asa_out, "SYSTEM_CALL = %d\n\n", (int) SYSTEM_CALL);
#if INT_LONG
fprintf (ptr_asa_out, "OPTIONS->Limit_Acceptances = %ld\n",
(LONG_INT) OPTIONS->Limit_Acceptances);
fprintf (ptr_asa_out, "OPTIONS->Limit_Generated = %ld\n",
(LONG_INT) OPTIONS->Limit_Generated);
#else
fprintf (ptr_asa_out, "OPTIONS->Limit_Acceptances = %d\n",
(LONG_INT) OPTIONS->Limit_Acceptances);
fprintf (ptr_asa_out, "OPTIONS->Limit_Generated = %d\n",
(LONG_INT) OPTIONS->Limit_Generated);
#endif
fprintf (ptr_asa_out, "OPTIONS->Limit_Invalid_Generated_States = %d\n",
OPTIONS->Limit_Invalid_Generated_States);
fprintf (ptr_asa_out, "OPTIONS->Accepted_To_Generated_Ratio = %*.*g\n\n",
G_FIELD, G_PRECISION, OPTIONS->Accepted_To_Generated_Ratio);
fprintf (ptr_asa_out, "OPTIONS->Cost_Precision = %*.*g\n",
G_FIELD, G_PRECISION, OPTIONS->Cost_Precision);
fprintf (ptr_asa_out, "OPTIONS->Maximum_Cost_Repeat = %d\n",
OPTIONS->Maximum_Cost_Repeat);
fprintf (ptr_asa_out, "OPTIONS->Number_Cost_Samples = %d\n",
OPTIONS->Number_Cost_Samples);
fprintf (ptr_asa_out, "OPTIONS->Temperature_Ratio_Scale = %*.*g\n",
G_FIELD, G_PRECISION, OPTIONS->Temperature_Ratio_Scale);
fprintf (ptr_asa_out, "OPTIONS->Cost_Parameter_Scale_Ratio = %*.*g\n",
G_FIELD, G_PRECISION, OPTIONS->Cost_Parameter_Scale_Ratio);
fprintf (ptr_asa_out, "OPTIONS->Temperature_Anneal_Scale = %*.*g\n",
G_FIELD, G_PRECISION, OPTIONS->Temperature_Anneal_Scale);
fprintf (ptr_asa_out, "OPTIONS->Include_Integer_Parameters = %d\n",
OPTIONS->Include_Integer_Parameters);
fprintf (ptr_asa_out, "OPTIONS->User_Initial_Parameters = %d\n",
OPTIONS->User_Initial_Parameters);
#if INT_ALLOC
fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %d\n",
(int) OPTIONS->Sequential_Parameters);
#else
#if INT_LONG
fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %ld\n",
(LONG_INT) OPTIONS->Sequential_Parameters);
#else
fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %d\n",
(LONG_INT) OPTIONS->Sequential_Parameters);
#endif
#endif
fprintf (ptr_asa_out, "OPTIONS->Initial_Parameter_Temperature = %*.*g\n",
G_FIELD, G_PRECISION, OPTIONS->Initial_Parameter_Temperature);
fprintf (ptr_asa_out, "OPTIONS->Acceptance_Frequency_Modulus = %d\n",
OPTIONS->Acceptance_Frequency_Modulus);
fprintf (ptr_asa_out, "OPTIONS->Generated_Frequency_Modulus = %d\n",
OPTIONS->Generated_Frequency_Modulus);
fprintf (ptr_asa_out, "OPTIONS->Reanneal_Cost = %d\n",
OPTIONS->Reanneal_Cost);
fprintf (ptr_asa_out, "OPTIONS->Reanneal_Parameters = %d\n\n",
OPTIONS->Reanneal_Parameters);
fprintf (ptr_asa_out, "OPTIONS->Delta_X = %*.*g\n",
G_FIELD, G_PRECISION, OPTIONS->Delta_X);
fprintf (ptr_asa_out, "OPTIONS->User_Tangents = %d\n",
OPTIONS->User_Tangents);
fprintf (ptr_asa_out, "OPTIONS->Curvature_0 = %d\n", OPTIONS->Curvature_0);
fprintf (ptr_asa_out, "OPTIONS->Asa_Recursive_Level = %d\n\n",
OPTIONS->Asa_Recursive_Level);
fprintf (ptr_asa_out, "\n");
}
#endif /* ASA_PRINT */
#if TIME_CALC
#if TIME_GETRUSAGE
/***********************************************************************
* print_time
* This calculates the time and runtime and prints it.
***********************************************************************/
#if HAVE_ANSI
void
print_time (char *message, FILE * ptr_asa_out)
#else
void
print_time (message, ptr_asa_out)
char *message;
FILE *ptr_asa_out;
#endif /* HAVE_ANSI */
{
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, ptr_asa_out);
}
/***********************************************************************
* aux_print_time
* auxiliary print the time routine
***********************************************************************/
#if HAVE_ANSI
void
aux_print_time (struct timeval *time, char *message, FILE * ptr_asa_out)
#else
void
aux_print_time (time, message, ptr_asa_out)
struct timeval *time;
char *message;
FILE *ptr_asa_out;
#endif /* HAVE_ANSI */
{
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_asa_out,
"%s:time: %gh %gm %gs; incr: %gh %gm %gs\n",
message, h, m, s, dh, dm, ds);
}
#else /* TIME_GETRUSAGE */
/* Note that on many machines the time resolution of this algorithm
* may be less than the other alternatives, e.g., rounding off the
* number of ticks to the nearest tens of thousands. Also, because
* time here is typically indexed by a long integer, there typically
* is a cycle of time in periods of fractions of an hour. For
* example, under Solaris 2.5.1: The value returned by clock() is
* defined in microseconds, since the first call to clock(), for
* compatibility with systems that have * CPU clocks with much higher
* resolution. Because of this, the value returned will wrap around
* after accumulating only 2147 seconds of CPU time (about 36 minutes).
*
* See asa.h for two places where some additional modifications should
* be made under SunOS 4.1.x. */
#if HAVE_ANSI
void
print_time (char *message, FILE * ptr_asa_out)
#else
void
print_time (message, ptr_asa_out)
char *message;
FILE *ptr_asa_out;
#endif /* HAVE_ANSI */
{
aux_print_time (clock (), message, ptr_asa_out);
} /*print_time */
/***********************************************************************
* aux_print_time
* auxiliary print the time routine
***********************************************************************/
#if HAVE_ANSI
void
aux_print_time (clock_t time, char *message, FILE * ptr_asa_out)
#else
void
aux_print_time (time, message, ptr_asa_out)
clock_t time;
char *message;
FILE *ptr_asa_out;
#endif /* HAVE_ANSI */
{
static clock_t previousTime = -1;
clock_t diffTime;
double clocksPerSecF = CLOCKS_PER_SEC;
double timeF, diffF;
double s, m, h;
double ds, dm, dh;
if (previousTime != -1) {
diffTime = time - previousTime;
timeF = time;
diffF = diffTime;
previousTime = time;
s = timeF / clocksPerSecF;
ds = diffF / clocksPerSecF;
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);
fprintf (ptr_asa_out,
"%s:time: %gh %gm %gs; incr: %gh %gm %gs\n",
message, h, m, s, dh, dm, ds);
} else {
/* The first call will be invalid - don't output anything. */
fprintf (ptr_asa_out, "TIMING PARAMETERS: ticks/sec: %lu\n",
CLOCKS_PER_SEC);
previousTime = time;
}
} /* aux_print_time */
#endif /* TIME_GETRUSAGE */
#endif /* TIME_CALC */
#if MULTI_MIN
#if HAVE_ANSI
static int
multi_compare (const void *ii, const void *jj)
#else /* HAVE_ANSI */
static int
multi_compare (ii, jj)
char *ii;
char *jj;
#endif /* HAVE_ANSI */
{
int i;
int j;
i = *(int *) ii;
j = *(int *) jj;
if (multi_cost_qsort[i] > multi_cost_qsort[j] + (double) EPS_DOUBLE)
return (1);
else if (multi_cost_qsort[i] < multi_cost_qsort[j] - (double) EPS_DOUBLE)
return (-1);
else
return (0);
}
#endif /* MULTI_MIN */
#if ASA_PARALLEL
#if HAVE_ANSI
static int
sort_parallel (const void *ii, const void *jj)
#else /* HAVE_ANSI */
static int
sort_parallel (ii, jj)
void *ii;
void *jj;
#endif /* HAVE_ANSI */
{
LONG_INT i;
LONG_INT j;
i = *(LONG_INT *) ii;
j = *(LONG_INT *) jj;
if (gener_block_state_qsort[i].cost > gener_block_state_qsort[j].cost)
return (1);
else if (gener_block_state_qsort[i].cost < gener_block_state_qsort[j].cost)
return (-1);
else
return (0);
}
#endif /* ASA_PARALLEL */
#if HAVE_ANSI
void
Exit_ASA (char *statement)
#else /* HAVE_ANSI */
void
Exit_ASA (statement)
char *statement;
#endif /* HAVE_ANSI */
{
#if INCL_STDOUT
printf ("\n\n*** EXIT calloc failed in ASA *** %s\n\n", statement);
#else
;
#endif /* INCL_STDOUT */
}