Exemplo n.º 1
0
        ///
        /// \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;
        }