Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Double Engine::optimise(adolc::CallBack& objective,
- vector<Double>& start_values, vector<Double>& lower_bounds,
- vector<Double>& upper_bounds, int& convergence, int& max_iterations,
- int& max_evaluations, Double gradient_tolerance, double **out_hessian,
- int untransformed_hessians, Double step_size) {
- // Variables
- unsigned parameter_count = start_values.size();
- double obj_score = 0.0;
- adouble aobj_score = 0.0;
- Double penalty = 0.0;
- vector<double> scaled_candidate_values(parameter_count, 0.0);
- vector<double> gradient_values(parameter_count, 0.0);
- /**
- * Validate our values, bounds etc
- */
- if (lower_bounds.size() != parameter_count)
- LOG_CODE_ERROR("lower_bounds.size() != parameter_count")
- if (upper_bounds.size() != parameter_count)
- LOG_CODE_ERROR("upper_bounds.size() != parameter_count")
- // Create our Minimiser
- FMM fmm(parameter_count, max_evaluations, max_iterations, gradient_tolerance.value());
- vector<adouble> candidates(parameter_count, 0.0);
- vector<adouble> scaled_candidates(parameter_count, 0.0);
- /**
- * Scale our start values
- */
- cout << "Start Values (scaled): ";
- for (unsigned i = 0; i < start_values.size(); ++i) {
- if (start_values[i] < lower_bounds[i])
- LOG_CODE_ERROR("start_values[i] < lower_bounds[i]");
- if (start_values[i] > upper_bounds[i])
- LOG_CODE_ERROR("start_values[i] > upper_bounds[i]");
- if (dc::IsEqual(lower_bounds[i], upper_bounds[i]))
- scaled_candidates[i] = 0.0;
- else
- scaled_candidates[i] = math::scale_value(start_values[i], lower_bounds[i], upper_bounds[i]);
- cout << scaled_candidates[i] << ", ";
- }
- cout << endl;
- // Loop through our Minimiser now
- while (fmm.getResult() >= 0) {
- // Do we need to evaluate objective function again?
- if ((fmm.getResult() == 0) || (fmm.getResult() == 2)) {
- cout << "About to trace the objective (model)" << endl;
- trace_on(0);
- // declare our dependent variables
- for (unsigned i = 0; i < candidates.size(); ++i)
- scaled_candidates[i] <<= scaled_candidates[i].value();
- // Reset Variables
- penalty = 0.0;
- // unscale candidates
- cout << "candidates (unscaled): ";
- for (unsigned i = 0; i < parameter_count; ++i) {
- if (dc::IsEqual(lower_bounds[i], upper_bounds[i]))
- candidates[i] = lower_bounds[i];
- else
- candidates[i] = math::unscale_value(scaled_candidates[i], penalty, lower_bounds[i], upper_bounds[i]);
- cout << candidates[i] << ", ";
- }
- cout << endl;
- cout << "Running Model: Start -->";
- aobj_score = objective(candidates);
- cout << " End" << endl;
- aobj_score += penalty; // penalty for breaking bounds
- aobj_score >>= obj_score;
- trace_off();
- cout << "Finished objective function call with score = " << obj_score << " (inc Penalty: " << penalty << ")" << endl;
- }
- // Gradient Required
- // This will loop through each variable changing it once
- // to see how the other variables change.
- // There-by generating our co-variance
- if (fmm.getResult() >= 1) { // 1 = Gradient Required
- cout << "About to eval gradient" << endl;
- double* adolc_x = new double[parameter_count];
- double* adolc_g = new double[parameter_count];
- cout << "adolc_x: ";
- for (unsigned i = 0; i < parameter_count; ++i) {
- adolc_x[i] = scaled_candidates[i].value();
- cout << adolc_x[i] << ", ";
- }
- cout << endl;
- int g_status = gradient(0, parameter_count, adolc_x, adolc_g);
- // double one = 1.0;
- // int g_status = fos_reverse(0, 1, parameter_count, &one, adolc_g);
- cout << "Finished gradient call with status: " << g_status << endl;
- cout << "gradient: ";
- for (unsigned i = 0; i < parameter_count; ++i) {
- gradient_values[i] = adolc_g[i];
- cout << gradient_values[i] << ", ";
- }
- cout << endl;
- delete [] adolc_x;
- delete [] adolc_g;
- // Gradient Finished
- }
- /**
- * Scale our candidates in to candidate_values so we can
- * pass them to fmin() which will build use a new set of
- * scaled candidates.
- *
- * Then we assign them back so they can be unscaled during
- * the trace
- */
- cout << "before: ";
- for (unsigned i = 0; i < candidates.size(); ++i) {
- scaled_candidate_values[i] = scaled_candidates[i].value();
- cout << scaled_candidate_values[i] << ",";
- }
- cout << endl;
- fmm.fMin(scaled_candidate_values, obj_score, gradient_values);
- cout << "after: ";
- for (unsigned i = 0; i < candidates.size(); ++i) {
- scaled_candidates[i] = scaled_candidate_values[i];
- cout << scaled_candidates[i] << ", ";
- }
- cout << endl;
- cout << "FMM score: " << obj_score << endl;
- cout << "FMM Result: " << fmm.getResult() << endl;
- }
- if (fmm.getResult() == -3)
- cout << "Convergence Unclear" << endl;
- else if (fmm.getResult() == -2)
- cout << "Max Evaluations" << endl;
- else if (fmm.getResult() == -1)
- cout << "BAM CONVERGENCE" << endl;
- else
- cout << "UNKNOWN RETURN VALUE: " << fmm.getResult() << endl;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement