ʻOhana
Population structure, admixture history, and selection using learning methods.
jade.treeless_controller.hpp
1 /* -------------------------------------------------------------------------
2  Ohana
3  Copyright (c) 2015-2020 Jade Cheng (\___/)
4  Jade Cheng <info@jade-cheng.com> (='.'=)
5  ------------------------------------------------------------------------- */
6 
7 #ifndef JADE_TREELESS_CONTROLLER_HPP__
8 #define JADE_TREELESS_CONTROLLER_HPP__
9 
10 #include "jade.controller.hpp"
11 
12 namespace jade
13 {
14  ///
15  /// A template for a class that encodes and decodes parameters for the
16  /// Nelder-Mead algorithm. This class does not use a user-specified Newick
17  /// tree.
18  ///
19  template <typename TValue>
21  : public basic_controller<TValue>
22  {
23  public:
24  /// The value type.
25  typedef TValue value_type;
26 
27  /// The matrix type.
29 
30  /// The settings type.
32 
33  /// The container type for the controller.
34  typedef typename
37 
38  ///
39  /// Initializes a new instance of the class based on the specified
40  /// program settings.
41  ///
43  const settings_type & settings) ///< The program settings.
44  : basic_controller<TValue> (settings)
45  {
46  }
47 
48  // --------------------------------------------------------------------
49  virtual container_type init_parameters() override
50  {
51  const auto & c = this->get_c();
52  const auto rk = this->get_rk();
53  assert(c.get_height() == rk);
54 
55  //
56  // The container contains the lower-right triangle of data,
57  // including the diagonal. This comes to RK * RK (the total number
58  // of items in the matrix), subtract RK (the number of items in the
59  // diagonal), divide by two (only half of these elements), plus RK
60  // (the number of items in the diagonal).
61  //
62  container_type params;
63  params.reserve(rk + ((rk * rk) - rk) / 2);
64 
65  //
66  // Pointers to the start and end of the first row. Note the
67  // covariance matrix is symmetric.
68  //
69  auto src_ptr = c.get_data();
70  auto src_end = c.get_data() + rk;
71 
72  //
73  // Loop over every row/column.
74  //
75  for (size_t i = 0; i < rk; i++)
76  {
77  //
78  // Skip the columns before the diagonal.
79  //
80  src_ptr += i;
81 
82  //
83  // Copy all columns from the diagonal to the end of the row.
84  //
85  while (src_ptr != src_end)
86  params.push_back(*src_ptr++);
87 
88  //
89  // Advance the next end-of-row RK elements ahead.
90  //
91  src_end += rk;
92  }
93 
94  return params;
95  }
96 
97  protected:
98  ///
99  /// Decodes the specified Nelder-Mead container and stores the result
100  /// into the lower triangle, including the diagonal, of the covariance
101  /// matrix.
102  /// \return True to indicate this method is successful.
103  ///
104  virtual bool _decode_lower(
105  matrix_type & dst, ///< The covariance matrix.
106  const container_type & src) ///< The Nelder-Mead container.
107  override
108  {
109  const auto rk = this->get_rk();
110 
111  //
112  // The container contains the lower-right triangle of data,
113  // including the diagonal. This comes to RK * RK (the total number
114  // of items in the matrix), subtract RK (the number of items in the
115  // diagonal), divide by two (only half of these elements), plus RK
116  // (the number of items in the diagonal).
117  //
118  assert(src.size() == rk + ((rk * rk) - rk) / 2);
119 
120  //
121  // Pointers to the start and end of the first column.
122  //
123  auto dst_ptr = dst.get_data();
124  auto dst_end = dst.get_data() + dst.get_length();
125  auto src_ptr = src.data();
126  const auto src_end = src.data() + src.size();
127 
128  //
129  // Loop over every row/column.
130  //
131  while (src_ptr != src_end)
132  {
133  //
134  // Don't lose track of the start of the column data.
135  //
136  const auto anchor = dst_ptr;
137 
138  //
139  // Copy the rows of the column from the diagonal to the end.
140  //
141  for (; dst_ptr != dst_end; dst_ptr += rk)
142  *dst_ptr = *src_ptr++;
143 
144  //
145  // The next start-of-column is below and to the right of the
146  // previous one. The next end-of-column is one to the right.
147  //
148  dst_ptr = anchor + rk + 1;
149  dst_end++;
150  }
151 
152  //
153  // This method is always successful.
154  //
155  return true;
156  }
157  };
158 }
159 
160 #endif // JADE_TREELESS_CONTROLLER_HPP__
jade::basic_controller
A template for a class that performs the Nelder-Mead optimization. This class implements shared featu...
Definition: jade.controller.hpp:24
jade::basic_matrix::get_data
const value_type * get_data() const
Definition: jade.matrix.hpp:542
jade::basic_treeless_controller::matrix_type
basic_matrix< value_type > matrix_type
The matrix type.
Definition: jade.treeless_controller.hpp:28
jade::basic_matrix::get_length
size_t get_length() const
Definition: jade.matrix.hpp:624
jade::basic_treeless_controller::container_type
basic_controller< TValue >::container_type container_type
The container type for the controller.
Definition: jade.treeless_controller.hpp:36
jade::basic_controller::get_rk
size_t get_rk() const
Definition: jade.controller.hpp:164
jade::basic_controller::container_type
simplex_type::container_type container_type
The container type for the simplex.
Definition: jade.controller.hpp:45
jade::basic_treeless_controller
A template for a class that encodes and decodes parameters for the Nelder-Mead algorithm....
Definition: jade.treeless_controller.hpp:22
jade::basic_treeless_controller::value_type
TValue value_type
The value type.
Definition: jade.treeless_controller.hpp:25
jade::basic_treeless_controller::basic_treeless_controller
basic_treeless_controller(const settings_type &settings)
Initializes a new instance of the class based on the specified program settings.
Definition: jade.treeless_controller.hpp:42
jade::basic_settings
A template for a class encapsulating the settings provided to the optimizer.
Definition: cpax/jade.settings.hpp:22
jade::basic_treeless_controller::_decode_lower
virtual bool _decode_lower(matrix_type &dst, const container_type &src) override
Decodes the specified Nelder-Mead container and stores the result into the lower triangle,...
Definition: jade.treeless_controller.hpp:104
jade::basic_treeless_controller::init_parameters
virtual container_type init_parameters() override
Creates and returns the initial set of parameters for the Nelder- Mead algorithm.
Definition: jade.treeless_controller.hpp:49
jade::basic_matrix< value_type >
jade::basic_controller::get_c
const matrix_type & get_c() const
Definition: jade.controller.hpp:156
jade::basic_treeless_controller::settings_type
basic_settings< value_type > settings_type
The settings type.
Definition: jade.treeless_controller.hpp:31