/** * Evaluates the problem function, increases the number of evaluations and updates the best observed value * and the best observed evaluation number. * * @note Both x and y must point to correctly sized allocated memory regions. * * @param problem The given COCO problem. * @param x The decision vector. * @param y The objective vector that is the result of the evaluation (in single-objective problems only the * first vector item is being set). */ void coco_evaluate_function(coco_problem_t *problem, const double *x, double *y) { /* implements a safer version of problem->evaluate(problem, x, y) */ size_t i, j; assert(problem != NULL); assert(problem->evaluate_function != NULL); /* Set objective vector to INFINITY if the decision vector contains any INFINITY values */ for (i = 0; i < coco_problem_get_dimension(problem); i++) { if (coco_is_inf(x[i])) { for (j = 0; j < coco_problem_get_number_of_objectives(problem); j++) { y[j] = fabs(x[i]); } return; } } /* Set objective vector to NAN if the decision vector contains any NAN values */ if (coco_vector_contains_nan(x, coco_problem_get_dimension(problem))) { coco_vector_set_to_nan(y, coco_problem_get_number_of_objectives(problem)); return; } problem->evaluate_function(problem, x, y); problem->evaluations++; /* each derived class has its own counter, only the most outer will be visible */ /* A little bit of bookkeeping */ if (y[0] < problem->best_observed_fvalue[0]) { problem->best_observed_fvalue[0] = y[0]; problem->best_observed_evaluation[0] = problem->evaluations; } }
/** * @brief Allocates a problem constructed by stacking two COCO problems. * * This is particularly useful for generating multi-objective problems, e.g. a bi-objective problem from two * single-objective problems. The stacked problem must behave like a normal COCO problem accepting the same * input. The region of interest in the decision space is defined by parameters smallest_values_of_interest * and largest_values_of_interest, which are two arrays of size equal to the dimensionality of both problems. * * @note Regions of interest in the decision space must either agree or at least one of them must be NULL. * @note Best parameter becomes somewhat meaningless, but the nadir value make sense now. */ static coco_problem_t *coco_problem_stacked_allocate(coco_problem_t *problem1, coco_problem_t *problem2, const double *smallest_values_of_interest, const double *largest_values_of_interest) { const size_t number_of_variables = coco_problem_get_dimension(problem1); const size_t number_of_objectives = coco_problem_get_number_of_objectives(problem1) + coco_problem_get_number_of_objectives(problem2); const size_t number_of_constraints = coco_problem_get_number_of_constraints(problem1) + coco_problem_get_number_of_constraints(problem2); size_t i; char *s; coco_problem_stacked_data_t *data; coco_problem_t *problem; /* the new coco problem */ assert(coco_problem_get_dimension(problem1) == coco_problem_get_dimension(problem2)); problem = coco_problem_allocate(number_of_variables, number_of_objectives, number_of_constraints); s = coco_strconcat(coco_problem_get_id(problem1), "__"); problem->problem_id = coco_strconcat(s, coco_problem_get_id(problem2)); coco_free_memory(s); s = coco_strconcat(coco_problem_get_name(problem1), " + "); problem->problem_name = coco_strconcat(s, coco_problem_get_name(problem2)); coco_free_memory(s); problem->evaluate_function = coco_problem_stacked_evaluate_function; if (number_of_constraints > 0) problem->evaluate_constraint = coco_problem_stacked_evaluate_constraint; assert(smallest_values_of_interest); assert(largest_values_of_interest); for (i = 0; i < number_of_variables; ++i) { problem->smallest_values_of_interest[i] = smallest_values_of_interest[i]; problem->largest_values_of_interest[i] = largest_values_of_interest[i]; } if (problem->best_parameter) /* logger_bbob doesn't work then anymore */ coco_free_memory(problem->best_parameter); problem->best_parameter = NULL; /* Compute the ideal and nadir values */ assert(problem->best_value); assert(problem->nadir_value); problem->best_value[0] = problem1->best_value[0]; problem->best_value[1] = problem2->best_value[0]; coco_evaluate_function(problem1, problem2->best_parameter, &problem->nadir_value[0]); coco_evaluate_function(problem2, problem1->best_parameter, &problem->nadir_value[1]); /* setup data holder */ data = (coco_problem_stacked_data_t *) coco_allocate_memory(sizeof(*data)); data->problem1 = problem1; data->problem2 = problem2; problem->data = data; problem->problem_free_function = coco_problem_stacked_free; return problem; }
static void coco_stacked_problem_evaluate(coco_problem_t *self, const double *x, double *y) { coco_stacked_problem_data_t* data = (coco_stacked_problem_data_t *) self->data; assert( coco_problem_get_number_of_objectives(self) == coco_problem_get_number_of_objectives(data->problem1) + coco_problem_get_number_of_objectives(data->problem2)); coco_evaluate_function(data->problem1, x, &y[0]); coco_evaluate_function(data->problem2, x, &y[coco_problem_get_number_of_objectives(data->problem1)]); }
/* The gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t *ref; mxArray *problem_prop; coco_problem_t *problem = NULL; /* const char *class_name = NULL; */ int nb_objectives; double *x; double *y; /* check for proper number of arguments */ if(nrhs!=2) { mexErrMsgIdAndTxt("cocoEvaluateFunction:nrhs","Two inputs required."); } /* get the problem */ ref = (mwSize *) mxGetData(prhs[0]); problem = (coco_problem_t *)(*ref); /* make sure the second input argument is array of doubles */ if(!mxIsDouble(prhs[1])) { mexErrMsgIdAndTxt("cocoEvaluateFunction:notDoubleArray","Input x must be an array of doubles."); } /* get the x vector */ x = mxGetPr(prhs[1]); /* prepare the return value */ nb_objectives = coco_problem_get_number_of_objectives(problem); plhs[0] = mxCreateDoubleMatrix(1, (size_t)nb_objectives, mxREAL); y = mxGetPr(plhs[0]); /* call coco_evaluate_function(...) */ coco_evaluate_function(problem, x, y); }
/** * @brief Evaluates the transformation. */ static void transform_vars_asymmetric_evaluate(coco_problem_t *problem, const double *x, double *y) { size_t i; double exponent; transform_vars_asymmetric_data_t *data; coco_problem_t *inner_problem; if (coco_vector_contains_nan(x, coco_problem_get_dimension(problem))) { coco_vector_set_to_nan(y, coco_problem_get_number_of_objectives(problem)); return; } data = (transform_vars_asymmetric_data_t *) coco_problem_transformed_get_data(problem); inner_problem = coco_problem_transformed_get_inner_problem(problem); for (i = 0; i < problem->number_of_variables; ++i) { if (x[i] > 0.0) { exponent = 1.0 + (data->beta * (double) (long) i) / ((double) (long) problem->number_of_variables - 1.0) * sqrt(x[i]); data->x[i] = pow(x[i], exponent); } else { data->x[i] = x[i]; } } coco_evaluate_function(inner_problem, data->x, y); assert(y[0] + 1e-13 >= problem->best_value[0]); }
/* * Class: CocoJNI * Method: cocoEvaluateConstraint * Signature: (J[D)[D */ JNIEXPORT jdoubleArray JNICALL Java_org_moeaframework_problem_BBOB2016_CocoJNI_cocoEvaluateConstraint (JNIEnv *jenv, jclass interface_cls, jlong jproblem_pointer, jdoubleArray jx) { coco_problem_t *problem = NULL; double *y = NULL; double *x = NULL; int number_of_objectives; jdoubleArray jy; /* This test is both to prevent warning because interface_cls was not used and to check for exceptions */ if (interface_cls == NULL) { jclass Exception = (*jenv)->FindClass(jenv, "java/lang/Exception"); (*jenv)->ThrowNew(jenv, Exception, "Exception in cocoEvaluateConstraint\n"); } problem = (coco_problem_t *) jproblem_pointer; number_of_objectives = (int) coco_problem_get_number_of_objectives(problem); /* Call coco_evaluate_constraint */ x = (*jenv)->GetDoubleArrayElements(jenv, jx, NULL); y = coco_allocate_vector(number_of_objectives); coco_evaluate_constraint(problem, x, y); /* Prepare the return value */ jy = (*jenv)->NewDoubleArray(jenv, number_of_objectives); (*jenv)->SetDoubleArrayRegion(jenv, jy, 0, number_of_objectives, y); /* Free resources */ coco_free_memory(y); (*jenv)->ReleaseDoubleArrayElements(jenv, jx, x, JNI_ABORT); return jy; }
/** * A random search optimizer. */ void my_optimizer(coco_problem_t *problem) { const size_t budget = 2; coco_random_state_t *rng = coco_random_new(0xdeadbeef); const double *lbounds = coco_problem_get_smallest_values_of_interest(problem); const double *ubounds = coco_problem_get_largest_values_of_interest(problem); size_t dimension = coco_problem_get_dimension(problem); size_t number_of_objectives = coco_problem_get_number_of_objectives(problem); double *x = coco_allocate_vector(dimension); double *y = coco_allocate_vector(number_of_objectives); double range; size_t i, j; for (i = 0; i < budget; ++i) { for (j = 0; j < dimension; ++j) { range = ubounds[j] - lbounds[j]; x[j] = lbounds[j] + coco_random_uniform(rng) * range; } coco_evaluate_function(problem, x, y); } coco_random_free(rng); coco_free_memory(x); coco_free_memory(y); }
static void transform_vars_permblockdiag_evaluate(coco_problem_t *problem, const double *x, double *y) { size_t i, j, current_blocksize, first_non_zero_ind; transform_vars_permblockdiag_t *data; coco_problem_t *inner_problem; if (coco_vector_contains_nan(x, coco_problem_get_dimension(problem))) { coco_vector_set_to_nan(y, coco_problem_get_number_of_objectives(problem)); return; } data = (transform_vars_permblockdiag_t *) coco_problem_transformed_get_data(problem); inner_problem = coco_problem_transformed_get_inner_problem(problem); for (i = 0; i < inner_problem->number_of_variables; ++i) { current_blocksize = data->block_size_map[data->P2[i]];/*the block_size is that of the permuted line*/ first_non_zero_ind = data->first_non_zero_map[data->P2[i]]; data->x[i] = 0; /*compute data->x[i] = < B[P2[i]] , x[P1] > */ for (j = first_non_zero_ind; j < first_non_zero_ind + current_blocksize; ++j) {/*blocksize[P2[i]]*/ data->x[i] += data->B[data->P2[i]][j - first_non_zero_ind] * x[data->P1[j]];/*all B lines start at 0*/ } if (data->x[i] > 100 || data->x[i] < -100 || 1) { } } coco_evaluate_function(inner_problem, data->x, y); assert(y[0] + 1e-13 >= problem->best_value[0]); }
/** * @brief Evaluates the transformation. */ static void transform_vars_oscillate_evaluate(coco_problem_t *problem, const double *x, double *y) { static const double alpha = 0.1; double tmp, base, *oscillated_x; size_t i; transform_vars_oscillate_data_t *data; coco_problem_t *inner_problem; if (coco_vector_contains_nan(x, coco_problem_get_dimension(problem))) { coco_vector_set_to_nan(y, coco_problem_get_number_of_objectives(problem)); return; } data = (transform_vars_oscillate_data_t *) coco_problem_transformed_get_data(problem); oscillated_x = data->oscillated_x; /* short cut to make code more readable */ inner_problem = coco_problem_transformed_get_inner_problem(problem); for (i = 0; i < problem->number_of_variables; ++i) { if (x[i] > 0.0) { tmp = log(x[i]) / alpha; base = exp(tmp + 0.49 * (sin(tmp) + sin(0.79 * tmp))); oscillated_x[i] = pow(base, alpha); } else if (x[i] < 0.0) { tmp = log(-x[i]) / alpha; base = exp(tmp + 0.49 * (sin(0.55 * tmp) + sin(0.31 * tmp))); oscillated_x[i] = -pow(base, alpha); } else { oscillated_x[i] = 0.0; } } coco_evaluate_function(inner_problem, oscillated_x, y); assert(y[0] + 1e-13 >= problem->best_value[0]); }
/** * @note Can be used to prevent unnecessary burning of CPU time. */ int coco_problem_final_target_hit(const coco_problem_t *problem) { assert(problem != NULL); if (coco_problem_get_number_of_objectives(problem) != 1 || coco_problem_get_evaluations(problem) < 1) return 0; if (problem->best_value == NULL) return 0; return problem->best_observed_fvalue[0] <= problem->best_value[0] + problem->final_target_delta[0] ? 1 : 0; }
/* * Class: CocoJNI * Method: cocoProblemGetNumberOfObjectives * Signature: (J)I */ JNIEXPORT jint JNICALL Java_org_moeaframework_problem_BBOB2016_CocoJNI_cocoProblemGetNumberOfObjectives (JNIEnv *jenv, jclass interface_cls, jlong jproblem_pointer) { coco_problem_t *problem = NULL; jint jresult; /* This test is both to prevent warning because interface_cls was not used and to check for exceptions */ if (interface_cls == NULL) { jclass Exception = (*jenv)->FindClass(jenv, "java/lang/Exception"); (*jenv)->ThrowNew(jenv, Exception, "Exception in cocoProblemGetNumberOfObjectives\n"); } problem = (coco_problem_t *) jproblem_pointer; jresult = (jint) coco_problem_get_number_of_objectives(problem); return jresult; }
/** * @brief Evaluates the transformation. */ static void transform_vars_shift_evaluate(coco_problem_t *problem, const double *x, double *y) { size_t i; transform_vars_shift_data_t *data; coco_problem_t *inner_problem; if (coco_vector_contains_nan(x, coco_problem_get_dimension(problem))) { coco_vector_set_to_nan(y, coco_problem_get_number_of_objectives(problem)); return; } data = (transform_vars_shift_data_t *) coco_problem_transformed_get_data(problem); inner_problem = coco_problem_transformed_get_inner_problem(problem); for (i = 0; i < problem->number_of_variables; ++i) { data->shifted_x[i] = x[i] - data->offset[i]; } coco_evaluate_function(inner_problem, data->shifted_x, y); assert(y[0] + 1e-13 >= problem->best_value[0]); }
/* The gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { long long *ref; coco_problem_t *problem = NULL; const mwSize dims[2] = {1, 1}; int *res; /* check for proper number of arguments */ if(nrhs!=1) { mexErrMsgIdAndTxt("cocoProblemGetNumberOfObjectives:nrhs","One input required."); } /* get the problem */ ref = (long long *)mxGetData(prhs[0]); problem = (coco_problem_t *)(*ref); /* prepare the return value */ plhs[0] = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); res = (int *)mxGetData(plhs[0]); res[0] = coco_problem_get_number_of_objectives(problem); }
/** * @brief Evaluates the transformation. */ static void transform_vars_z_hat_evaluate(coco_problem_t *problem, const double *x, double *y) { size_t i; transform_vars_z_hat_data_t *data; coco_problem_t *inner_problem; if (coco_vector_contains_nan(x, coco_problem_get_dimension(problem))) { coco_vector_set_to_nan(y, coco_problem_get_number_of_objectives(problem)); return; } data = (transform_vars_z_hat_data_t *) coco_problem_transformed_get_data(problem); inner_problem = coco_problem_transformed_get_inner_problem(problem); data->z[0] = x[0]; for (i = 1; i < problem->number_of_variables; ++i) { data->z[i] = x[i] + 0.25 * (x[i - 1] - 2.0 * fabs(data->xopt[i - 1])); } coco_evaluate_function(inner_problem, data->z, y); assert(y[0] + 1e-13 >= problem->best_value[0]); }
/** * @brief Evaluates the transformation. */ static void transform_vars_affine_evaluate(coco_problem_t *problem, const double *x, double *y) { size_t i, j; transform_vars_affine_data_t *data; coco_problem_t *inner_problem; if (coco_vector_contains_nan(x, coco_problem_get_dimension(problem))) { coco_vector_set_to_nan(y, coco_problem_get_number_of_objectives(problem)); return; } data = (transform_vars_affine_data_t *) coco_problem_transformed_get_data(problem); inner_problem = coco_problem_transformed_get_inner_problem(problem); for (i = 0; i < inner_problem->number_of_variables; ++i) { /* data->M has problem->number_of_variables columns and inner_problem->number_of_variables rows. */ const double *current_row = data->M + i * problem->number_of_variables; data->x[i] = data->b[i]; for (j = 0; j < problem->number_of_variables; ++j) { data->x[i] += x[j] * current_row[j]; } } coco_evaluate_function(inner_problem, data->x, y); assert(y[0] + 1e-13 >= problem->best_value[0]); }
/** * Return a problem that stacks the output of two problems, namely * of coco_evaluate_function and coco_evaluate_constraint. The accepted * input remains the same and must be identical for the stacked * problems. * * This is particularly useful to generate multiobjective problems, * e.g. a biobjective problem from two single objective problems. * * Details: regions of interest must either agree or at least one * of them must be NULL. Best parameter becomes somewhat meaningless. */ coco_problem_t *coco_stacked_problem_allocate(coco_problem_t *problem1, coco_problem_t *problem2, void *userdata, coco_stacked_problem_free_data_t free_data) { const size_t number_of_variables = coco_problem_get_dimension(problem1); const size_t number_of_objectives = coco_problem_get_number_of_objectives(problem1) + coco_problem_get_number_of_objectives(problem2); const size_t number_of_constraints = coco_problem_get_number_of_constraints(problem1) + coco_problem_get_number_of_constraints(problem2); size_t i; char *s; const double *smallest, *largest; coco_stacked_problem_data_t *data; coco_problem_t *problem; /* the new coco problem */ assert(coco_problem_get_dimension(problem1) == coco_problem_get_dimension(problem2)); problem = coco_problem_allocate(number_of_variables, number_of_objectives, number_of_constraints); s = coco_strconcat(coco_problem_get_id(problem1), "__"); problem->problem_id = coco_strconcat(s, coco_problem_get_id(problem2)); coco_free_memory(s); s = coco_strconcat(coco_problem_get_name(problem1), " + "); problem->problem_name = coco_strconcat(s, coco_problem_get_name(problem2)); coco_free_memory(s); problem->evaluate_function = coco_stacked_problem_evaluate; if (number_of_constraints > 0) problem->evaluate_constraint = coco_stacked_problem_evaluate_constraint; /* set/copy "boundaries" and best_parameter */ smallest = problem1->smallest_values_of_interest; if (smallest == NULL) smallest = problem2->smallest_values_of_interest; largest = problem1->largest_values_of_interest; if (largest == NULL) largest = problem2->largest_values_of_interest; for (i = 0; i < number_of_variables; ++i) { if (problem2->smallest_values_of_interest != NULL) assert(smallest[i] == problem2->smallest_values_of_interest[i]); if (problem2->largest_values_of_interest != NULL) assert(largest[i] == problem2->largest_values_of_interest[i]); if (smallest != NULL) problem->smallest_values_of_interest[i] = smallest[i]; if (largest != NULL) problem->largest_values_of_interest[i] = largest[i]; if (problem->best_parameter) /* bbob2009 logger doesn't work then anymore */ coco_free_memory(problem->best_parameter); problem->best_parameter = NULL; if (problem->best_value) coco_free_memory(problem->best_value); problem->best_value = NULL; /* bbob2009 logger doesn't work */ } /* setup data holder */ data = coco_allocate_memory(sizeof(*data)); data->problem1 = problem1; data->problem2 = problem2; data->data = userdata; data->free_data = free_data; problem->data = data; problem->free_problem = coco_stacked_problem_free; /* free self->data and coco_problem_free(self) */ return problem; }