Program Listing for File optimizationProblem.h¶
↰ Return to documentation for file (include/parpeoptimization/optimizationProblem.h
)
#ifndef OPTIMIZATION_PROBLEM_H
#define OPTIMIZATION_PROBLEM_H
#include <parpeoptimization/optimizationOptions.h>
#include <parpeoptimization/optimizationResultWriter.h>
#include <parpecommon/functions.h>
#include <parpecommon/logging.h>
#include <vector>
#include <hdf5.h>
#include <gsl/gsl-lite.hpp>
namespace parpe {
class OptimizationReporter;
class OptimizationReporter: public GradientFunction {
public:
OptimizationReporter(GradientFunction *gradFun,
std::unique_ptr<Logger> logger);
OptimizationReporter(GradientFunction *gradFun,
std::unique_ptr<OptimizationResultWriter> rw,
std::unique_ptr<Logger> logger);
FunctionEvaluationStatus evaluate(gsl::span<double const> parameters,
double &fval,
gsl::span<double> gradient,
Logger *logger = nullptr,
double *cpuTime = nullptr) const override;
int numParameters() const override;
virtual bool starting(gsl::span<const double> initialParameters) const;
virtual bool iterationFinished(gsl::span<const double> parameters,
double objectiveFunctionValue,
gsl::span<const double> objectiveFunctionGradient) const;
virtual bool beforeCostFunctionCall(gsl::span<const double> parameters) const;
virtual bool afterCostFunctionCall(gsl::span<const double> parameters,
double objectiveFunctionValue,
gsl::span<double const> objectiveFunctionGradient) const;
virtual void finished(double optimalCost,
gsl::span<const double> parameters,
int exitStatus) const;
// TODO how to pass optimizer-specific info? pass OptimizerStatus class ?
// virtual int intermediateFunction(int alg_mod, int iter_count,
// double obj_value, double inf_pr,
// double inf_du, double mu, double d_norm,
// double regularization_size,
// double alpha_du, double alpha_pr,
// int ls_trials);
virtual double getFinalCost() const;
virtual std::vector<double> const& getFinalParameters() const;
void setGradientFunction(GradientFunction *gradFun) const;
std::vector<std::string> getParameterIds() const override;
std::unique_ptr<OptimizationResultWriter> result_writer_;
mutable double cpu_time_total_sec_ = 0.0;
mutable double cpu_time_iteration_sec_ = 0.0;
std::unique_ptr<Logger> logger_;
protected:
void printObjectiveFunctionFailureMessage() const;
// data members are mutable, because we inherit from GradientFunction,
// and evaluate() is const there. This could probably be solved better....
mutable WallTimer wall_timer_;
mutable int num_function_calls_ = 0;
mutable int num_iterations_ = 0;
mutable int num_parameters_ = 0;
mutable bool started_ = false;
// non-owning
mutable GradientFunction *grad_fun_ = nullptr;
// for caching
mutable bool have_cached_cost_ = false;
mutable bool have_cached_gradient_ = false;
mutable std::vector<double> cached_gradient_;
mutable double cached_cost_ = std::numeric_limits<double>::infinity();
mutable FunctionEvaluationStatus cached_status_ = functionEvaluationSuccess;
mutable double final_cost_ = std::numeric_limits<double>::quiet_NaN();
// keeps the most recent parameters, assuming they are the final ones
mutable std::vector<double> cached_parameters_;
std::string default_logger_prefix_;
};
class OptimizationProblem {
public:
OptimizationProblem() = default;
OptimizationProblem(std::unique_ptr<GradientFunction> costFun,
std::unique_ptr<Logger> logger);
OptimizationProblem(OptimizationProblem const& other) = delete;
virtual ~OptimizationProblem() = default;
virtual void fillInitialParameters(gsl::span<double> buffer) const;
virtual void fillParametersMin(gsl::span<double> buffer) const = 0;
virtual void fillParametersMax(gsl::span<double> buffer) const = 0;
virtual OptimizationOptions const& getOptimizationOptions() const;
virtual void setOptimizationOptions(OptimizationOptions const& options);
virtual std::unique_ptr<OptimizationReporter> getReporter() const;
// const?
std::unique_ptr<GradientFunction> cost_fun_;
std::unique_ptr<Logger> logger_;
private:
OptimizationOptions optimization_options_;
};
class OptimizationProblemImpl: public OptimizationProblem {
public:
using OptimizationProblem::OptimizationProblem;
void fillParametersMin(gsl::span<double> buffer) const override;
void fillParametersMax(gsl::span<double> buffer) const override;
void setParametersMin(std::vector<double> parametersMin);
void setParametersMax(std::vector<double> parametersMax);
void setInitialParameters(std::vector<double> initial);
void fillInitialParameters(gsl::span<double> buffer) const override;
private:
std::vector<double> parametersMin;
std::vector<double> parametersMax;
std::vector<double> parametersStart;
};
int getLocalOptimum(OptimizationProblem *problem);
void optimizationProblemGradientCheckMultiEps(OptimizationProblem *problem,
int numParameterIndicesToCheck);
void optimizationProblemGradientCheckMultiEps(OptimizationProblem *problem,
gsl::span<const int> parameterIndices,
gsl::span<double> multi_eps);
void optimizationProblemGradientCheck(OptimizationProblem *problem,
int numParameterIndicesToCheck,
double epsilon);
void optimizationProblemGradientCheck(OptimizationProblem *problem,
gsl::span<const int> parameterIndices,
double epsilon);
} // namespace parpe
#endif