DiSMEC++
minimizer.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021, Aalto University, developed by Erik Schultheis
2 // All rights reserved.
3 //
4 // SPDX-License-Identifier: MIT
5 
6 #include "minimizer.h"
7 #include <vector>
8 #include <stdexcept>
9 #include "spdlog/spdlog.h"
10 #include "stats/collection.h"
11 
12 using namespace dismec::solvers;
13 
14 Minimizer::Minimizer(std::shared_ptr<spdlog::logger> logger) :
15  m_Logger(std::move(logger)) {
16 }
17 
18 Minimizer::~Minimizer() = default;
19 
20 void Minimizer::set_logger(std::shared_ptr<spdlog::logger> logger) {
21  m_Logger = std::move(logger);
22 }
23 
25  long n = objective.num_variables();
26  if(init.size() != n) {
27  throw std::invalid_argument("Weight vector incompatible with problem size");
28  }
29 
30  auto start = std::chrono::steady_clock::now();
31  auto result = run(objective, init);
32  result.Duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start);
33  return result;
34 }
35 
36 #include "doctest.h"
37 
38 using namespace dismec;
39 
40 namespace
41 {
43 
45  class MockMinimizer : public Minimizer {
46  MinimizationResult run(Objective& objective, Eigen::Ref<DenseRealVector> init) override {
47  MinimizationResult result;
49  result.FinalGrad = 5.0;
50  result.FinalValue = 2.0;
51  result.NumIters = 55;
52  result.Duration = std::chrono::milliseconds(4242); // this should be set by the parent class - we use this value
53  // so we can verify that
54  return result;
55  }
56  };
57 
59  struct MockObjective : public Objective {
60  [[nodiscard]] long num_variables() const noexcept override { return 12; }
61  real_t value_unchecked(const HashVector& location) override { return 5.0; }
62  void gradient_unchecked(const HashVector& location, Eigen::Ref<DenseRealVector> target) override {};
63  void hessian_times_direction_unchecked(const HashVector& location, const DenseRealVector& direction,
64  Eigen::Ref<DenseRealVector> target) override {};
65  void project_to_line_unchecked(const HashVector& location, const DenseRealVector& direction) override {};
66  real_t lookup_on_line(real_t position) override { return 0.0; };
67  };
68 }
69 
77 TEST_CASE("minimizer base class minimize") {
78  MockMinimizer mnm;
79  DenseRealVector vec;
80  MockObjective goal;
81 
82  // check that having an improperly sized initial vector throws
83  SUBCASE("init vector verifier") {
84  CHECK_THROWS(mnm.minimize(goal, vec));
85  }
86 
87  // check that the base class does the timing
88  SUBCASE("timing") {
89  vec.resize(goal.num_variables());
90  auto result = mnm.minimize(goal, vec);
91  CHECK(result.Duration != std::chrono::milliseconds(4242));
92  }
93 
94  // check that the other results are passed through as-is
95  SUBCASE("result passing") {
96  vec.resize(goal.num_variables());
97  auto result = mnm.minimize(goal, vec);
98  CHECK(result.Outcome == MinimizerStatus::DIVERGED);
99  CHECK(result.FinalGrad == 5.0);
100  CHECK(result.FinalValue == 2.0);
101  CHECK(result.NumIters == 55);
102  }
103 }
A minimizer to be used in test cases that returns a fixed result.
Definition: minimizer.cpp:45
MinimizationResult run(Objective &objective, Eigen::Ref< DenseRealVector > init) override
Definition: minimizer.cpp:46
An Eigen vector with versioning information, to implement simple caching of results.
Definition: hash_vector.h:43
Class that models an optimization objective.
Definition: objective.h:41
Minimizer(std::shared_ptr< spdlog::logger > logger={})
Definition: minimizer.cpp:14
MinimizationResult minimize(objective::Objective &objective, Eigen::Ref< DenseRealVector > init)
Definition: minimizer.cpp:24
virtual MinimizationResult run(objective::Objective &objective, Eigen::Ref< DenseRealVector > init)=0
std::shared_ptr< spdlog::logger > m_Logger
Definition: minimizer.h:45
void set_logger(std::shared_ptr< spdlog::logger > logger)
sets the logger object that is used for progress tracking.
Definition: minimizer.cpp:20
TEST_CASE("minimizer base class minimize")
Definition: minimizer.cpp:77
@ DIVERGED
The optimization objective appears to be unbounded.
Main namespace in which all types, classes, and functions are defined.
Definition: app.h:15
types::DenseVector< real_t > DenseRealVector
Any dense, real values vector.
Definition: matrix_types.h:40
float real_t
The default type for floating point values.
Definition: config.h:17
An objective to be used in test cases. Does not do any computations, but just resturns constants.
Definition: minimizer.cpp:59
void hessian_times_direction_unchecked(const HashVector &location, const DenseRealVector &direction, Eigen::Ref< DenseRealVector > target) override
Definition: minimizer.cpp:63
void project_to_line_unchecked(const HashVector &location, const DenseRealVector &direction) override
Definition: minimizer.cpp:65
real_t lookup_on_line(real_t position) override
Looks up the value of the objective on the line defined by the last call to project_to_line().
Definition: minimizer.cpp:66
real_t value_unchecked(const HashVector &location) override
Definition: minimizer.cpp:61
long num_variables() const noexcept override
Definition: minimizer.cpp:60
void gradient_unchecked(const HashVector &location, Eigen::Ref< DenseRealVector > target) override
Definition: minimizer.cpp:62
std::chrono::milliseconds Duration
Definition: minimizer.h:31