34 assert(*N_parameters == 3);
35 *f = exp(x[0] * x[0] - exp(x[1]) + sin(x[2]));
43 best_state_vector =
new double[N_parameters];
44 state_vector =
new double[N_parameters];
45 double* gradient =
new double[N_parameters];
47 function_evaluations = 0;
49 double base_case_objective_function;
53 auto N_worker_groups_requested = GENERATE(range(1,5));
54 mpi_partition->set_N_worker_groups(N_worker_groups_requested);
55 mpi_partition->init(MPI_COMM_WORLD);
58 state_vector[0] = 1.2;
59 state_vector[1] = 0.9;
60 state_vector[2] = -0.4;
62 finite_difference_step_size = 1.0e-7;
63 double correct_objective_function = 2.443823056453063e-01;
65 SECTION(
"1-sided differences") {
66 centered_differences =
false;
68 if (mpi_partition->get_proc0_world()) {
70 finite_difference_gradient(state_vector, &base_case_objective_function, gradient);
73 MPI_Bcast(&data,1,MPI_INT,0,mpi_partition->get_comm_group_leaders());
76 if (mpi_partition->get_proc0_worker_groups()) {
83 if (mpi_partition->get_proc0_world()) {
86 CHECK( function_evaluations == 4);
87 CHECK(base_case_objective_function == Approx(correct_objective_function).epsilon(1e-14));
88 CHECK( gradient[0] == Approx( 5.865176283537110e-01).epsilon(1e-13));
89 CHECK( gradient[1] == Approx(-6.010834349701177e-01).epsilon(1e-13));
90 CHECK( gradient[2] == Approx( 2.250910244305793e-01).epsilon(1e-13));
94 SECTION(
"centered differences") {
95 centered_differences =
true;
97 if (mpi_partition->get_proc0_world()) {
99 finite_difference_gradient(state_vector, &base_case_objective_function, gradient);
102 MPI_Bcast(&data,1,MPI_INT,0,mpi_partition->get_comm_group_leaders());
105 if (mpi_partition->get_proc0_worker_groups()) {
106 group_leaders_loop();
112 if (mpi_partition->get_proc0_world()) {
115 CHECK( function_evaluations == 7);
116 CHECK(base_case_objective_function == Approx(correct_objective_function).epsilon(1e-14));
117 CHECK( gradient[0] == Approx( 5.865175337071982e-01).epsilon(1e-13));
118 CHECK( gradient[1] == Approx(-6.010834789627051e-01).epsilon(1e-13));
119 CHECK( gradient[2] == Approx( 2.250910093037906e-01).epsilon(1e-13));
123 delete[] state_vector;
133 assert(*N_parameters == 2);
134 assert(*N_terms == 4);
135 for (
int j = 0; j < *N_terms; j++) {
136 f[j] = exp(j + x[0] * x[0] - exp(x[1]));
146 best_state_vector =
new double[N_parameters];
147 residuals =
new double[N_terms];
148 double* base_case_residuals =
new double[N_terms];
149 state_vector =
new double[N_parameters];
150 double* Jacobian =
new double[N_parameters * N_terms];
151 targets =
new double[N_terms];
152 sigmas =
new double[N_terms];
153 best_residual_function =
new double[N_terms];
154 double* gradient =
new double[N_parameters];
155 double base_case_objective_function;
158 function_evaluations = 0;
162 auto N_worker_groups_requested = GENERATE(range(1,5));
164 mpi_partition->set_N_worker_groups(N_worker_groups_requested);
165 mpi_partition->init(MPI_COMM_WORLD);
168 state_vector[0] = 1.2;
169 state_vector[1] = 0.9;
172 for (
int j=0; j<N_terms; j++) {
173 targets[j] = 1.5 + 2 * j;
174 sigmas[j] = 0.8 + 1.3 * j;
177 finite_difference_step_size = 1.0e-7;
180 double correct_residuals[] = {3.607380846860443e-01, 9.805877804351946e-01, 2.665513944765978e+00, 7.245618119561541e+00};
181 double correct_d_residuals_d_x0_1sided[] = { 8.657715439008840e-01, 2.353411054922816e+00, 6.397234502131255e+00, 1.738948636642590e+01};
182 double correct_d_residuals_d_x0_centered[] = { 8.657714037352271e-01, 2.353410674116319e+00, 6.397233469623842e+00, 1.738948351093228e+01};
183 double correct_d_residuals_d_x1_1sided[] = {-8.872724499564555e-01, -2.411856577788640e+00, -6.556105911492693e+00, -1.782134355643450e+01};
184 double correct_d_residuals_d_x1_centered[] = {-8.872725151820582e-01, -2.411856754314101e+00, -6.556106388888594e+00, -1.782134486205678e+01};
188 double correct_objective_function = 0;
189 double correct_gradient_1sided[] = {0.0, 0.0};
190 double correct_gradient_centered[] = {0.0, 0.0};
191 for (
int j=0; j<N_terms; j++) {
192 temp = (correct_residuals[j] - targets[j]) / sigmas[j];
193 correct_objective_function += temp * temp;
194 correct_gradient_1sided[0] += 2 * (correct_residuals[j] - targets[j]) / (sigmas[j] * sigmas[j]) * correct_d_residuals_d_x0_1sided[j];
195 correct_gradient_1sided[1] += 2 * (correct_residuals[j] - targets[j]) / (sigmas[j] * sigmas[j]) * correct_d_residuals_d_x1_1sided[j];
196 correct_gradient_centered[0] += 2 * (correct_residuals[j] - targets[j]) / (sigmas[j] * sigmas[j]) * correct_d_residuals_d_x0_centered[j];
197 correct_gradient_centered[1] += 2 * (correct_residuals[j] - targets[j]) / (sigmas[j] * sigmas[j]) * correct_d_residuals_d_x1_centered[j];
200 SECTION(
"1-sided differences, Jacobian") {
201 centered_differences =
false;
203 if (mpi_partition->get_proc0_world()) {
205 finite_difference_Jacobian(state_vector, base_case_residuals, Jacobian);
208 MPI_Bcast(&data,1,MPI_INT,0,mpi_partition->get_comm_group_leaders());
211 if (mpi_partition->get_proc0_worker_groups()) {
212 group_leaders_loop();
218 if (mpi_partition->get_proc0_world()) {
231 CHECK(function_evaluations == 3);
234 CHECK(base_case_residuals[0] == Approx(correct_residuals[0]).epsilon(1e-14));
235 CHECK(base_case_residuals[1] == Approx(correct_residuals[1]).epsilon(1e-14));
236 CHECK(base_case_residuals[2] == Approx(correct_residuals[2]).epsilon(1e-14));
237 CHECK(base_case_residuals[3] == Approx(correct_residuals[3]).epsilon(1e-14));
240 CHECK(Jacobian[0] == Approx(correct_d_residuals_d_x0_1sided[0]).epsilon(1e-13));
241 CHECK(Jacobian[1] == Approx(correct_d_residuals_d_x0_1sided[1]).epsilon(1e-13));
242 CHECK(Jacobian[2] == Approx(correct_d_residuals_d_x0_1sided[2]).epsilon(1e-13));
243 CHECK(Jacobian[3] == Approx(correct_d_residuals_d_x0_1sided[3]).epsilon(1e-13));
245 CHECK(Jacobian[4] == Approx(correct_d_residuals_d_x1_1sided[0]).epsilon(1e-13));
246 CHECK(Jacobian[5] == Approx(correct_d_residuals_d_x1_1sided[1]).epsilon(1e-13));
247 CHECK(Jacobian[6] == Approx(correct_d_residuals_d_x1_1sided[2]).epsilon(1e-13));
248 CHECK(Jacobian[7] == Approx(correct_d_residuals_d_x1_1sided[3]).epsilon(1e-13));
252 SECTION(
"Centered differences, Jacobian") {
253 centered_differences =
true;
255 if (mpi_partition->get_proc0_world()) {
257 finite_difference_Jacobian(state_vector, base_case_residuals, Jacobian);
260 MPI_Bcast(&data,1,MPI_INT,0,mpi_partition->get_comm_group_leaders());
263 if (mpi_partition->get_proc0_worker_groups()) {
264 group_leaders_loop();
270 if (mpi_partition->get_proc0_world()) {
283 CHECK(function_evaluations == 5);
286 CHECK(base_case_residuals[0] == Approx(correct_residuals[0]).epsilon(1e-14));
287 CHECK(base_case_residuals[1] == Approx(correct_residuals[1]).epsilon(1e-14));
288 CHECK(base_case_residuals[2] == Approx(correct_residuals[2]).epsilon(1e-14));
289 CHECK(base_case_residuals[3] == Approx(correct_residuals[3]).epsilon(1e-14));
292 CHECK(Jacobian[0] == Approx(correct_d_residuals_d_x0_centered[0]).epsilon(1e-13));
293 CHECK(Jacobian[1] == Approx(correct_d_residuals_d_x0_centered[1]).epsilon(1e-13));
294 CHECK(Jacobian[2] == Approx(correct_d_residuals_d_x0_centered[2]).epsilon(1e-13));
295 CHECK(Jacobian[3] == Approx(correct_d_residuals_d_x0_centered[3]).epsilon(1e-13));
297 CHECK(Jacobian[4] == Approx(correct_d_residuals_d_x1_centered[0]).epsilon(1e-13));
298 CHECK(Jacobian[5] == Approx(correct_d_residuals_d_x1_centered[1]).epsilon(1e-13));
299 CHECK(Jacobian[6] == Approx(correct_d_residuals_d_x1_centered[2]).epsilon(1e-13));
300 CHECK(Jacobian[7] == Approx(correct_d_residuals_d_x1_centered[3]).epsilon(1e-13));
304 SECTION(
"1-sided differences, gradient") {
305 centered_differences =
false;
307 if (mpi_partition->get_proc0_world()) {
309 finite_difference_gradient(state_vector, &base_case_objective_function, gradient);
312 MPI_Bcast(&data,1,MPI_INT,0,mpi_partition->get_comm_group_leaders());
315 if (mpi_partition->get_proc0_worker_groups()) {
316 group_leaders_loop();
322 if (mpi_partition->get_proc0_world()) {
324 CHECK(function_evaluations == 3);
326 CHECK(base_case_objective_function == Approx(correct_objective_function).epsilon(1e-14));
328 CHECK(gradient[0] == Approx(correct_gradient_1sided[0]).epsilon(1e-13));
329 CHECK(gradient[1] == Approx(correct_gradient_1sided[1]).epsilon(1e-13));
332 SECTION(
"Centered differences, gradient") {
333 centered_differences =
true;
335 if (mpi_partition->get_proc0_world()) {
337 finite_difference_gradient(state_vector, &base_case_objective_function, gradient);
340 MPI_Bcast(&data,1,MPI_INT,0,mpi_partition->get_comm_group_leaders());
343 if (mpi_partition->get_proc0_worker_groups()) {
344 group_leaders_loop();
350 if (mpi_partition->get_proc0_world()) {
352 CHECK(function_evaluations == 5);
354 CHECK(base_case_objective_function == Approx(correct_objective_function).epsilon(1e-14));
356 CHECK(gradient[0] == Approx(correct_gradient_centered[0]).epsilon(1e-13));
357 CHECK(gradient[1] == Approx(correct_gradient_centered[1]).epsilon(1e-13));
361 delete[] state_vector;
365 delete[] best_residual_function;
366 delete[] base_case_residuals;