finite_difference_Jacobian_to_gradient.cpp
Go to the documentation of this file.
1 // Copyright 2019, University of Maryland and the MANGO development team.
2 //
3 // This file is part of MANGO.
4 //
5 // MANGO is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License as
7 // published by the Free Software Foundation, either version 3 of the
8 // License, or (at your option) any later version.
9 //
10 // MANGO is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with MANGO. If not, see
17 // <https://www.gnu.org/licenses/>.
18 
19 #include <iostream>
20 #include <iomanip>
21 #include <cstring>
22 #include <stdexcept>
23 #include "mango.hpp"
24 #include "Least_squares_solver.hpp"
25 
26 void mango::Least_squares_solver::finite_difference_gradient(const double* state_vector, double* base_case_objective_function, double* gradient) {
27  // This subroutine overrides mango::Solver::finite_difference_gradient.
28  // gradient should have been allocated already, with size N_parameters.
29 
30  if (verbose > 0) std::cout << "Hello from finite_difference_Jacobian_to_gradient from proc " << mpi_partition->get_rank_world() << std::endl;
31  if (!mpi_partition->get_proc0_world()) throw std::runtime_error("Only proc0_world should get here!");
32 
33  double* base_case_residual_vector = new double[N_terms];
34  double* Jacobian = new double[N_terms * N_parameters];
35 
36  finite_difference_Jacobian(state_vector, base_case_residual_vector, Jacobian);
37 
38  int j_parameter, j_term;
39  double term;
40  *base_case_objective_function = 0;
41  memset(gradient, 0, N_parameters*sizeof(double));
42  for (j_term=0; j_term<N_terms; j_term++) {
43  term = (base_case_residual_vector[j_term] - targets[j_term]) / sigmas[j_term];
44  *base_case_objective_function += term*term;
45  for (j_parameter=0; j_parameter<N_parameters; j_parameter++) {
46  gradient[j_parameter] += 2 * (term / sigmas[j_term]) * Jacobian[j_parameter*N_terms + j_term];
47  }
48  }
49 
50  delete[] base_case_residual_vector;
51  delete[] Jacobian;
52 
53 }
Least_squares_solver.hpp
mango::Least_squares_solver::N_terms
int N_terms
Definition: Least_squares_solver.hpp:38
mango::Least_squares_solver::sigmas
double * sigmas
Definition: Least_squares_solver.hpp:40
mango::Solver::verbose
int verbose
Definition: Solver.hpp:63
mango::Solver::state_vector
double * state_vector
Definition: Solver.hpp:58
mango::Solver::mpi_partition
MPI_Partition * mpi_partition
Definition: Solver.hpp:65
mango.hpp
mango::MPI_Partition::get_rank_world
int get_rank_world()
Get the MPI rank of this processor in MANGO's world communicator.
Definition: mpi_partition.cpp:66
mango::Solver::N_parameters
int N_parameters
Definition: Solver.hpp:43
mango::Least_squares_solver::finite_difference_Jacobian
void finite_difference_Jacobian(const double *, double *, double *)
Definition: Least_squares_solver.cpp:54
mango::MPI_Partition::get_proc0_world
bool get_proc0_world()
Determine whether this MPI processor has rank 0 in MANGO's world communicator.
Definition: mpi_partition.cpp:56
mango::Least_squares_solver::finite_difference_gradient
void finite_difference_gradient(const double *, double *, double *)
Definition: finite_difference_Jacobian_to_gradient.cpp:26
mango::Least_squares_solver::targets
double * targets
Definition: Least_squares_solver.hpp:39