// -------------------------------------------------------------------- static matrix_type _compute_rooted_fa(const matrix_type & fa) { const size_t K = fa.get_height(); const size_t J = fa.get_width(); assert(K > 1); matrix_type rooted_fa (K - 1, J); for (size_t k = 0; k + 1 < K; k++) for (size_t j = 0; j < J; j++) rooted_fa(k, j) = fa(k + 1, j) - fa(0, j); return rooted_fa; }
/// /// \return A new-and-improved F matrix. /// static matrix_type improve_f( const genotype_matrix_type & g, ///< The G matrix. const matrix_type & q, ///< The Q matrix. const matrix_type & fa, ///< The F matrix. const matrix_type & fb, ///< The 1-F matrix. const matrix_type & qfa, ///< The Q*F matrix. const matrix_type & qfb, ///< The Q*(1-F) matrix. const matrix_type * fif, ///< The Fin-force matrix. const bool frb) ///< Using frequency-bounds. { assert(verification_type::validate_gqf_sizes(g, q, fa)); assert(verification_type::validate_gqf_sizes(g, q, fb)); assert(verification_type::validate_q(q)); assert(verification_type::validate_f(fa)); assert(nullptr == fif || !frb); const auto I = g.get_height(); const auto K = fa.get_height(); const auto J = fa.get_width(); assert(nullptr == fif || verification_type:: validate_fif_size(*fif, K, J)); matrix_type f_dst (K, J); static const std::vector<size_t> fixed_active_set; matrix_type derivative_vec (K, 1); matrix_type hessian_mat (K, K); const auto frb_delta = value_type(1.0) / (value_type(2 * I) + value_type(1.0)); for (size_t j = 0; j < J; j++) { const auto f_column = fa.copy_column(j); g.compute_derivatives_f( q, fa, fb, qfa, qfb, j, derivative_vec, hessian_mat); const auto coefficients_mat = _create_coefficients_mat(K, 0); auto b_vec = _create_b_vec(f_column, 0); if (nullptr != fif) { for (size_t k = 0; k < fif->get_height(); k++) { b_vec[k + 0] = value_type(0); b_vec[k + K] = value_type(0); } } else if (frb) { for (size_t k = 0; k < K; k++) { b_vec[k + 0] -= frb_delta; b_vec[k + K] -= frb_delta; } } std::vector<size_t> active_set { 0 }; matrix_type delta_vec (K, 1); delta_vec[0] = -b_vec[0]; qpas_type::loop_over_active_set( b_vec, coefficients_mat, hessian_mat, derivative_vec, fixed_active_set, active_set, delta_vec); for (size_t k = 0; k < K; k++) f_dst(k, j) = f_column[k] + delta_vec[k]; } f_dst.clamp(min, max); return f_dst; }
/// /// \return A new-and-improved Q matrix. /// static matrix_type improve_q( const genotype_matrix_type & g, ///< The G matrix. const matrix_type & q, ///< The Q matrix. const matrix_type & fa, ///< The F matrix. const matrix_type & fb, ///< The 1-F matrix. const matrix_type & qfa, ///< The Q*F matrix. const matrix_type & qfb, ///< The Q*(1-F) matrix. const forced_grouping_type * fg) ///< The force-grouping. { assert(verification_type::validate_gqf_sizes(g, q, fa)); assert(verification_type::validate_gqf_sizes(g, q, fb)); assert(verification_type::validate_q(q)); assert(verification_type::validate_f(fa)); const auto I = q.get_height(); const auto K = q.get_width(); matrix_type q_dst (I, K); const std::vector<size_t> fixed_active_set { K + K }; matrix_type derivative_vec (K, 1); matrix_type hessian_mat (K, K); for (size_t i = 0; i < I; i++) { const auto q_row = q.copy_row(i); g.compute_derivatives_q( q, fa, fb, qfa, qfb, i, derivative_vec, hessian_mat); const auto coefficients_mat = _create_coefficients_mat(K, 1); auto b_vec = _create_b_vec(q_row, 1); if (nullptr != fg) { for (size_t k = 0; k < K; k++) { b_vec[k + 0] -= fg->get_min(i, k); b_vec[k + K] += fg->get_max(i, k) - value_type(1); } } std::vector<size_t> active_set { 0 }; matrix_type delta_vec (K, 1); delta_vec[0] = -b_vec[0]; qpas_type::loop_over_active_set( b_vec, coefficients_mat, hessian_mat, derivative_vec, fixed_active_set, active_set, delta_vec); for (size_t k = 0; k < K; k++) q_dst(i, k) = q_row[k] + delta_vec[k]; q_dst.clamp_row(i, min, max); const auto sum = q_dst.get_row_sum(i); q_dst.multiply_row(i, value_type(1) / sum); } return q_dst; }