void idwt_wp(Image_tree dwts, gray **pixels) { Image image; int i, j; image = inv_transform(dwts, dwt_filters, dwt_method + 1); for (i = 0; i < dwt_rows; i++) for (j = 0; j < dwt_cols; j++) pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); printf("idwt_wp(): working!!\n"); free_image(image); }
void idwt(Image_tree dwts, gray *pixels) { Image image; int i, j; image = inv_transform(dwts, dwt_filters, dwt_method + 1); for (i = 0; i < dwt_rows; i++) for (j = 0; j < dwt_cols; j++) // pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); pixels[j + (i*(image->width))] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); // for (i = 0; i < (dwt_cols*dwt_rows); i++) pixels[i] = PIXELRANGE((int)(image->data[i] + 0.5)); free_image(image); free_image_tree(dwts); }
Cylinder::Cylinder( const Vec3& p1, const Vec3& p2, double r, const Shape& s ) : Shape(s) { const Matrix& TM = Matrix().setTranslation(p1); Vec3 p2_trans = p2 - p1; Vec3 rot_axis = cross(p2_trans, Vec3(0,0,1)); double rot_angle = acos( p2_trans.dir().dot(Vec3(0,0,1)) ); Matrix RM = Matrix(); if( rot_angle > ZERO ) { RM.setRotation(-rot_angle, rot_axis); } const Matrix& SM = Matrix().setScale( Vec4(r,r, (p2-p1).l2(), 1) ); transform() = transform() * TM * RM * SM; inv_transform() = transform().inverse(); }
bool Node::intersect(Ray &ray, DifferentialGeometry &diff_geom) const { if (bvh){ return bvh->intersect(ray, diff_geom); } assert(children.empty()); bool hit = false; Ray node_space = ray; inv_transform(ray, node_space); if (geometry){ hit = geometry->intersect(node_space, diff_geom); if (hit){ diff_geom.node = this; } } if (hit){ transform(diff_geom, diff_geom); ray.max_t = node_space.max_t; } return hit; }
inline bool cg_int(arma::vec& init_out_vals, std::function<double (const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data)> opt_objfn, void* opt_data, algo_settings_t* settings_inp) { // notation: 'p' stands for '+1'. // bool success = false; const size_t n_vals = init_out_vals.n_elem; // // CG settings algo_settings_t settings; if (settings_inp) { settings = *settings_inp; } const uint_t conv_failure_switch = settings.conv_failure_switch; const uint_t iter_max = settings.iter_max; const double err_tol = settings.err_tol; const uint_t cg_method = settings.cg_method; // update method const double cg_restart_threshold = settings.cg_restart_threshold; const double wolfe_cons_1 = 1E-03; // line search tuning parameters const double wolfe_cons_2 = 0.10; const bool vals_bound = settings.vals_bound; const arma::vec lower_bounds = settings.lower_bounds; const arma::vec upper_bounds = settings.upper_bounds; const arma::uvec bounds_type = determine_bounds_type(vals_bound, n_vals, lower_bounds, upper_bounds); // lambda function for box constraints std::function<double (const arma::vec& vals_inp, arma::vec* grad_out, void* box_data)> box_objfn \ = [opt_objfn, vals_bound, bounds_type, lower_bounds, upper_bounds] (const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data) \ -> double { if (vals_bound) { arma::vec vals_inv_trans = inv_transform(vals_inp, bounds_type, lower_bounds, upper_bounds); double ret; if (grad_out) { arma::vec grad_obj = *grad_out; ret = opt_objfn(vals_inv_trans,&grad_obj,opt_data); // arma::mat jacob_matrix = jacobian_adjust(vals_inp,bounds_type,lower_bounds,upper_bounds); arma::vec jacob_vec = arma::diagvec(jacobian_adjust(vals_inp,bounds_type,lower_bounds,upper_bounds)); // *grad_out = jacob_matrix * grad_obj; // no need for transpose as jacob_matrix is diagonal *grad_out = jacob_vec % grad_obj; } else { ret = opt_objfn(vals_inv_trans,nullptr,opt_data); } return ret; } else { return opt_objfn(vals_inp,grad_out,opt_data); } }; // // initialization arma::vec x = init_out_vals; if (!x.is_finite()) { printf("cg error: non-finite initial value(s).\n"); return false; } if (vals_bound) { // should we transform the parameters? x = transform(x, bounds_type, lower_bounds, upper_bounds); } arma::vec grad(n_vals); // gradient box_objfn(x,&grad,opt_data); // double err = arma::accu(arma::abs(grad)); double err = arma::norm(grad, 2); if (err <= err_tol) { return true; } // double t_init = 1.0; // initial value for line search arma::vec d = - grad, d_p; arma::vec x_p = x, grad_p = grad; double t = line_search_mt(t_init, x_p, grad_p, d, &wolfe_cons_1, &wolfe_cons_2, box_objfn, opt_data); err = arma::norm(grad_p, 2); if (err <= err_tol) { init_out_vals = x_p; return true; } // // begin loop uint_t iter = 0; while (err > err_tol && iter < iter_max) { iter++; // double beta = cg_update(grad,grad_p,d,iter,cg_method,cg_restart_threshold); d_p = - grad_p + beta*d; t_init = t * (arma::dot(grad,d) / arma::dot(grad_p,d_p)); grad = grad_p; t = line_search_mt(t_init, x_p, grad_p, d, &wolfe_cons_1, &wolfe_cons_2, box_objfn, opt_data); // err = arma::norm(grad_p, 2); d = d_p; x = x_p; } // if (vals_bound) { x_p = inv_transform(x_p, bounds_type, lower_bounds, upper_bounds); } error_reporting(init_out_vals,x_p,opt_objfn,opt_data,success,err,err_tol,iter,iter_max,conv_failure_switch,settings_inp); // return success; }
inline bool pso_int(arma::vec& init_out_vals, std::function<double (const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data)> opt_objfn, void* opt_data, algo_settings_t* settings_inp) { bool success = false; const size_t n_vals = init_out_vals.n_elem; // // PSO settings algo_settings_t settings; if (settings_inp) { settings = *settings_inp; } const uint_t conv_failure_switch = settings.conv_failure_switch; const double err_tol = settings.err_tol; const bool center_particle = settings.pso_center_particle; const size_t n_pop = (center_particle) ? settings.pso_n_pop + 1 : settings.pso_n_pop; const size_t n_gen = settings.pso_n_gen; const uint_t check_freq = (settings.pso_check_freq > 0) ? settings.pso_check_freq : n_gen ; const uint_t inertia_method = settings.pso_inertia_method; double par_w = settings.pso_par_initial_w; const double par_w_max = settings.pso_par_w_max; const double par_w_min = settings.pso_par_w_min; const double par_damp = settings.pso_par_w_damp; const uint_t velocity_method = settings.pso_velocity_method; double par_c_cog = settings.pso_par_c_cog; double par_c_soc = settings.pso_par_c_soc; const double par_initial_c_cog = settings.pso_par_initial_c_cog; const double par_final_c_cog = settings.pso_par_final_c_cog; const double par_initial_c_soc = settings.pso_par_initial_c_soc; const double par_final_c_soc = settings.pso_par_final_c_soc; const arma::vec par_initial_lb = (settings.pso_initial_lb.n_elem == n_vals) ? settings.pso_initial_lb : init_out_vals - 0.5; const arma::vec par_initial_ub = (settings.pso_initial_ub.n_elem == n_vals) ? settings.pso_initial_ub : init_out_vals + 0.5; const bool vals_bound = settings.vals_bound; const arma::vec lower_bounds = settings.lower_bounds; const arma::vec upper_bounds = settings.upper_bounds; const arma::uvec bounds_type = determine_bounds_type(vals_bound, n_vals, lower_bounds, upper_bounds); // lambda function for box constraints std::function<double (const arma::vec& vals_inp, arma::vec* grad_out, void* box_data)> box_objfn \ = [opt_objfn, vals_bound, bounds_type, lower_bounds, upper_bounds] (const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data) \ -> double { if (vals_bound) { arma::vec vals_inv_trans = inv_transform(vals_inp, bounds_type, lower_bounds, upper_bounds); return opt_objfn(vals_inv_trans,nullptr,opt_data); } else { return opt_objfn(vals_inp,nullptr,opt_data); } }; // // initialize arma::vec objfn_vals(n_pop); arma::mat P(n_pop,n_vals); #ifdef OPTIM_USE_OMP #pragma omp parallel for #endif for (size_t i=0; i < n_pop; i++) { if (center_particle && i == n_pop - 1) { P.row(i) = arma::sum(P.rows(0,n_pop-2),0) / static_cast<double>(n_pop-1); // center vector } else { P.row(i) = par_initial_lb.t() + (par_initial_ub.t() - par_initial_lb.t())%arma::randu(1,n_vals); } double prop_objfn_val = opt_objfn(P.row(i).t(),nullptr,opt_data); if (!std::isfinite(prop_objfn_val)) { prop_objfn_val = inf; } objfn_vals(i) = prop_objfn_val; if (vals_bound) { P.row(i) = arma::trans( transform(P.row(i).t(), bounds_type, lower_bounds, upper_bounds) ); } } arma::vec best_vals = objfn_vals; arma::mat best_vecs = P; double global_best_val = objfn_vals.min(); double global_best_val_check = global_best_val; arma::rowvec global_best_vec = P.row( objfn_vals.index_min() ); // // begin loop uint_t iter = 0; double err = 2.0*err_tol; arma::mat V = arma::zeros(n_pop,n_vals); while (err > err_tol && iter < n_gen) { iter++; // // parameter updating if (inertia_method == 1) { par_w = par_w_min + (par_w_max - par_w_min) * (iter + 1) / n_gen; } else { par_w *= par_damp; } if (velocity_method == 2) { par_c_cog = par_initial_c_cog - (par_initial_c_cog - par_final_c_cog) * (iter + 1) / n_gen; par_c_soc = par_initial_c_soc - (par_initial_c_soc - par_final_c_soc) * (iter + 1) / n_gen; } // // population loop #ifdef OPTIM_USE_OMP #pragma omp parallel for #endif for (size_t i=0; i < n_pop; i++) { if ( !(center_particle && i == n_pop - 1) ) { V.row(i) = par_w*V.row(i) + par_c_cog*arma::randu(1,n_vals)%(best_vecs.row(i) - P.row(i)) + par_c_soc*arma::randu(1,n_vals)%(global_best_vec - P.row(i)); P.row(i) += V.row(i); } else { P.row(i) = arma::sum(P.rows(0,n_pop-2),0) / static_cast<double>(n_pop-1); // center vector } // double prop_objfn_val = box_objfn(P.row(i).t(),nullptr,opt_data); if (!std::isfinite(prop_objfn_val)) { prop_objfn_val = inf; } objfn_vals(i) = prop_objfn_val; if (objfn_vals(i) < best_vals(i)) { best_vals(i) = objfn_vals(i); best_vecs.row(i) = P.row(i); } } uint_t min_objfn_val_index = best_vals.index_min(); double min_objfn_val = best_vals(min_objfn_val_index); if (min_objfn_val < global_best_val) { global_best_val = min_objfn_val; global_best_vec = best_vecs.row( min_objfn_val_index ); } if (iter%check_freq == 0) { err = std::abs(global_best_val - global_best_val_check) / (1.0 + std::abs(global_best_val)); if (global_best_val < global_best_val_check) { global_best_val_check = global_best_val; } } } // if (vals_bound) { global_best_vec = arma::trans( inv_transform(global_best_vec.t(), bounds_type, lower_bounds, upper_bounds) ); } error_reporting(init_out_vals,global_best_vec.t(),opt_objfn,opt_data,success,err,err_tol,iter,n_gen,conv_failure_switch,settings_inp); // return true; }
bool mcmc::de_int(const arma::vec& initial_vals, arma::cube& draws_out, std::function<double (const arma::vec& vals_inp, void* target_data)> target_log_kernel, void* target_data, algo_settings_t* settings_inp) { bool success = false; const size_t n_vals = initial_vals.n_elem; // // DE settings algo_settings_t settings; if (settings_inp) { settings = *settings_inp; } const size_t n_pop = settings.de_n_pop; const size_t n_gen = settings.de_n_gen; const size_t n_burnin = settings.de_n_burnin; const bool jumps = settings.de_jumps; const double par_b = settings.de_par_b; // const double par_gamma = settings.de_par_gamma; const double par_gamma = 2.38 / std::sqrt(2.0*n_vals); const double par_gamma_jump = settings.de_par_gamma_jump; const arma::vec par_initial_lb = (settings.de_initial_lb.n_elem == n_vals) ? settings.de_initial_lb : initial_vals - 0.5; const arma::vec par_initial_ub = (settings.de_initial_ub.n_elem == n_vals) ? settings.de_initial_ub : initial_vals + 0.5; const bool vals_bound = settings.vals_bound; const arma::vec lower_bounds = settings.lower_bounds; const arma::vec upper_bounds = settings.upper_bounds; const arma::uvec bounds_type = determine_bounds_type(vals_bound, n_vals, lower_bounds, upper_bounds); // lambda function for box constraints std::function<double (const arma::vec& vals_inp, void* box_data)> box_log_kernel \ = [target_log_kernel, vals_bound, bounds_type, lower_bounds, upper_bounds] (const arma::vec& vals_inp, void* target_data) \ -> double { if (vals_bound) { arma::vec vals_inv_trans = inv_transform(vals_inp, bounds_type, lower_bounds, upper_bounds); return target_log_kernel(vals_inv_trans, target_data) + log_jacobian(vals_inp, bounds_type, lower_bounds, upper_bounds); } else { return target_log_kernel(vals_inp, target_data); } }; // arma::vec target_vals(n_pop); arma::mat X(n_pop,n_vals); #ifdef MCMC_USE_OPENMP #pragma omp parallel for #endif for (size_t i=0; i < n_pop; i++) { X.row(i) = par_initial_lb.t() + (par_initial_ub.t() - par_initial_lb.t())%arma::randu(1,n_vals); double prop_kernel_val = box_log_kernel(X.row(i).t(),target_data); if (!std::isfinite(prop_kernel_val)) { prop_kernel_val = neginf; } target_vals(i) = prop_kernel_val; } // // begin MCMC run draws_out.set_size(n_pop,n_vals,n_gen); int n_accept = 0; double par_gamma_run = par_gamma; for (size_t j=0; j < n_gen + n_burnin; j++) { double temperature_j = de_cooling_schedule(j,n_gen); if (jumps && ((j+1) % 10 == 0)) { par_gamma_run = par_gamma_jump; } #ifdef MCMC_USE_OPENMP #pragma omp parallel for #endif for (size_t i=0; i < n_pop; i++) { uint_t R_1, R_2; do { R_1 = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_pop-1))); } while(R_1==i); do { R_2 = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_pop-1))); } while(R_2==i || R_2==R_1); // arma::vec prop_rand = arma::randu(n_vals,1)*(2*par_b) - par_b; // generate a vector of U[-b,b] RVs arma::rowvec X_prop = X.row(i) + par_gamma_run * ( X.row(R_1) - X.row(R_2) ) + prop_rand; double prop_kernel_val = box_log_kernel(X_prop.t(),target_data); if (!std::isfinite(prop_kernel_val)) { prop_kernel_val = neginf; } // double comp_val = prop_kernel_val - target_vals(i); double z = arma::as_scalar(arma::randu(1,1)); if (comp_val > temperature_j * std::log(z)) { X.row(i) = X_prop; target_vals(i) = prop_kernel_val; if (j >= n_burnin) { n_accept++; } } } // if (j >= n_burnin) { draws_out.slice(j-n_burnin) = X; } if (jumps && ((j+1) % 10 == 0)) { par_gamma_run = par_gamma; } } success = true; // if (vals_bound) { #ifdef MCMC_USE_OPENMP #pragma omp parallel for #endif for (size_t ii = 0; ii < n_gen; ii++) { for (size_t jj = 0; jj < n_pop; jj++) { draws_out.slice(ii).row(jj) = arma::trans(inv_transform(draws_out.slice(ii).row(jj).t(), bounds_type, lower_bounds, upper_bounds)); } } } if (settings_inp) { settings_inp->de_accept_rate = static_cast<double>(n_accept) / static_cast<double>(n_pop*n_gen); } // return success; }
void decrypt_block(uint32_t round_keys[NUM_ROUND_KEYS][ROUND_KEY_LENGTH], uint32_t current_block[BLOCK_LENGTH], uint32_t past_block[BLOCK_LENGTH], char* output, int test) { int last_byte_loc; uint32_t next_past_block[BLOCK_LENGTH]; // stores next_block so it can be set to current_block after CBC after decryption memcpy(next_past_block, current_block, BLOCK_LENGTH * BYTE_CHUNK_SIZE); /* * START CODE BLOCK * * Following code from serpent.c file in official submission code (http://www.cl.cam.ac.uk/~rja14/Papers/serpent.tar.gz) with minor name changes. See 'sboxes.h' for note on copyright. */ register uint32_t x0, x1, x2, x3; register uint32_t y0, y1, y2, y3; x0 = current_block[0]; x1 = current_block[1]; x2 = current_block[2]; x3 = current_block[3]; /* Start to decrypt the ciphertext x */ keying(x0, x1, x2, x3, round_keys[32]); InvRND31(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[31]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND30(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[30]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND29(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[29]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND28(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[28]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND27(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[27]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND26(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[26]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND25(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[25]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND24(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[24]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND23(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[23]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND22(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[22]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND21(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[21]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND20(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[20]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND19(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[19]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND18(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[18]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND17(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[17]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND16(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[16]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND15(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[15]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND14(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[14]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND13(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[13]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND12(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[12]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND11(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[11]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND10(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[10]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND09(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 9]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND08(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 8]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND07(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 7]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND06(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 6]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND05(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 5]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND04(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 4]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND03(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 3]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND02(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 2]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND01(x0, x1, x2, x3, y0, y1, y2, y3); keying(y0, y1, y2, y3, round_keys[ 1]); inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); InvRND00(x0, x1, x2, x3, y0, y1, y2, y3); x0 = y0; x1 = y1; x2 = y2; x3 = y3; keying(x0, x1, x2, x3, round_keys[ 0]); /* The plaintext is now in x */ current_block[0] = x0; current_block[1] = x1; current_block[2] = x2; current_block[3] = x3; /* * END CODE BLOCK */ if (!test) { decrypt_cbc(current_block, past_block); } last_byte_loc = unpad(current_block); decrypt_export_block(output, current_block, last_byte_loc); memcpy(past_block, next_past_block, BLOCK_LENGTH * BYTE_CHUNK_SIZE); }
inline bool de_prmm_int(arma::vec& init_out_vals, std::function<double (const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data)> opt_objfn, void* opt_data, algo_settings_t* settings_inp) { bool success = false; const size_t n_vals = init_out_vals.n_elem; // // DE settings algo_settings_t settings; if (settings_inp) { settings = *settings_inp; } const uint_t conv_failure_switch = settings.conv_failure_switch; const double err_tol = settings.err_tol; size_t n_pop = settings.de_n_pop; // const size_t check_freq = settings.de_check_freq; const double par_initial_F = settings.de_par_F; const double par_initial_CR = settings.de_par_CR; const arma::vec par_initial_lb = (settings.de_initial_lb.n_elem == n_vals) ? settings.de_initial_lb : init_out_vals - 0.5; const arma::vec par_initial_ub = (settings.de_initial_ub.n_elem == n_vals) ? settings.de_initial_ub : init_out_vals + 0.5; const double F_l = settings.de_par_F_l; const double F_u = settings.de_par_F_u; const double tau_F = settings.de_par_tau_F; const double tau_CR = settings.de_par_tau_CR; arma::vec F_vec(n_pop), CR_vec(n_pop); F_vec.fill(par_initial_F); CR_vec.fill(par_initial_CR); const uint_t max_fn_eval = settings.de_max_fn_eval; const uint_t pmax = settings.de_pmax; const size_t n_pop_best = settings.de_n_pop_best; const double d_eps = 0.5; size_t n_gen = std::ceil(max_fn_eval / (pmax*n_pop)); const bool vals_bound = settings.vals_bound; const arma::vec lower_bounds = settings.lower_bounds; const arma::vec upper_bounds = settings.upper_bounds; const arma::uvec bounds_type = determine_bounds_type(vals_bound, n_vals, lower_bounds, upper_bounds); // lambda function for box constraints std::function<double (const arma::vec& vals_inp, arma::vec* grad_out, void* box_data)> box_objfn \ = [opt_objfn, vals_bound, bounds_type, lower_bounds, upper_bounds] (const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data) \ -> double { if (vals_bound) { arma::vec vals_inv_trans = inv_transform(vals_inp, bounds_type, lower_bounds, upper_bounds); return opt_objfn(vals_inv_trans,nullptr,opt_data); } else { return opt_objfn(vals_inp,nullptr,opt_data); } }; // // setup arma::vec objfn_vals(n_pop); arma::mat X(n_pop,n_vals), X_next(n_pop,n_vals); #ifdef OPTIM_USE_OMP #pragma omp parallel for #endif for (size_t i=0; i < n_pop; i++) { X_next.row(i) = par_initial_lb.t() + (par_initial_ub.t() - par_initial_lb.t())%arma::randu(1,n_vals); double prop_objfn_val = opt_objfn(X_next.row(i).t(),nullptr,opt_data); if (!std::isfinite(prop_objfn_val)) { prop_objfn_val = inf; } objfn_vals(i) = prop_objfn_val; if (vals_bound) { X_next.row(i) = arma::trans( transform(X_next.row(i).t(), bounds_type, lower_bounds, upper_bounds) ); } } double best_objfn_val_running = objfn_vals.min(); // double best_objfn_val_check = best_objfn_val_running; double best_val_main = best_objfn_val_running; double best_val_best = best_objfn_val_running; arma::rowvec best_sol_running = X_next.row( objfn_vals.index_min() ); arma::rowvec best_vec_main = best_sol_running; arma::rowvec best_vec_best = best_sol_running; arma::rowvec xchg_vec = best_sol_running; // uint_t n_reset = 1; uint_t iter = 0; double err = 2*err_tol; while (err > err_tol && iter < n_gen + 1) { iter++; // // population reduction step if (iter == n_gen && n_reset < 4) { size_t n_pop_temp = n_pop/2; arma::vec objfn_vals_reset(n_pop_temp); arma::mat X_reset(n_pop_temp,n_vals); #ifdef OPTIM_USE_OMP #pragma omp parallel for #endif for (size_t j=0; j < n_pop_temp; j++) { if (objfn_vals(j) < objfn_vals(j + n_pop_temp)) { X_reset.row(j) = X_next.row(j); objfn_vals_reset(j) = objfn_vals(j); } else { X_reset.row(j) = X_next.row(j + n_pop_temp); objfn_vals_reset(j) = objfn_vals(j + n_pop_temp); } } objfn_vals = objfn_vals_reset; X_next = X_reset; n_pop /= 2; n_gen *= 2; iter = 1; n_reset++; } X = X_next; // // first population: n_pop - n_pop_best #ifdef OPTIM_USE_OMP #pragma omp parallel for #endif for (size_t i=0; i < n_pop - n_pop_best; i++) { arma::vec rand_pars = arma::randu(4); if (rand_pars(0) < tau_F) { F_vec(i) = F_l + (F_u-F_l)*rand_pars(1); } if (rand_pars(2) < tau_CR) { CR_vec(i) = rand_pars(3); } // uint_t c_1, c_2, c_3; do { c_1 = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_pop-1))); } while(c_1==i); do { c_2 = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_pop-1))); } while(c_2==i || c_2==c_1); do { c_3 = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_pop-1))); } while(c_3==i || c_3==c_1 || c_3==c_2); // size_t j = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_vals-1))); arma::vec rand_unif = arma::randu(n_vals); arma::rowvec X_prop(n_vals); for (size_t k=0; k < n_vals; k++) { if ( rand_unif(k) < CR_vec(i) || k == j ) { double r_s = arma::as_scalar(arma::randu(1)); if ( r_s < 0.75 || n_pop >= 100 ) { X_prop(k) = X(c_3,k) + F_vec(i)*(X(c_1,k) - X(c_2,k)); } else { X_prop(k) = best_vec_main(k) + F_vec(i)*(X(c_1,k) - X(c_2,k)); } } else { X_prop(k) = X(i,k); } } // double prop_objfn_val = box_objfn(X_prop.t(),nullptr,opt_data); if (prop_objfn_val <= objfn_vals(i)) { X_next.row(i) = X_prop; objfn_vals(i) = prop_objfn_val; } else { X_next.row(i) = X.row(i); } } best_val_main = objfn_vals.rows(0,n_pop - n_pop_best - 1).min(); best_vec_main = X_next.rows(0,n_pop - n_pop_best - 1).row( objfn_vals.rows(0,n_pop - n_pop_best - 1).index_min() ); if (best_val_main < best_val_best) { xchg_vec = best_vec_main; } // // second population for (size_t i = n_pop - n_pop_best; i < n_pop; i++) { arma::vec rand_pars = arma::randu(4); if (rand_pars(0) < tau_F) { F_vec(i) = F_l + (F_u-F_l)*rand_pars(1); } if (rand_pars(2) < tau_CR) { CR_vec(i) = rand_pars(3); } // uint_t c_1, c_2; do { c_1 = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_pop-1))); } while(c_1==i); do { c_2 = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_pop-1))); } while(c_2==i || c_2==c_1); // size_t j = arma::as_scalar(arma::randi(1, arma::distr_param(0, n_vals-1))); arma::vec rand_unif = arma::randu(n_vals); arma::rowvec X_prop(n_vals); for (size_t k=0; k < n_vals; k++) { if ( rand_unif(k) < CR_vec(i) || k == j ) { X_prop(k) = best_vec_best(k) + F_vec(i)*(X(c_1,k) - X(c_2,k)); } else { X_prop(k) = X(i,k); } } // double prop_objfn_val = box_objfn(X_prop.t(),nullptr,opt_data); if (prop_objfn_val <= objfn_vals(i)) { X_next.row(i) = X_prop; objfn_vals(i) = prop_objfn_val; } else { X_next.row(i) = X.row(i); } } best_val_best = objfn_vals.rows(n_pop - n_pop_best, n_pop - 1).min(); best_vec_best = X_next.rows(n_pop - n_pop_best, n_pop - 1).row( objfn_vals.rows(n_pop - n_pop_best, n_pop - 1).index_min() ); if (best_val_best < best_val_main) { double the_sum = 0; for (size_t j=0; j < n_vals; j++) { double min_val = X.col(j).min(); the_sum += (best_vec_best(j) - min_val) / (xchg_vec(j) - min_val); } the_sum /= static_cast<double>(n_vals); if (std::abs(the_sum - 1.0) > d_eps) { best_vec_main = best_vec_best; } else { best_vec_best = best_vec_main; } } else { best_vec_best = best_vec_main; } // // assign running global minimum if (objfn_vals.min() < best_objfn_val_running) { best_objfn_val_running = objfn_vals.min(); best_sol_running = X_next.row( objfn_vals.index_min() ); } // if (iter%check_freq == 0) { // // err = std::abs(objfn_vals.min() - best_objfn_val) / (std::abs(best_objfn_val) + 1E-08); // err = std::abs(best_objfn_val_running - best_objfn_val_check); // // best_objfn_val_check = objfn_vals.min(); // if (best_objfn_val_running < best_objfn_val_check) { // best_objfn_val_check = best_objfn_val_running; // } // } } // if (vals_bound) { best_sol_running = arma::trans( inv_transform(best_sol_running.t(), bounds_type, lower_bounds, upper_bounds) ); } error_reporting(init_out_vals,best_sol_running.t(),opt_objfn,opt_data,success,err,err_tol,iter,n_gen,conv_failure_switch,settings_inp); // return true; }