|
ʻOhana
Population structure, admixture history, and selection using learning methods.
|
7 #ifndef JADE_LEMKE_HPP__
8 #define JADE_LEMKE_HPP__
10 #include "jade.matrix.hpp"
17 template <
typename TValue>
25 std::numeric_limits<size_t>::max();
47 static const char *
str(
52 #define CASE(E) case E: return #E; break
86 , _state (
state::executing)
92 const auto & t = _tableau;
94 const auto z0 = n + n;
100 for (
size_t i = 0; i < n; i++)
101 _labels.push_back(i);
108 if (!_find_initial_pivot_row())
144 const auto & t = _tableau;
147 const auto z0 = n + n;
148 const auto q = n + n + 1;
150 std::ostringstream out;
151 if (label < z1) out <<
"w_" << label + 1;
152 else if (label < z0) out <<
"z_" << label + 1 - n;
153 else if (label == z0) out <<
"z_0";
154 else if (label == q) out <<
"q";
172 const auto & t = _tableau;
175 const auto q = n + n + 1;
179 for (
size_t i = 0; i < n; i++)
181 const auto label = _labels[i];
183 out[label - z1] = t(i, q);
246 if (!_find_pivot_row())
295 return solve(out, _create_tableau(m, q));
312 return solve(out, _create_tableau(q, a, c, b));
320 const auto & t = _tableau;
322 const auto q = n + n + 1;
324 static const size_t cx = 8;
325 std::ostringstream out;
326 out << std::setprecision(3)
327 << std::setw(cx) <<
"BV";
329 for (
size_t j = 0; j <= q; j++)
333 for (
size_t i = 0; i < n; i++)
336 for (
size_t j = 0; j <= q; j++)
337 out << std::setw(cx) << t(i, j);
342 <<
"state: " <<
state::str(_state) << std::endl
351 out << std::endl << std::endl;
361 assert(q.get_width() == a.get_width() || a.is_empty());
362 assert(q.is_square());
363 assert(q.get_height() >= 1);
365 const auto qn = q.get_height();
366 const auto ah = a.get_height();
367 const auto mn = qn + ah;
374 for (
size_t i = 0; i < qn; i++)
375 for (
size_t j = 0; j < qn; j++)
381 for (
size_t i = 0; i < ah; i++)
382 for (
size_t j = 0; j < qn; j++)
383 m(qn + i, j) = a(i, j);
388 for (
size_t i = 0; i < ah; i++)
389 for (
size_t j = 0; j < qn; j++)
390 m(j, qn + i) = -a(i, j);
400 assert(c.is_column_vector());
401 assert(b.is_column_vector() || b.is_empty());
402 assert(c.get_height() >= 1);
404 const auto ch = c.get_height();
405 const auto bh = b.get_height();
412 for (
size_t i = 0; i < ch; i++)
418 for (
size_t i = 0; i < bh; i++)
429 assert(m.is_square());
430 assert(q.is_column_vector());
431 assert(m.get_height() == q.get_height());
433 const auto n = q.get_length();
439 for (
size_t i = 0; i < n; i++)
445 for (
size_t i = 0; i < n; i++)
446 for (
size_t j = 0; j < n; j++)
447 t(i, n + j) = -m(i, j);
452 for (
size_t i = 0; i < n; i++)
458 for (
size_t i = 0; i < n; i++)
459 t(i, 2 * n + 1) = q[i];
471 return _create_tableau(_create_m(q, a), _create_q(c, b));
479 const auto n = t.get_height();
484 auto & t_pivot = t(_pivot_row, _pivot_col);
485 if (std::fabs(t_pivot) < _epsilon)
491 for (
size_t j = 0; j < w; j++)
493 t(_pivot_row, j) /= t_pivot;
499 for (
size_t i = 0; i < n; i++)
504 auto & t_ip = t(i, _pivot_col);
505 for (
size_t j = 0; j < w; j++)
507 t(i, j) -= t_ip * t(_pivot_row, j);
515 bool _find_initial_pivot_row()
517 const auto & t = _tableau;
519 const auto q = n + n + 1;
528 for (
size_t i = 0; i < n; i++)
533 const auto t_iq = t(i, q);
554 bool _find_pivot_row()
556 const auto & t = _tableau;
558 const auto q = n + n + 1;
567 for (
size_t i = 0; i < n; i++)
572 const auto t_ip = t(i, _pivot_col);
579 const auto r_i = t(i, q) / t_ip;
596 const auto & t = _tableau;
599 const auto z0 = n + n;
604 const auto old_label = _labels[_pivot_row];
609 _labels[_pivot_row] = _pivot_col;
621 _pivot_col = old_label >= z1
637 static constexpr
auto _epsilon =
value_type(0.000001);
647 #endif // JADE_LEMKE_HPP__
bool solve()
Executes the algorithm until it has completed or has aborted.
std::string format_label(const size_t label) const
static bool solve(matrix_type &out, const matrix_type &m, const matrix_type &q)
Attempts to solve the linear complementarity problem using Lemke's Algorithm. If successful,...
matrix_type get_output() const
A template for a class that implements Lemke's algorithm.
bool is_executing() const
@ aborted_pivot
Aborted finding the pivot.
std::vector< size_t > labels_type
The labels type.
basic_lemke(const matrix_type &tableau)
Initializes a new instance of the class based on the specified tableau.
static constexpr auto invalid_index
The value associated with an invalid or unassigned index.
basic_matrix< value_type > matrix_type
The matrix type.
state_type get_state() const
@ aborted_initialization
Aborted during initialization.
static const char * str(const type value)
@ completed
The algorithm completed.
Possible states of the algorithm.
size_t get_height() const
const labels_type & get_labels() const
size_t get_pivot_row() const
basic_lemke(const matrix_type &q, const matrix_type &a, const matrix_type &c, const matrix_type &b)
Initializes a new instance of the class based on the specified Q and A matrices and c and b vectors.
static bool solve(matrix_type &out, const matrix_type &q, const matrix_type &a, const matrix_type &c, const matrix_type &b)
Attempts to solve the linear complementarity problem using Lemke's Algorithm. If successful,...
TValue value_type
The value type.
const matrix_type & get_tableau() const
size_t get_pivot_col() const
static bool solve(matrix_type &out, const matrix_type &tableau)
Attempts to solve the linear complementarity problem using Lemke's Algorithm. If successful,...
basic_lemke(const matrix_type &m, const matrix_type &q)
Initializes a new instance of the class based on the specified M and Q matrices.
state::type state_type
The state type.
bool iterate()
Performs one step of the algorithm.
@ executing
The algorithm is executing.
@ aborted_elimination
Aborted with an invalid pivot.