7 #ifndef JADE_LIKELIHOOD_GENOTYPE_MATRIX_HPP__
8 #define JADE_LIKELIHOOD_GENOTYPE_MATRIX_HPP__
10 #include "jade.genotype_matrix.hpp"
18 template <
typename TValue>
57 const std::string & path)
67 char const *
const path)
70 assert(path !=
nullptr);
74 std::ifstream in (path);
76 throw error(
"error reading file");
79 _g_aa.
swap(tmp._g_aa);
80 _g_Aa.
swap(tmp._g_Aa);
81 _g_AA.
swap(tmp._g_AA);
83 catch (
const std::exception & e)
86 <<
"error reading likelihood genotype matrix '"
87 << path <<
"': " << e.
what();
160 auto g_aa_ij_ptr = _g_aa.
get_data() + j;
161 auto g_Aa_ij_ptr = _g_Aa.
get_data() + j;
162 auto g_AA_ij_ptr = _g_AA.
get_data() + j;
164 auto qfa_ij_ptr = qfa.
get_data() + j;
165 auto qfb_ij_ptr = qfb.
get_data() + j;
166 const auto g_aa_ij_end = g_aa_ij_ptr + _g_aa.
get_length();
167 const auto g_step = J;
168 const auto q_step = K;
169 const auto qf_step = J;
170 while (g_aa_ij_ptr != g_aa_ij_end)
172 const auto g_AA_ij = *g_AA_ij_ptr;
173 const auto g_Aa_ij = *g_Aa_ij_ptr;
174 const auto g_aa_ij = *g_aa_ij_ptr;
175 const auto qfa_ij = *qfa_ij_ptr;
176 const auto qfb_ij = *qfb_ij_ptr;
179 g_AA_ij * qfa_ij * qfa_ij +
180 g_aa_ij * qfb_ij * qfb_ij +
181 g_Aa_ij * qfa_ij * qfb_ij * 2);
183 const auto theta = 2 * (
197 auto q_ik1_ptr = q_i0_ptr;
198 const auto q_ik1_end = q_i0_ptr + K;
199 const auto q_ik2_end = q_i0_ptr + K;
200 while (q_ik1_ptr != q_ik1_end)
202 const auto q_ik1 = *q_ik1_ptr;
204 *d_ptr += theta * alpha * q_ik1;
210 auto q_ik2_ptr = q_i0_ptr;
211 while (q_ik2_ptr != q_ik2_end)
213 const auto q_ik2 = *q_ik2_ptr;
214 const auto term = 2 * (g_AA_ij + g_aa_ij
217 *h_ptr += alpha * q_ik1 * q_ik2 * (
218 term - (theta * theta * alpha));
228 g_AA_ij_ptr += g_step;
229 g_Aa_ij_ptr += g_step;
230 g_aa_ij_ptr += g_step;
231 qfa_ij_ptr += qf_step;
232 qfb_ij_ptr += qf_step;
277 auto g_AA_ij_ptr = _g_AA.
get_data(i, 0);
278 auto g_Aa_ij_ptr = _g_Aa.
get_data(i, 0);
279 auto g_aa_ij_ptr = _g_aa.
get_data(i, 0);
280 const auto g_aa_ij_end = g_aa_ij_ptr + J;
281 auto qfa_ij_ptr = qfa.
get_data(i, 0);
282 auto qfb_ij_ptr = qfb.
get_data(i, 0);
286 while (g_aa_ij_ptr != g_aa_ij_end)
288 const auto g_AA_ij = *g_AA_ij_ptr;
289 const auto g_Aa_ij = *g_Aa_ij_ptr;
290 const auto g_aa_ij = *g_aa_ij_ptr;
291 const auto qfa_ij = *qfa_ij_ptr;
292 const auto qfb_ij = *qfb_ij_ptr;
295 g_AA_ij * qfa_ij * qfa_ij +
296 g_aa_ij * qfb_ij * qfb_ij +
297 g_Aa_ij * qfa_ij * qfb_ij * 2);
299 const auto theta = 2 * (
303 const auto gamma = 2 * (
314 auto fa_k1j_ptr = fa_0j_ptr;
315 auto fb_k1j_ptr = fb_0j_ptr;
318 const auto h_end = h_ptr + h_mat.
get_length();
319 while (h_ptr != h_end)
321 const auto fa_k1j = *fa_k1j_ptr;
322 const auto fb_k1j = *fb_k1j_ptr;
324 *d_ptr += alpha * ((theta * fa_k1j) + (gamma * fb_k1j));
331 auto fa_k2j_ptr = fa_0j_ptr;
332 auto fb_k2j_ptr = fb_0j_ptr;
333 const auto fa_k2j_end = fa_k2j_ptr + fa.
get_length();
334 while (fa_k2j_ptr != fa_k2j_end)
336 const auto fa_k2j = *fa_k2j_ptr;
337 const auto fb_k2j = *fb_k2j_ptr;
339 const auto term1 = 2 * (
340 (g_AA_ij * fa_k1j * fa_k2j) +
341 (g_aa_ij * fb_k1j * fb_k2j));
343 const auto term2 = 2 * g_Aa_ij * (
348 (theta * theta * fa_k1j * fa_k2j) +
349 (gamma * gamma * fb_k1j * fb_k2j);
351 const auto term4 = theta * gamma * (
355 *h_ptr += alpha * (term1 + term2
356 - alpha * (term3 + term4));
358 fa_k2j_ptr += f_step;
359 fb_k2j_ptr += f_step;
363 fa_k1j_ptr += f_step;
364 fb_k1j_ptr += f_step;
392 auto g_aa_ij_ptr = _g_aa.
get_data();
393 auto g_Aa_ij_ptr = _g_Aa.
get_data();
394 auto g_AA_ij_ptr = _g_AA.
get_data();
397 const auto qfb_ij_end = qfb_ij_ptr + qfb.
get_length();
401 while (qfb_ij_ptr != qfb_ij_end)
403 const auto qfa_ij = *qfa_ij_ptr;
404 const auto qfb_ij = *qfb_ij_ptr;
407 (*g_AA_ij_ptr * qfa_ij * qfa_ij) +
408 (*g_aa_ij_ptr * qfb_ij * qfb_ij) +
409 (*g_Aa_ij_ptr * qfa_ij * qfb_ij *
value_type(2)));
428 static const auto em_iterations = size_t(100);
429 static const auto em_epsilon =
value_type(1.0e-6);
431 const auto f_min =
value_type(0.0) + f_epsilon;
432 const auto f_max =
value_type(1.0) - f_epsilon;
439 for (
size_t j = 0; j < J; j++)
443 for (
auto iter = em_iterations; iter > 0; iter--)
448 for (
size_t i = 0; i < I; i++)
450 const auto AA = _g_AA(i, j) * mu_j * mu_j;
451 const auto aa = _g_aa(i, j) * wu_j * wu_j;
452 const auto Aa = _g_Aa(i, j) * mu_j * wu_j
459 const auto previous_mu_j = mu_j;
460 mu_j = std::min(std::max(
465 if (std::fabs(previous_mu_j - mu_j) <= em_epsilon)
524 inline virtual std::string
str()
const override
526 std::ostringstream out;
527 out << _g_aa <<
'\n' << _g_Aa <<
'\n' << _g_AA;
537 inline void _validate_sizes()
540 const auto w = _g_AA.get_width();
542 const auto is_size_mismatch =
false
543 || h != _g_Aa.get_height()
544 || h != _g_aa.get_height()
545 || w != _g_Aa.get_width()
546 || w != _g_aa.get_width();
548 if (is_size_mismatch)
549 throw error(
"inconsistent matrix_type sizes in "
550 "likelihood genotype matrix_type.");
578 assert(q.get_width() == fa.get_height());
579 assert(fa.is_size(fb));
580 assert(i < q.get_height());
581 assert(j < fa.get_width());
583 const auto J = fa.get_width();
584 const auto K = fa.get_height();
586 auto fa_mj_ptr = fa.get_data(0, j);
587 auto fb_mj_ptr = fb.get_data(0, j);
588 auto q_im_ptr = q.get_data(i, 0);
589 const auto q_im_end = q_im_ptr + K;
591 while (q_im_ptr != q_im_end)
593 const auto q_im = *q_im_ptr;
594 const auto fa_mj = *fa_mj_ptr;
595 const auto fb_mj = *fb_mj_ptr;
597 qfa_ij += q_im * fa_mj;
598 qfb_ij += q_im * fb_mj;
615 f_ij += g_AA_ij * qfa_ij * qfa_ij;
616 f_ij += g_aa_ij * qfb_ij * qfb_ij;
617 f_ij += g_Aa_ij * qfa_ij * qfb_ij *
value_type(2);
632 g_f_ijk +=
value_type(2) * g_AA_ij * q_ik * qfa_ij;
633 g_f_ijk -=
value_type(2) * g_aa_ij * q_ik * qfb_ij;
635 (qfb_ij * q_ik) - (qfa_ij * q_ik));
651 g_q_ijk +=
value_type(2) * g_AA_ij * fa_kj * qfa_ij;
652 g_q_ijk +=
value_type(2) * g_aa_ij * fb_kj * qfb_ij;
654 (qfa_ij * fb_kj) + (qfb_ij * fa_kj));
662 #endif // JADE_LIKELIHOOD_GENOTYPE_MATRIX_HPP__