<commit_before>#ifndef MJOLNIR_OMP_PROTEIN_DNA_NON_SPECIFIC_INTERACTION_HPP
#define MJOLNIR_OMP_PROTEIN_DNA_NON_SPECIFIC_INTERACTION_HPP
#include <mjolnir/omp/OpenMPSimulatorTraits.hpp>
#include <mjolnir/omp/System.hpp>
#include <mjolnir/forcefield/PDNS/ProteinDNANonSpecificInteraction.hpp>

namespace mjolnir
{

// Protein-DNA Non-Specific interaction that represents hydrogen bond between
// side chain atoms in proteins and the phosphate residues in DNA.
// This is an implementation of the potential developed in the following paper.
// - T.Niina, G.B.Brandani, C.Tan, and S.Takada (2017) PLoS. Comp. Biol.
//
// U(r, theta, phi) = k f(r) g(theta) g(phi)
//
// f(r)   = exp(-(r-r0)^2 / 2sigma^2)
// g(phi) = 1                                ...         |phi - phi0| <  delta
//          1 - cos^2(pi(phi-phi0) / 2delta) ... delta < |phi - phi0| < 2delta
//          0                                ... otherwise
//
template<typename realT, template<typename, typename> class boundaryT>
class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<realT, boundaryT>>
    final : public GlobalInteractionBase<OpenMPSimulatorTraits<realT, boundaryT>>
{
  public:

    using traits_type     = OpenMPSimulatorTraits<realT, boundaryT>;
    using base_type       = GlobalInteractionBase<traits_type>;
    using real_type       = typename base_type::real_type;
    using coordinate_type = typename base_type::coordinate_type;
    using system_type     = typename base_type::system_type;
    using boundary_type   = typename base_type::boundary_type;
    using potential_type  = ProteinDNANonSpecificPotential<real_type>;
    using partition_type  = SpatialPartition<traitsT, potential_type>;

  public:

    ProteinDNANonSpecificInteraction(potential_type&& pot, partition_type&& part)
        : potential_(std::move(pot)), partition_(std::move(part))
    {}
    ~ProteinDNANonSpecificInteraction() {}

    void initialize(const system_type& sys) override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();
        MJOLNIR_LOG_INFO("potential is PDNS");

        this->potential_.initialize(sys);
        this->partition_.initialize(sys, this->potential_);
        return;
    }

    void update(const system_type& sys) override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();
        MJOLNIR_LOG_INFO("potential is PDNS");

        this->potential_.update(sys);
        this->partition_.initialize(sys, this->potential_);
        return;
    }

    void update_margin(const real_type dmargin, const system_type& sys) override
    {
        this->current_margin_ -= dmargin;
        if(this->current_margin_ < 0)
        {
            this->make_list(sys);
        }
        return ;
    }

    void calc_force(system_type& sys) const noexcept override
    {
        MJOLNIR_GET_DEFAULT_LOGGER_DEBUG();
        MJOLNIR_LOG_FUNCTION_DEBUG();

        constexpr auto tolerance = math::abs_tolerance<real_type>();
        // XXX Note: P is ambiguous because both Protein and Phosphate has `P`.
        // But this interaction is named as P-D ns, so here it uses `P` for protein
        // and `D` for DNA.

#pragma omp for nowait
        for(std::size_t i=0; i < this->potential_.contacts().size(); ++i)
        {
            const auto& para = potential_.contacts()[i];

            const auto  P  = para.P;
            const auto& rP = sys.position(P);
            for(const auto& ptnr : this->partition_.partners(P))
            {
                const auto  D  = ptnr.index;  // DNA phosphate
                const auto  S3 = ptnr.parameter().S3; // 3' Sugar
                const auto& rD = sys.position(D);

                MJOLNIR_LOG_DEBUG("protein = ", P, ", DNA = ", D, ", r0 = ", para.r0);

                //  PC          S5'    |
                //    o         o--o B | theta is an angle formed by the vector
                //    A\ P   D /       | from the neighboring amino acid residue at
                // vP | o --> o        | the N-term side to the amino acid residue
                //    |/     `-\       | at the C-term side (vP in the figure) and
                //    o    phi  o--o B | the vector from Protein to DNA (phosphate).
                //  PN           S3'   |

                // ----------------------------------------------------------------
                // calculates the distance part

                const auto rPD    = sys.adjust_direction(rD - rP); // PRO -> DNA
                const auto lPD_sq = math::length_sq(rPD);
                if(para.r_cut_sq < lPD_sq)
                {
                    continue;
                }
                const auto rlPD   = math::rsqrt(lPD_sq);
                const auto  lPD   = lPD_sq * rlPD;
                const auto f_df   = potential_.f_df(para.r0, lPD);

                MJOLNIR_LOG_DEBUG("f = ", f_df.first, ", df = ", f_df.second);

                // ----------------------------------------------------------------
                // calculates the angle part (theta)

                const auto& rPC   = sys.position(para.PC);
                const auto& rPN   = sys.position(para.PN);
                const auto rPNC   = sys.adjust_direction(rPC - rPN); // PN -> PC
                const auto rlPNC  = math::rlength(rPNC);
                const auto dotPNC = math::dot_product(rPNC, rPD);
                const auto cosPNC = dotPNC * rlPD * rlPNC;
                const auto theta  = std::acos(math::clamp<real_type>(cosPNC,-1,1));

                const auto g_dg_theta = potential_.g_dg(para.theta0, theta);

                MJOLNIR_LOG_DEBUG("g(theta) = ", g_dg_theta.first,
                                 ", dg(theta) = ", g_dg_theta.second);

                // ----------------------------------------------------------------
                // calculates the angle part (phi)

                const auto& rS3   = sys.position(S3);
                const auto rS3D   = sys.adjust_direction(rD - rS3); // S3' -> D
                const auto rlS3D  = math::rlength(rS3D);
                const auto dotS3D = math::dot_product(rPD, rS3D);
                const auto cosS3D = dotS3D * rlS3D * rlPD;
                const auto phi    = std::acos(math::clamp<real_type>(cosS3D,-1,1));

                const auto g_dg_phi = potential_.g_dg(para.phi0, phi);

                MJOLNIR_LOG_DEBUG("g(phi) = ", g_dg_phi.first,
                                 ", dg(phi) = ", g_dg_phi.second);

                // ----------------------------------------------------------------
                // calculate force
                //
                //   d/dr [kf(r)  g(theta)  g(phi)]
                // =    k [df(r)  g(theta)  g(phi) dr/dr     +
                //          f(r) dg(theta)  g(phi) dtheta/dr +
                //          f(r)  g(theta) dg(phi) dphi/dr   ]
                const auto k = para.k;
                const auto thread_id = omp_get_thread_num();

                // df(r) g(theta) g(phi)
                if(g_dg_theta.first  != 0 && g_dg_phi.first  != 0)
                {
                    MJOLNIR_LOG_DEBUG("calculating distance force");

                    const auto coef = rlPD * k *
                        f_df.second * g_dg_theta.first * g_dg_phi.first;
                    const auto F = -coef * rPD;

                    sys.force_thread(thread_id, P) -= F;
                    sys.force_thread(thread_id, D) += F;
                }

                // f(r) dg(theta) g(phi)
                if(g_dg_theta.second != 0 && g_dg_phi.first  != 0)
                {
                    MJOLNIR_LOG_DEBUG("calculating theta force");

                    const auto deriv =
                        k * f_df.first * g_dg_theta.second * g_dg_phi.first;

                    const auto sin_theta = std::sin(theta);
                    const auto coef_sin  = deriv / std::max(sin_theta, tolerance);

                    const auto rPD_reg  = rlPD  * rPD;
                    const auto rPNC_reg = rlPNC * rPNC;

                    const auto F_P  = -coef_sin * rlPD  * (rPNC_reg - cosPNC * rPD_reg );
                    const auto F_PN = -coef_sin * rlPNC * (rPD_reg  - cosPNC * rPNC_reg);

                    sys.force_thread(thread_id, D)       -= F_P;
                    sys.force_thread(thread_id, P)       += F_P;
                    sys.force_thread(thread_id, para.PN) += F_PN;
                    sys.force_thread(thread_id, para.PC) -= F_PN;
                }

                // f(r) dg(theta) g(phi)
                if(g_dg_theta.first  != 0 && g_dg_phi.second != 0)
                {
                    MJOLNIR_LOG_DEBUG("calculating phi force");

                    const auto deriv =
                        k * f_df.first * g_dg_theta.first * g_dg_phi.second;

                    const auto sin_phi  = std::sin(phi);
                    const auto coef_sin = deriv / std::max(sin_phi, tolerance);

                    const auto rPD_reg  = rlPD  * rPD;
                    const auto rS3D_reg = rlS3D * rS3D;

                    const auto F_P = -coef_sin * rlPD  * (rS3D_reg - cosS3D * rPD_reg);
                    const auto F_S = -coef_sin * rlS3D * (rPD_reg  - cosS3D * rS3D_reg);

                    sys.force_thread(thread_id, P)  += F_P;
                    sys.force_thread(thread_id, D)  -= F_P + F_S;
                    sys.force_thread(thread_id, S3) += F_S;
                }
            }
        }
        return;
    }

    real_type calc_energy(const system_type& sys) const noexcept override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();
        // XXX Note: P is ambiguous because both Protein and Phosphate has `P`.
        // But this interaction is named as P-D ns, so here it uses `P` for protein
        // and `D` for DNA.

        real_type E = 0.0;
#pragma omp parallel for reduction(+:E)
        for(std::size_t i=0; i < this->potential_.contacts().size(); ++i)
        {
            const auto& para = potential_.contacts()[i];

            const auto  P  = para.P;
            const auto& rP = sys.position(P);
            for(const auto& ptnr : this->partition_.partners(P))
            {
                const auto  D  = ptnr.index;  // DNA phosphate
                const auto  S3 = ptnr.parameter().S3; // 3' Sugar
                const auto& rD = sys.position(D);

                //  PC          S5'    |
                //    o         o--o B | theta is an angle formed by the vector
                //    A\ P   D /       | from the neighboring amino acid residue at
                // vP | o --> o        | the N-term side to the amino acid residue
                //    |/     `-\       | at the C-term side (vP in the figure) and
                //    o    phi  o--o B | the vector from Protein to DNA (phosphate).
                //  PN           S3'   |

                // ----------------------------------------------------------------
                // calculates the distance part

                const auto rPD    = sys.adjust_direction(rD - rP); // PRO -> DNA
                const auto lPD_sq = math::length_sq(rPD);
                if(para.r_cut_sq < lPD_sq)
                {
                    continue;
                }
                const auto rlPD   = math::rsqrt(lPD_sq);
                const auto  lPD   = lPD_sq * rlPD;
                const auto f      = potential_.f(para.r0, lPD);

                // ----------------------------------------------------------------
                // calculates the angle part (theta)

                const auto& rPC    = sys.position(para.PC);
                const auto& rPN    = sys.position(para.PN);
                const auto rPNC    = sys.adjust_direction(rPC - rPN); // PN -> PC
                const auto rlPNC   = math::rlength(rPNC);
                const auto dotPNC  = math::dot_product(rPNC, rPD);
                const auto cosPNC  = dotPNC * rlPD * rlPNC;
                const auto theta   = std::acos(math::clamp<real_type>(cosPNC,-1,1));
                const auto g_theta = potential_.g(para.theta0, theta);

                if(g_theta == real_type(0)) {continue;}

                // ----------------------------------------------------------------
                // calculates the angle part (phi)

                const auto& rS3   = sys.position(S3);
                const auto rS3D   = sys.adjust_direction(rD - rS3); // S3' -> D
                const auto rlS3D  = math::rlength(rS3D);
                const auto dotS3D = math::dot_product(rPD, rS3D);
                const auto cosS3D = dotS3D * rlS3D * rlPD;
                const auto phi    = std::acos(math::clamp<real_type>(cosS3D,-1,1));
                const auto g_phi  = potential_.g(para.phi0, phi);

                if(g_phi == real_type(0)) {continue;}

                // ----------------------------------------------------------------
                // calculate energy

                const auto k = para.k;

                MJOLNIR_LOG_INFO("protein = ", P, ", DNA = ", D, ", r0 = ", para.r0);

                E += k * f * g_theta * g_phi;
            }
        }
        return E;
    }

    std::string name() const override {return "PDNSInteraction";}

    potential_type const& potential() const noexcept {return potential_;}
    potential_type&       potential()       noexcept {return potential_;}

  private:

    potential_type potential_;
    partition_type partition_;
};
} // mjolnir

#ifdef MJOLNIR_SEPARATE_BUILD
// explicitly specialize BondAngleInteraction with LocalPotentials
#include <mjolnir/core/BoundaryCondition.hpp>

namespace mjolnir
{
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<double, UnlimitedBoundary>       >;
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<float,  UnlimitedBoundary>       >;
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<float,  CuboidalPeriodicBoundary>>;
} // mjolnir
#endif // MJOLNIR_SEPARATE_BUILD
#endif// MJOLNIR_FORCEFIELD_PDNS_PROTEIN_DNA_NON_SPECIFIC_INTERACTION_HPP
<commit_msg>fix: compilation errors in omp/PDNS<commit_after>#ifndef MJOLNIR_OMP_PROTEIN_DNA_NON_SPECIFIC_INTERACTION_HPP
#define MJOLNIR_OMP_PROTEIN_DNA_NON_SPECIFIC_INTERACTION_HPP
#include <mjolnir/omp/OpenMPSimulatorTraits.hpp>
#include <mjolnir/omp/System.hpp>
#include <mjolnir/forcefield/PDNS/ProteinDNANonSpecificInteraction.hpp>

namespace mjolnir
{

// Protein-DNA Non-Specific interaction that represents hydrogen bond between
// side chain atoms in proteins and the phosphate residues in DNA.
// This is an implementation of the potential developed in the following paper.
// - T.Niina, G.B.Brandani, C.Tan, and S.Takada (2017) PLoS. Comp. Biol.
//
// U(r, theta, phi) = k f(r) g(theta) g(phi)
//
// f(r)   = exp(-(r-r0)^2 / 2sigma^2)
// g(phi) = 1                                ...         |phi - phi0| <  delta
//          1 - cos^2(pi(phi-phi0) / 2delta) ... delta < |phi - phi0| < 2delta
//          0                                ... otherwise
//
template<typename realT, template<typename, typename> class boundaryT>
class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<realT, boundaryT>>
    final : public GlobalInteractionBase<OpenMPSimulatorTraits<realT, boundaryT>>
{
  public:

    using traits_type     = OpenMPSimulatorTraits<realT, boundaryT>;
    using base_type       = GlobalInteractionBase<traits_type>;
    using real_type       = typename base_type::real_type;
    using coordinate_type = typename base_type::coordinate_type;
    using system_type     = typename base_type::system_type;
    using boundary_type   = typename base_type::boundary_type;
    using potential_type  = ProteinDNANonSpecificPotential<real_type>;
    using partition_type  = SpatialPartition<traits_type, potential_type>;

  public:

    ProteinDNANonSpecificInteraction(potential_type&& pot, partition_type&& part)
        : potential_(std::move(pot)), partition_(std::move(part))
    {}
    ~ProteinDNANonSpecificInteraction() {}

    void initialize(const system_type& sys) override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();
        MJOLNIR_LOG_INFO("potential is PDNS");

        this->potential_.initialize(sys);
        this->partition_.initialize(sys, this->potential_);
        return;
    }

    void update(const system_type& sys) override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();
        MJOLNIR_LOG_INFO("potential is PDNS");

        this->potential_.update(sys);
        this->partition_.initialize(sys, this->potential_);
        return;
    }

    void update_margin(const real_type dmargin, const system_type& sys) override
    {
        this->partition_.update(dmargin, sys, this->potential_);
        return ;
    }

    void calc_force(system_type& sys) const noexcept override
    {
        MJOLNIR_GET_DEFAULT_LOGGER_DEBUG();
        MJOLNIR_LOG_FUNCTION_DEBUG();

        constexpr auto tolerance = math::abs_tolerance<real_type>();
        // XXX Note: P is ambiguous because both Protein and Phosphate has `P`.
        // But this interaction is named as P-D ns, so here it uses `P` for protein
        // and `D` for DNA.

#pragma omp for nowait
        for(std::size_t i=0; i < this->potential_.contacts().size(); ++i)
        {
            const auto& para = potential_.contacts()[i];

            const auto  P  = para.P;
            const auto& rP = sys.position(P);
            for(const auto& ptnr : this->partition_.partners(P))
            {
                const auto  D  = ptnr.index;  // DNA phosphate
                const auto  S3 = ptnr.parameter().S3; // 3' Sugar
                const auto& rD = sys.position(D);

                MJOLNIR_LOG_DEBUG("protein = ", P, ", DNA = ", D, ", r0 = ", para.r0);

                //  PC          S5'    |
                //    o         o--o B | theta is an angle formed by the vector
                //    A\ P   D /       | from the neighboring amino acid residue at
                // vP | o --> o        | the N-term side to the amino acid residue
                //    |/     `-\       | at the C-term side (vP in the figure) and
                //    o    phi  o--o B | the vector from Protein to DNA (phosphate).
                //  PN           S3'   |

                // ----------------------------------------------------------------
                // calculates the distance part

                const auto rPD    = sys.adjust_direction(rD - rP); // PRO -> DNA
                const auto lPD_sq = math::length_sq(rPD);
                if(para.r_cut_sq < lPD_sq)
                {
                    continue;
                }
                const auto rlPD   = math::rsqrt(lPD_sq);
                const auto  lPD   = lPD_sq * rlPD;
                const auto f_df   = potential_.f_df(para.r0, lPD);

                MJOLNIR_LOG_DEBUG("f = ", f_df.first, ", df = ", f_df.second);

                // ----------------------------------------------------------------
                // calculates the angle part (theta)

                const auto& rPC   = sys.position(para.PC);
                const auto& rPN   = sys.position(para.PN);
                const auto rPNC   = sys.adjust_direction(rPC - rPN); // PN -> PC
                const auto rlPNC  = math::rlength(rPNC);
                const auto dotPNC = math::dot_product(rPNC, rPD);
                const auto cosPNC = dotPNC * rlPD * rlPNC;
                const auto theta  = std::acos(math::clamp<real_type>(cosPNC,-1,1));

                const auto g_dg_theta = potential_.g_dg(para.theta0, theta);

                MJOLNIR_LOG_DEBUG("g(theta) = ", g_dg_theta.first,
                                 ", dg(theta) = ", g_dg_theta.second);

                // ----------------------------------------------------------------
                // calculates the angle part (phi)

                const auto& rS3   = sys.position(S3);
                const auto rS3D   = sys.adjust_direction(rD - rS3); // S3' -> D
                const auto rlS3D  = math::rlength(rS3D);
                const auto dotS3D = math::dot_product(rPD, rS3D);
                const auto cosS3D = dotS3D * rlS3D * rlPD;
                const auto phi    = std::acos(math::clamp<real_type>(cosS3D,-1,1));

                const auto g_dg_phi = potential_.g_dg(para.phi0, phi);

                MJOLNIR_LOG_DEBUG("g(phi) = ", g_dg_phi.first,
                                 ", dg(phi) = ", g_dg_phi.second);

                // ----------------------------------------------------------------
                // calculate force
                //
                //   d/dr [kf(r)  g(theta)  g(phi)]
                // =    k [df(r)  g(theta)  g(phi) dr/dr     +
                //          f(r) dg(theta)  g(phi) dtheta/dr +
                //          f(r)  g(theta) dg(phi) dphi/dr   ]
                const auto k = para.k;
                const auto thread_id = omp_get_thread_num();

                // df(r) g(theta) g(phi)
                if(g_dg_theta.first  != 0 && g_dg_phi.first  != 0)
                {
                    MJOLNIR_LOG_DEBUG("calculating distance force");

                    const auto coef = rlPD * k *
                        f_df.second * g_dg_theta.first * g_dg_phi.first;
                    const auto F = -coef * rPD;

                    sys.force_thread(thread_id, P) -= F;
                    sys.force_thread(thread_id, D) += F;
                }

                // f(r) dg(theta) g(phi)
                if(g_dg_theta.second != 0 && g_dg_phi.first  != 0)
                {
                    MJOLNIR_LOG_DEBUG("calculating theta force");

                    const auto deriv =
                        k * f_df.first * g_dg_theta.second * g_dg_phi.first;

                    const auto sin_theta = std::sin(theta);
                    const auto coef_sin  = deriv / std::max(sin_theta, tolerance);

                    const auto rPD_reg  = rlPD  * rPD;
                    const auto rPNC_reg = rlPNC * rPNC;

                    const auto F_P  = -coef_sin * rlPD  * (rPNC_reg - cosPNC * rPD_reg );
                    const auto F_PN = -coef_sin * rlPNC * (rPD_reg  - cosPNC * rPNC_reg);

                    sys.force_thread(thread_id, D)       -= F_P;
                    sys.force_thread(thread_id, P)       += F_P;
                    sys.force_thread(thread_id, para.PN) += F_PN;
                    sys.force_thread(thread_id, para.PC) -= F_PN;
                }

                // f(r) dg(theta) g(phi)
                if(g_dg_theta.first  != 0 && g_dg_phi.second != 0)
                {
                    MJOLNIR_LOG_DEBUG("calculating phi force");

                    const auto deriv =
                        k * f_df.first * g_dg_theta.first * g_dg_phi.second;

                    const auto sin_phi  = std::sin(phi);
                    const auto coef_sin = deriv / std::max(sin_phi, tolerance);

                    const auto rPD_reg  = rlPD  * rPD;
                    const auto rS3D_reg = rlS3D * rS3D;

                    const auto F_P = -coef_sin * rlPD  * (rS3D_reg - cosS3D * rPD_reg);
                    const auto F_S = -coef_sin * rlS3D * (rPD_reg  - cosS3D * rS3D_reg);

                    sys.force_thread(thread_id, P)  += F_P;
                    sys.force_thread(thread_id, D)  -= F_P + F_S;
                    sys.force_thread(thread_id, S3) += F_S;
                }
            }
        }
        return;
    }

    real_type calc_energy(const system_type& sys) const noexcept override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();
        // XXX Note: P is ambiguous because both Protein and Phosphate has `P`.
        // But this interaction is named as P-D ns, so here it uses `P` for protein
        // and `D` for DNA.

        real_type E = 0.0;
#pragma omp parallel for reduction(+:E)
        for(std::size_t i=0; i < this->potential_.contacts().size(); ++i)
        {
            const auto& para = potential_.contacts()[i];

            const auto  P  = para.P;
            const auto& rP = sys.position(P);
            for(const auto& ptnr : this->partition_.partners(P))
            {
                const auto  D  = ptnr.index;  // DNA phosphate
                const auto  S3 = ptnr.parameter().S3; // 3' Sugar
                const auto& rD = sys.position(D);

                //  PC          S5'    |
                //    o         o--o B | theta is an angle formed by the vector
                //    A\ P   D /       | from the neighboring amino acid residue at
                // vP | o --> o        | the N-term side to the amino acid residue
                //    |/     `-\       | at the C-term side (vP in the figure) and
                //    o    phi  o--o B | the vector from Protein to DNA (phosphate).
                //  PN           S3'   |

                // ----------------------------------------------------------------
                // calculates the distance part

                const auto rPD    = sys.adjust_direction(rD - rP); // PRO -> DNA
                const auto lPD_sq = math::length_sq(rPD);
                if(para.r_cut_sq < lPD_sq)
                {
                    continue;
                }
                const auto rlPD   = math::rsqrt(lPD_sq);
                const auto  lPD   = lPD_sq * rlPD;
                const auto f      = potential_.f(para.r0, lPD);

                // ----------------------------------------------------------------
                // calculates the angle part (theta)

                const auto& rPC    = sys.position(para.PC);
                const auto& rPN    = sys.position(para.PN);
                const auto rPNC    = sys.adjust_direction(rPC - rPN); // PN -> PC
                const auto rlPNC   = math::rlength(rPNC);
                const auto dotPNC  = math::dot_product(rPNC, rPD);
                const auto cosPNC  = dotPNC * rlPD * rlPNC;
                const auto theta   = std::acos(math::clamp<real_type>(cosPNC,-1,1));
                const auto g_theta = potential_.g(para.theta0, theta);

                if(g_theta == real_type(0)) {continue;}

                // ----------------------------------------------------------------
                // calculates the angle part (phi)

                const auto& rS3   = sys.position(S3);
                const auto rS3D   = sys.adjust_direction(rD - rS3); // S3' -> D
                const auto rlS3D  = math::rlength(rS3D);
                const auto dotS3D = math::dot_product(rPD, rS3D);
                const auto cosS3D = dotS3D * rlS3D * rlPD;
                const auto phi    = std::acos(math::clamp<real_type>(cosS3D,-1,1));
                const auto g_phi  = potential_.g(para.phi0, phi);

                if(g_phi == real_type(0)) {continue;}

                // ----------------------------------------------------------------
                // calculate energy

                const auto k = para.k;

                MJOLNIR_LOG_INFO("protein = ", P, ", DNA = ", D, ", r0 = ", para.r0);

                E += k * f * g_theta * g_phi;
            }
        }
        return E;
    }

    std::string name() const override {return "PDNSInteraction";}

    potential_type const& potential() const noexcept {return potential_;}
    potential_type&       potential()       noexcept {return potential_;}

  private:

    potential_type potential_;
    partition_type partition_;
};
} // mjolnir

#ifdef MJOLNIR_SEPARATE_BUILD
// explicitly specialize BondAngleInteraction with LocalPotentials
#include <mjolnir/core/BoundaryCondition.hpp>

namespace mjolnir
{
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<double, UnlimitedBoundary>       >;
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<float,  UnlimitedBoundary>       >;
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class ProteinDNANonSpecificInteraction<OpenMPSimulatorTraits<float,  CuboidalPeriodicBoundary>>;
} // mjolnir
#endif // MJOLNIR_SEPARATE_BUILD
#endif// MJOLNIR_FORCEFIELD_PDNS_PROTEIN_DNA_NON_SPECIFIC_INTERACTION_HPP
<|endoftext|>


<commit_before>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     g_dfs_server_main.h
* @version
* @brief
* @author   duye
* @date     2014-09-28
* @note
*
*  1. 2014-09-28 duye Created this file
*
*/

#include <g_logger.h>
#include <g_system.h>
#include <g_dfs_server.h>

static const GInt8* LOG_PREFIX = "dfs.server.main";

/**
 * @brief dfs server process monitor class
 */
class DfsServerProcessMonitorObserver : public gsys::ProcessMoniterInterface
{
public:
    DfsServerProcessMonitorObserver() {}
    ~DfsServerProcessMonitorObserver() {}

    /**
     * @brief handle system signal, when segmentation fault
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onSegmentationFault(const GInt32 sig)
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server segmentation fault happened");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::instance().setState(HOST_SERVER_FAULT);
        if (!gsys::ProcessMonitor::instance().exitWait())
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit===========");
        }
    }

    /**
     * @brief handle system signal, when ctrl+c
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onCtrlC(const GInt32 sig)
    {
        G_LOG_INFO(LOG_PREFIX, "DFS server stop by ctrl + c");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::instance()->setState(HOST_SERVER_STOP);
        if (!gsys::ProcessMonitor::instance().exitWait())
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit==============");
        }
    }
}

int main(int argc, char** argv)
{
    G_LOG_INIT();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server startup===========");

    // process monitor
    DfsServerProcessMonitorObserver dfs_server_process_monitor_observer;
    gsys::ProcessMonitor::instance().addMonitor(&dfs_server_process_monitor_observer);

    if (IS_NO(DfdServer::instance().start()))
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server startup fault");
        return -1;
    }

    while (DfsServer::instance().getState() == SERVER_RUNNING)
    {
        gsys::gsystem::sleep(2);
    }

    DfsServer::instance().stop();
    exit_condition.broadcast();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server stopped===========");

    G_LOG_UNINIT();

    return 0;
}
<commit_msg>Update g_dfs_server_main.cpp<commit_after>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     g_dfs_server_main.h
* @version
* @brief
* @author   duye
* @date     2014-09-28
* @note
*
*  1. 2014-09-28 duye Created this file
*
*/

#include <g_logger.h>
#include <g_system.h>
#include <g_dfs_server.h>

static const GInt8* LOG_PREFIX = "dfs.server.main";

/**
 * @brief dfs server process monitor class
 */
class DfsServerProcessMonitorObserver : public gsys::ProcessMoniterInterface
{
public:
    DfsServerProcessMonitorObserver() {}
    ~DfsServerProcessMonitorObserver() {}

    /**
     * @brief handle system signal, when segmentation fault
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onSegmentationFault(const GInt32 sig)
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server segmentation fault happened");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::instance().setState(HOST_SERVER_FAULT);
        if (!gsys::ProcessMonitor::instance().exitWait())
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit===========");
        }
    }

    /**
     * @brief handle system signal, when ctrl+c
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onCtrlC(const GInt32 sig)
    {
        G_LOG_INFO(LOG_PREFIX, "DFS server stop by ctrl + c");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::instance()->setState(HOST_SERVER_STOP);
        if (!gsys::ProcessMonitor::instance().exitWait())
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit==============");
        }
    }
}

int main(int argc, char** argv)
{
    G_LOG_INIT();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server startup===========");

    // process monitor
    DfsServerProcessMonitorObserver dfs_server_process_monitor_observer;
    gsys::ProcessMonitor::instance().addMonitor(&dfs_server_process_monitor_observer);

    if (IS_NO(DfdServer::instance().start()))
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server startup fault");
        return -1;
    }

    while (DfsServer::instance().getState() == SERVER_RUNNING)
    {
        gsys::gsystem::sleep(2);
    }

    DfsServer::instance().stop();
    gsys::ProcessMonitor::instance().exitWakeup();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server stopped===========");

    G_LOG_UNINIT();

    return 0;
}
<|endoftext|>


<commit_before>{
   gROOT->Reset();
   TCanvas *nut = new TCanvas("nut", "FirstSession",100,10,700,900);
   nut->Range(0,0,20,24);
   nut->SetFillColor(10);
   nut->SetBorderSize(2);

   TPaveLabel *pl = new TPaveLabel(3,22,17,23.7,"My first ROOT interactive session","br");
   pl->SetFillColor(18);
   pl->SetTextSize(0.7);
   pl->Draw();

   TText t(0,0,"a");
   t.SetTextFont(62);
   t.SetTextSize(0.025);
   t.SetTextAlign(12);
   t.DrawText(2,20.3,"ROOT is based on CINT, a powerful C/C++ interpreter.");
   t.DrawText(2,19.3,"Blocks of lines can be entered within {...}.");
   t.DrawText(2,18.3,"Previous typed lines can be recalled.");

   t.SetTextFont(72);
   t.SetTextSize(0.026);
   t.DrawText(3,17,"Root >  float x=5; float y=7;");
   t.DrawText(3,16,"Root >  x*sqrt(y)");
   t.DrawText(3,14,"Root >  for (int i=2;i<7;i++) printf(\"sqrt(%d) = %f\",i,sqrt(i));");
   t.DrawText(3,10,"Root >  TF1 f1(\"f1\",\"sin(x)/x\",0,10)");
   t.DrawText(3, 9,"Root >  f1.Draw()");
   t.SetTextFont(81);
   t.SetTextSize(0.018);
   t.DrawText(4,15,"(double)1.322875655532e+01");
   t.DrawText(4,13.3,"sqrt(2) = 1.414214");
   t.DrawText(4,12.7,"sqrt(3) = 1.732051");
   t.DrawText(4,12.1,"sqrt(4) = 2.000000");
   t.DrawText(4,11.5,"sqrt(5) = 2.236068");
   t.DrawText(4,10.9,"sqrt(6) = 2.449490");

   TPad *pad = new TPad("pad","pad",.2,.05,.8,.35);
   pad->Draw();
   pad->cd();
   pad->SetGrid();
   TF1 f1("f1","sin(x)/x",0,10);
   f1.Draw();

   nut.cd();
  //--signature
   TText sig(.2,.2,"/user/brun/root/aihep/first.C");
   sig.SetTextFont(72);
   sig.SetTextSize(0.020);
   sig.Draw();

   nut->Modified();
   nut->Print("first.ps");
   nut->cd();
   nut->Update();
}
<commit_msg>Remove the line setting the TPaveLabel text size. This is now automatic.<commit_after>{
   gROOT->Reset();
   TCanvas *nut = new TCanvas("nut", "FirstSession",100,10,700,900);
   nut->Range(0,0,20,24);
   nut->SetFillColor(10);
   nut->SetBorderSize(2);

   TPaveLabel *pl = new TPaveLabel(3,22,17,23.7,"My first ROOT interactive session","br");
   pl->SetFillColor(18);
   pl->Draw();

   TText t(0,0,"a");
   t.SetTextFont(62);
   t.SetTextSize(0.025);
   t.SetTextAlign(12);
   t.DrawText(2,20.3,"ROOT is based on CINT, a powerful C/C++ interpreter.");
   t.DrawText(2,19.3,"Blocks of lines can be entered within {...}.");
   t.DrawText(2,18.3,"Previous typed lines can be recalled.");

   t.SetTextFont(72);
   t.SetTextSize(0.026);
   t.DrawText(3,17,"Root >  float x=5; float y=7;");
   t.DrawText(3,16,"Root >  x*sqrt(y)");
   t.DrawText(3,14,"Root >  for (int i=2;i<7;i++) printf(\"sqrt(%d) = %f\",i,sqrt(i));");
   t.DrawText(3,10,"Root >  TF1 f1(\"f1\",\"sin(x)/x\",0,10)");
   t.DrawText(3, 9,"Root >  f1.Draw()");
   t.SetTextFont(81);
   t.SetTextSize(0.018);
   t.DrawText(4,15,"(double)1.322875655532e+01");
   t.DrawText(4,13.3,"sqrt(2) = 1.414214");
   t.DrawText(4,12.7,"sqrt(3) = 1.732051");
   t.DrawText(4,12.1,"sqrt(4) = 2.000000");
   t.DrawText(4,11.5,"sqrt(5) = 2.236068");
   t.DrawText(4,10.9,"sqrt(6) = 2.449490");

   TPad *pad = new TPad("pad","pad",.2,.05,.8,.35);
   pad->Draw();
   pad->cd();
   pad->SetGrid();
   TF1 f1("f1","sin(x)/x",0,10);
   f1.Draw();

   nut.cd();
  //--signature
   TText sig(.2,.2,"/user/brun/root/aihep/first.C");
   sig.SetTextFont(72);
   sig.SetTextSize(0.020);
   sig.Draw();

   nut->Modified();
   nut->Print("first.ps");
   nut->cd();
   nut->Update();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <random>
#include <chrono>
#include <functional>
#include <algorithm>

#include <cmath>

#define NUM_FIELDS 4

namespace KNearestNeighbors
{
    struct Entry
    {
        std::array<double, NUM_FIELDS> Attributes;
        std::string Class;
    };

    using IntDoublePair = std::pair<int, double>;

    struct CompareSecond: std::binary_function<IntDoublePair, IntDoublePair, bool>
    {
        bool operator()(const IntDoublePair& a, const IntDoublePair& b)
        {
            return a.second < b.second;
        }
    };

    bool LoadDataset(const char* filename, std::vector<Entry>& data)
    {
        std::ifstream filein(filename);
        if (!filein.is_open())
            return false;

        while (!filein.eof())
        {
            std::string line;
            std::getline(filein, line);
            if ("" == line)
                continue;
            std::istringstream linein(std::move(line));
            Entry entry;
            for (auto& attribute: entry.Attributes)
            {
                std::string value;
                std::getline(linein, value, ',');
                attribute = std::stod(std::move(value), nullptr);
            }
            std::getline(linein, entry.Class);
            data.push_back(std::move(entry));
        }

        return true;
    }

    void SplitData(const std::vector<Entry>& data, std::set<int>& trainingSet, std::set<int>& testSet)
    {
        std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
        std::uniform_int_distribution<> distribution(0, (int)data.size() - 1);
        while (testSet.size() < 20)
            testSet.insert(distribution(generator));
        while ((int)trainingSet.size() < (int)data.size() - 20)
        {
            int index = distribution(generator);
            if (!testSet.count(index))
                trainingSet.insert(index);
        }
    }

    void GetNeighbors(const std::vector<Entry>& data, const std::set<int>& trainingSet, int testInstance, int k, std::set<int>& neighbors)
    {
        std::set<IntDoublePair, CompareSecond> distances;
        auto euclideanDistance = [](const Entry& entry1, const Entry& entry2)
        {
            double sumDeltasSquared = 0;
            for (int i = 0; i < NUM_FIELDS; i++)
            {
                double delta = entry1.Attributes[i] - entry2.Attributes[i];
                sumDeltasSquared += delta * delta;
            }
            return sqrt(sumDeltasSquared);
        };
        for (int trainer: trainingSet)
            distances.insert(std::make_pair(trainer, euclideanDistance(data[testInstance], data[trainer])));

        auto i = distances.begin();
        for (int j = 0; j < k; ++j, ++i)
            neighbors.insert(i->first);
    }

    std::string GetResponse(const std::vector<Entry>& data, const std::set<int>& neighbors)
    {
        std::map<std::string, int> classVotes;
        for (int neighbor: neighbors)
        {
            auto response = data[neighbor].Class;
            if (classVotes.count(response))
                ++classVotes[response];
            else
                classVotes[response] = 1;
        }

        auto compareSecond = [](const auto& a, const auto& b)
        {
            return a.second < b.second;
        };
        auto responsePos = std::max_element(classVotes.begin(), classVotes.end(), compareSecond);
        return responsePos->first;
    }
}

int main(int argc, const char* const* argv)
{
    if (argc < 2)
        return 1;

    // preparing data
    std::vector<KNearestNeighbors::Entry> data;
    if (!KNearestNeighbors::LoadDataset(argv[1], data))
        return 2;

    std::set<int> trainingSet, testSet;
    KNearestNeighbors::SplitData(data, trainingSet, testSet);

    // generating predictions
    int correctCount = 0;

    int k;
    std::cin >> k;
    for (int test: testSet)
    {
        // finding neighbors
        std::set<int> neighbors;
        KNearestNeighbors::GetNeighbors(data, trainingSet, test, k, neighbors);

        // getting response
        auto response = KNearestNeighbors::GetResponse(data, neighbors);
        std::cout << "Predicted: " << response << ", actual: " << data[test].Class << std::endl;
        if (response == data[test].Class)
            ++correctCount;
    }

    // calculating accuracy
    std::cout << "Accuracy: " << 100.0 * correctCount / testSet.size() << "%" << std::endl;
    return 0;
}
<commit_msg>knn: added macro constant definition for the number of test instances<commit_after>#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <random>
#include <chrono>
#include <functional>
#include <algorithm>

#include <cmath>

#define NUM_FIELDS 4
#define NUM_TEST_INSTANCES 20

namespace KNearestNeighbors
{
    struct Entry
    {
        std::array<double, NUM_FIELDS> Attributes;
        std::string Class;
    };

    using IntDoublePair = std::pair<int, double>;

    struct CompareSecond: std::binary_function<IntDoublePair, IntDoublePair, bool>
    {
        bool operator()(const IntDoublePair& a, const IntDoublePair& b)
        {
            return a.second < b.second;
        }
    };

    bool LoadDataset(const char* filename, std::vector<Entry>& data)
    {
        std::ifstream filein(filename);
        if (!filein.is_open())
            return false;

        while (!filein.eof())
        {
            std::string line;
            std::getline(filein, line);
            if ("" == line)
                continue;
            std::istringstream linein(std::move(line));
            Entry entry;
            for (auto& attribute: entry.Attributes)
            {
                std::string value;
                std::getline(linein, value, ',');
                attribute = std::stod(std::move(value), nullptr);
            }
            std::getline(linein, entry.Class);
            data.push_back(std::move(entry));
        }

        return true;
    }

    void SplitData(const std::vector<Entry>& data, std::set<int>& trainingSet, std::set<int>& testSet)
    {
        std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
        std::uniform_int_distribution<> distribution(0, (int)data.size() - 1);
        while (testSet.size() < NUM_TEST_INSTANCES)
            testSet.insert(distribution(generator));
        while ((int)trainingSet.size() < (int)data.size() - NUM_TEST_INSTANCES)
        {
            int index = distribution(generator);
            if (!testSet.count(index))
                trainingSet.insert(index);
        }
    }

    void GetNeighbors(const std::vector<Entry>& data, const std::set<int>& trainingSet, int testInstance, int k, std::set<int>& neighbors)
    {
        std::set<IntDoublePair, CompareSecond> distances;
        auto euclideanDistance = [](const Entry& entry1, const Entry& entry2)
        {
            double sumDeltasSquared = 0;
            for (int i = 0; i < NUM_FIELDS; i++)
            {
                double delta = entry1.Attributes[i] - entry2.Attributes[i];
                sumDeltasSquared += delta * delta;
            }
            return sqrt(sumDeltasSquared);
        };
        for (int trainer: trainingSet)
            distances.insert(std::make_pair(trainer, euclideanDistance(data[testInstance], data[trainer])));

        auto i = distances.begin();
        for (int j = 0; j < k; ++j, ++i)
            neighbors.insert(i->first);
    }

    std::string GetResponse(const std::vector<Entry>& data, const std::set<int>& neighbors)
    {
        std::map<std::string, int> classVotes;
        for (int neighbor: neighbors)
        {
            auto response = data[neighbor].Class;
            if (classVotes.count(response))
                ++classVotes[response];
            else
                classVotes[response] = 1;
        }

        auto compareSecond = [](const auto& a, const auto& b)
        {
            return a.second < b.second;
        };
        auto responsePos = std::max_element(classVotes.begin(), classVotes.end(), compareSecond);
        return responsePos->first;
    }
}

int main(int argc, const char* const* argv)
{
    if (argc < 2)
        return 1;

    // preparing data
    std::vector<KNearestNeighbors::Entry> data;
    if (!KNearestNeighbors::LoadDataset(argv[1], data))
        return 2;

    std::set<int> trainingSet, testSet;
    KNearestNeighbors::SplitData(data, trainingSet, testSet);

    // generating predictions
    int correctCount = 0;

    int k;
    std::cin >> k;
    for (int test: testSet)
    {
        // finding neighbors
        std::set<int> neighbors;
        KNearestNeighbors::GetNeighbors(data, trainingSet, test, k, neighbors);

        // getting response
        auto response = KNearestNeighbors::GetResponse(data, neighbors);
        std::cout << "Predicted: " << response << ", actual: " << data[test].Class << std::endl;
        if (response == data[test].Class)
            ++correctCount;
    }

    // calculating accuracy
    std::cout << "Accuracy: " << 100.0 * correctCount / testSet.size() << "%" << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>#include "config.h"
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cstring>

using namespace std;

//// parameters

// for bam file
int32_t min_bundle_gap = 100;
int min_num_hits_in_bundle = 20;
int32_t min_splice_boundary_hits = 1;
uint32_t min_max_splice_boundary_qual = 3;
double min_average_overlap = 2;
int min_max_region_overlap = 5;
double min_region_coverage = 0.5;
int max_num_bundles = -1;
int slope_bin_size = 5;
int slope_min_score = 32;
int slope_extend_score = 20;
int slope_min_bin_num = 16;
int slope_min_distance = 100;
int slope_flexible_bin_num = 2;
double slope_acceptance_sigma = 2.0;
int32_t average_read_length = 100;
int32_t average_slope_length = 240;
int pseudo_length_count = 10;
double min_boundary_edge_weight_ratio = 0.05;

// for algorithm
int max_dp_table_size = 10000;
int max_num_subsetsum_solutions = 10;
double max_equation_error_ratio = 0.2;

// for simulation
int simulation_num_vertices = 0;
int simulation_num_edges = 0;
int simulation_max_edge_weight = 0;

//// from command line
string algo;
string input_file;
string output_file;

bool output_tex_files = false;
string fixed_gene_name = "";
int min_gtf_transcripts_num = 0;
bool fast_mode = true;

int print_parameters()
{
	// for bam file
	printf("parameters:\n");
	printf("min_bundle_gap = %d\n", min_bundle_gap);
	printf("min_num_hits_in_bundle = %d\n", min_num_hits_in_bundle);
	printf("min_splice_boundary_hits = %d\n", min_splice_boundary_hits);
	printf("min_max_splice_boundary_qual = %d\n", min_max_splice_boundary_qual);
	printf("min_average_overlap = %.2lf\n", min_average_overlap);
	printf("min_max_region_overlap = %d\n", min_max_region_overlap);
	printf("min_region_coverage = %.2lf\n", min_region_coverage);
	printf("max_num_bundles = %d\n", max_num_bundles);
	printf("slope_bin_size = %d\n", slope_bin_size);
	printf("slope_min_bin_num = %d\n", slope_min_bin_num);
	printf("slope_min_distance = %d\n", slope_min_distance);
	printf("slope_min_score = %d\n", slope_min_score);
	printf("slope_extend_score = %d\n", slope_extend_score);
	printf("slope_flexible_bin_num = %d\n", slope_flexible_bin_num);
	printf("slope_acceptance_sigma = %.2lf\n", slope_acceptance_sigma);
	printf("average_slope_length = %d\n", average_slope_length);
	printf("average_read_length = %d\n", average_read_length);
	printf("pseudo_length_count = %d\n", pseudo_length_count);
	printf("min_boundary_edge_weight_ratio = %.2lf\n", min_boundary_edge_weight_ratio);

	// for algorithm
	printf("max_dp_table_size = %d\n", max_dp_table_size);
	printf("max_num_subsetsum_solutions = %d\n", max_num_subsetsum_solutions);
	printf("max_equation_error_ratio = %.2lf\n", max_equation_error_ratio);

	// for simulation
	printf("simulation_num_vertices = %d\n", simulation_num_vertices);
	printf("simulation_num_edges = %d\n", simulation_num_edges);
	printf("simulation_max_edge_weight = %d\n", simulation_max_edge_weight);

	// for command
	printf("algo = %s\n", algo.c_str());
	printf("input_file = %s\n", input_file.c_str());
	printf("output_file = %s\n", output_file.c_str());
	printf("output_tex_files = %c\n", output_tex_files ? 'T' : 'F');
	printf("fixed_gene_name = %s\n", fixed_gene_name.c_str());
	printf("min_gtf_transcripts_num = %d\n", min_gtf_transcripts_num);
	printf("fast_mode = %c\n", fast_mode ? 'T' : 'F');
	printf("\n");

	return 0;
}

bool parse_arguments(int argc, const char ** argv)
{
	output_tex_files = false;
	bool b = false;
	for(int i = 1; i < argc; i++)
	{
		if(string(argv[i]) == "-a")
		{
			algo = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-o")
		{
			output_file = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-i")
		{
			input_file = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-g")
		{
			fixed_gene_name = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-t")
		{
			output_tex_files = true;
		}
		else if(string(argv[i]) == "-f")
		{
			fast_mode = true;
		}
		else if(string(argv[i]) == "-x")
		{
			slope_min_score = atoi(argv[i + 1]);
			i++;
		}
	}

	return b;
}

<commit_msg>update<commit_after>#include "config.h"
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cstring>

using namespace std;

//// parameters

// for bam file
int32_t min_bundle_gap = 100;
int min_num_hits_in_bundle = 20;
int32_t min_splice_boundary_hits = 1;
uint32_t min_max_splice_boundary_qual = 3;
double min_average_overlap = 2;
int min_max_region_overlap = 5;
double min_region_coverage = 0.5;
int max_num_bundles = -1;
int slope_bin_size = 5;
int slope_min_score = 32;
int slope_extend_score = 20;
int slope_min_bin_num = 16;
int slope_min_distance = 100;
int slope_flexible_bin_num = 2;
double slope_acceptance_sigma = 2.0;
int32_t average_read_length = 100;
int32_t average_slope_length = 240;
int pseudo_length_count = 10;
double min_boundary_edge_weight_ratio = 0.05;

// for algorithm
int max_dp_table_size = 10000;
int max_num_subsetsum_solutions = 10;
double max_equation_error_ratio = 0.2;

// for simulation
int simulation_num_vertices = 0;
int simulation_num_edges = 0;
int simulation_max_edge_weight = 0;

//// from command line
string algo;
string input_file;
string output_file;

bool output_tex_files = false;
string fixed_gene_name = "";
int min_gtf_transcripts_num = 0;
bool fast_mode = true;

int print_parameters()
{
	// for bam file
	printf("parameters:\n");
	printf("min_bundle_gap = %d\n", min_bundle_gap);
	printf("min_num_hits_in_bundle = %d\n", min_num_hits_in_bundle);
	printf("min_splice_boundary_hits = %d\n", min_splice_boundary_hits);
	printf("min_max_splice_boundary_qual = %d\n", min_max_splice_boundary_qual);
	printf("min_average_overlap = %.2lf\n", min_average_overlap);
	printf("min_max_region_overlap = %d\n", min_max_region_overlap);
	printf("min_region_coverage = %.2lf\n", min_region_coverage);
	printf("max_num_bundles = %d\n", max_num_bundles);
	printf("slope_bin_size = %d\n", slope_bin_size);
	printf("slope_min_bin_num = %d\n", slope_min_bin_num);
	printf("slope_min_distance = %d\n", slope_min_distance);
	printf("slope_min_score = %d\n", slope_min_score);
	printf("slope_extend_score = %d\n", slope_extend_score);
	printf("slope_flexible_bin_num = %d\n", slope_flexible_bin_num);
	printf("slope_acceptance_sigma = %.2lf\n", slope_acceptance_sigma);
	printf("average_slope_length = %d\n", average_slope_length);
	printf("average_read_length = %d\n", average_read_length);
	printf("pseudo_length_count = %d\n", pseudo_length_count);
	printf("min_boundary_edge_weight_ratio = %.2lf\n", min_boundary_edge_weight_ratio);

	// for algorithm
	printf("max_dp_table_size = %d\n", max_dp_table_size);
	printf("max_num_subsetsum_solutions = %d\n", max_num_subsetsum_solutions);
	printf("max_equation_error_ratio = %.2lf\n", max_equation_error_ratio);

	// for simulation
	printf("simulation_num_vertices = %d\n", simulation_num_vertices);
	printf("simulation_num_edges = %d\n", simulation_num_edges);
	printf("simulation_max_edge_weight = %d\n", simulation_max_edge_weight);

	// for command
	printf("algo = %s\n", algo.c_str());
	printf("input_file = %s\n", input_file.c_str());
	printf("output_file = %s\n", output_file.c_str());
	printf("output_tex_files = %c\n", output_tex_files ? 'T' : 'F');
	printf("fixed_gene_name = %s\n", fixed_gene_name.c_str());
	printf("min_gtf_transcripts_num = %d\n", min_gtf_transcripts_num);
	printf("fast_mode = %c\n", fast_mode ? 'T' : 'F');
	printf("\n");

	return 0;
}

bool parse_arguments(int argc, const char ** argv)
{
	output_tex_files = false;
	bool b = false;
	for(int i = 1; i < argc; i++)
	{
		if(string(argv[i]) == "-a")
		{
			algo = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-o")
		{
			output_file = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-i")
		{
			input_file = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-g")
		{
			fixed_gene_name = string(argv[i + 1]);
			i++;
		}
		else if(string(argv[i]) == "-t")
		{
			output_tex_files = true;
		}
		else if(string(argv[i]) == "-f")
		{
			fast_mode = true;
		}
		else if(string(argv[i]) == "-x")
		{
			slope_min_score = atoi(argv[i + 1]);
			slope_extend_score = (int)(0.8 * slope_min_score);
			i++;
		}
	}

	return b;
}

<|endoftext|>


<commit_before>// compilation
// $ g++ -std=c++11 main.cpp -o main

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric>
#include <future>
#include <chrono>

typedef std::vector<std::string> NeptunIds;

NeptunIds readFile(const std::string& filename)
{
  NeptunIds ids;
  std::ifstream input(filename);
  unsigned int lineCount;

  input >> lineCount;

  for (int i = 0; i < lineCount; i++)
  {
    std::string id;

    input >> id;
    ids.push_back(id);
  }

  input.close();
  return ids;
}

void writeFile(const std::string& filename, NeptunIds& ids)
{
  std::ofstream output(filename);

  for (auto const& id : ids)
  {
    output << id << std::endl;
  }

  output.close();
}

template <typename T>
void bubbleSort(std::vector<T>& v)
{
  bool swapped = true;

  for (unsigned j = 1; swapped && j < v.size(); ++j)
  {
    swapped = false;

    for (unsigned i = 0; i < v.size() - j; ++i)
    {
      if (v[i] > v[i + 1])
      {
        std::swap(v[i], v[i + 1]);
        swapped = true;
      }
    }
  }
}

template <typename T>
void merge(std::vector<T>& v, std::vector<T>& v1, std::vector<T>& v2) {
  int i, j, k;
  v.clear();

  for (i = 0, j = 0, k = 0; i < v1.size() && j < v2.size(); ++k)
  {
    if (v1.at(i) <= v2.at(j))
    {
      v.push_back(v1.at(i));
      ++i;
    }
    else if (v1.at(i) > v2.at(j))
    {
      v.push_back(v2.at(j));
      ++j;
    }
    ++k;
  }

  while(i < v1.size())
  {
    v.push_back(v1.at(i));
    ++i;
  }

  while(j < v2.size())
  {
    v.push_back(v2.at(j));
    ++j;
  }
}

template <typename T>
void mergeSort(std::vector<T>& v) {
  if (v.size() <=  64)
  {
    bubbleSort(v);
    return;
  }

  std::vector<T> v1(v.begin(), v.begin() + v.size() / 2);
  std::vector<T> v2(v.begin() + v.size() / 2, v.end());

  auto future = std::async([&v1]() mutable {
    mergeSort(v1);
  });

  mergeSort(v2);

  future.wait();

  merge(v, v1, v2);
}

int main()
{
  using namespace std::chrono;

  NeptunIds ids = readFile("input.txt");

  time_point<system_clock> t0, t1;
  t0 = system_clock::now();

  mergeSort(ids);

  t1 = system_clock::now();
  std::cout << duration_cast<milliseconds>(t1 - t0).count() << "ms\n";

  writeFile("output.txt", ids);

  return 0;
}
<commit_msg>bead2: iterators<commit_after>// compilation
// $ g++ -std=c++11 main.cpp -o main

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric>
#include <future>
#include <chrono>

typedef std::vector<std::string> NeptunIds;

NeptunIds readFile(const std::string& filename)
{
  NeptunIds ids;
  std::ifstream input(filename);
  unsigned int lineCount;

  input >> lineCount;

  for (int i = 0; i < lineCount; i++)
  {
    std::string id;

    input >> id;
    ids.push_back(id);
  }

  input.close();
  return ids;
}

void writeFile(const std::string& filename, NeptunIds& ids)
{
  std::ofstream output(filename);

  for (auto const& id : ids)
  {
    output << id << std::endl;
  }

  output.close();
}

template<typename Iter>
void bubbleSort(Iter begin, Iter end)
{
  for (Iter i = begin; i != end; ++i)
  {
    for (Iter j = begin; j < i; ++j)
    {
      if (*i < *j)
      {
        std::iter_swap(i, j);
      }
    }
  }
}

template<typename Iter>
std::vector<typename Iter::value_type> merge(Iter begin, Iter middle, Iter end) {
  std::vector<typename Iter::value_type> buffer;
  buffer.reserve(std::distance(begin, end));

  Iter left(begin);
  Iter right(middle);

  const Iter &left_end = middle;
  const Iter &right_end = end;

  while (left != left_end && right != right_end)
  {
      buffer.push_back((*left <= *right) ? *left++ : *right++);
  }

  buffer.insert(buffer.end(), left, left_end);
  buffer.insert(buffer.end(), right, right_end);

  return buffer;
}

template<typename Iter>
void mergeSort(Iter begin, Iter end) {
  auto length = std::distance(begin, end);

  if (length <=  64)
  {
    bubbleSort(begin, end);
    return;
  }

  Iter middle = std::next(begin, length / 2);

  auto future = std::async(mergeSort<Iter>, begin, middle);
  mergeSort(middle, end);

  future.wait();

  auto &&v = merge(begin, middle, end);
  std::move(v.cbegin(), v.cend(), begin);
}

int main()
{
  using namespace std::chrono;

  NeptunIds ids = readFile("input.txt");

  time_point<system_clock> t0, t1;
  t0 = system_clock::now();

  mergeSort(ids.begin(), ids.end());

  t1 = system_clock::now();
  std::cout << duration_cast<milliseconds>(t1 - t0).count() << "ms\n";

  writeFile("output.txt", ids);

  return 0;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/poll.h>

#include <sal/types.h>

#include <vcl/apptypes.hxx>

#include "headless/svpinst.hxx"
#include "headless/svpframe.hxx"
#include "headless/svpdummies.hxx"
#include "headless/svpvd.hxx"
#ifdef IOS
#include "headless/svpgdi.hxx"
#include "quartz/salbmp.h"
#include "quartz/salgdi.h"
#include "quartz/salvd.h"
#endif
#include "headless/svpbmp.hxx"

#include <salframe.hxx>
#include <svdata.hxx>
#include <generic/gendata.hxx>
#include <basebmp/scanlineformats.hxx>
// FIXME: remove when we re-work the svp mainloop
#include <unx/salunxtime.h>

using namespace basebmp;

bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
{
    for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
         it != m_aFrames.end(); ++it )
    {
        if( *it == pFrame )
        {
            return true;
        }
    }
    return false;
}

SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;

SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
    SalGenericInstance( pMutex )
{
    m_aTimeout.tv_sec       = 0;
    m_aTimeout.tv_usec      = 0;
    m_nTimeoutMS            = 0;

    m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
    if (pipe (m_pTimeoutFDS) != -1)
    {
        // initialize 'wakeup' pipe.
        int flags;

        // set close-on-exec descriptor flag.
        if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
        {
            flags |= FD_CLOEXEC;
            fcntl (m_pTimeoutFDS[0], F_SETFD, flags);
        }
        if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
        {
            flags |= FD_CLOEXEC;
            fcntl (m_pTimeoutFDS[1], F_SETFD, flags);
        }

        // set non-blocking I/O flag.
        if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1)
        {
            flags |= O_NONBLOCK;
            fcntl (m_pTimeoutFDS[0], F_SETFL, flags);
        }
        if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1)
        {
            flags |= O_NONBLOCK;
            fcntl (m_pTimeoutFDS[1], F_SETFL, flags);
        }
    }
    m_aEventGuard = osl_createMutex();
    if( s_pDefaultInstance == NULL )
        s_pDefaultInstance = this;
}

SvpSalInstance::~SvpSalInstance()
{
    if( s_pDefaultInstance == this )
        s_pDefaultInstance = NULL;

    // close 'wakeup' pipe.
    close (m_pTimeoutFDS[0]);
    close (m_pTimeoutFDS[1]);
    osl_destroyMutex( m_aEventGuard );
}

void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
{
    if( osl_acquireMutex( m_aEventGuard ) )
    {
        m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
        osl_releaseMutex( m_aEventGuard );
    }
    Wakeup();
}

bool SvpSalInstance::PostedEventsInQueue()
{
    bool result = false;
    if( osl_acquireMutex( m_aEventGuard ) )
    {
        result = m_aUserEvents.size() > 0;
        osl_releaseMutex( m_aEventGuard );
    }
    return result;
}

void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
{
    m_aFrames.remove( pFrame );

    if( osl_acquireMutex( m_aEventGuard ) )
    {
        // cancel outstanding events for this frame
        if( ! m_aUserEvents.empty() )
        {
            std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
            do
            {
                if( it->m_pFrame    == pFrame )
                {
                    it = m_aUserEvents.erase( it );
                }
                else
                    ++it;
            } while( it != m_aUserEvents.end() );
        }
        osl_releaseMutex( m_aEventGuard );
    }
}

void SvpSalInstance::Wakeup()
{
    OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
}

bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
{
    bool bRet = false;
    if( m_aTimeout.tv_sec ) // timer is started
    {
        timeval aTimeOfDay;
        gettimeofday( &aTimeOfDay, 0 );
        if( aTimeOfDay >= m_aTimeout )
        {
            bRet = true;
            if( bExecuteTimers )
            {
                // timed out, update timeout
                m_aTimeout = aTimeOfDay;
                m_aTimeout += m_nTimeoutMS;

                osl::Guard< comphelper::SolarMutex > aGuard( mpSalYieldMutex );

                // notify
                ImplSVData* pSVData = ImplGetSVData();
                if( pSVData->mpSalTimer )
                    pSVData->mpSalTimer->CallCallback();
            }
        }
    }
    return bRet;
}

SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
{
    return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
}

SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
{
    return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
}

void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
{
    delete pFrame;
}

SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, bool )
{
    return new SvpSalObject();
}

void SvpSalInstance::DestroyObject( SalObject* pObject )
{
    delete pObject;
}

#ifndef IOS

SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics */,
                                                       long nDX, long nDY,
                                                       sal_uInt16 nBitCount,
                                                       const SystemGraphicsData* /* pData */ )
{
    SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
    pNew->SetSize( nDX, nDY );
    return pNew;
}

#endif

SalTimer* SvpSalInstance::CreateSalTimer()
{
    return new SvpSalTimer( this );
}

SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
{
    return new SvpImeStatus();
}

SalSystem* SvpSalInstance::CreateSalSystem()
{
    return new SvpSalSystem();
}

SalBitmap* SvpSalInstance::CreateSalBitmap()
{
#ifdef IOS
    return new QuartzSalBitmap();
#else
    return new SvpSalBitmap();
#endif
}

void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
    // first, check for already queued events.

    // release yield mutex
    std::list< SalUserEvent > aEvents;
    sal_uLong nAcquireCount = ReleaseYieldMutex();
    if( osl_acquireMutex( m_aEventGuard ) )
    {
        if( ! m_aUserEvents.empty() )
        {
            if( bHandleAllCurrentEvents )
            {
                aEvents = m_aUserEvents;
                m_aUserEvents.clear();
            }
            else
            {
                aEvents.push_back( m_aUserEvents.front() );
                m_aUserEvents.pop_front();
            }
        }
        osl_releaseMutex( m_aEventGuard );
    }
    // acquire yield mutex again
    AcquireYieldMutex( nAcquireCount );

    bool bEvent = !aEvents.empty();
    if( bEvent )
    {
        for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
        {
            if ( isFrameAlive( it->m_pFrame ) )
            {
                it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
                if( it->m_nEvent == SALEVENT_RESIZE )
                {
                    // this would be a good time to post a paint
                    const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
                    pSvpFrame->PostPaint(false);
                }
            }
        }
    }

    bEvent = CheckTimeout() || bEvent;

    if (bWait && ! bEvent )
    {
        int nTimeoutMS = 0;
        if (m_aTimeout.tv_sec) // Timer is started.
        {
            timeval Timeout;
            // determine remaining timeout.
            gettimeofday (&Timeout, 0);
            nTimeoutMS = m_aTimeout.tv_sec*1000 + m_aTimeout.tv_usec/1000
                         - Timeout.tv_sec*1000 - Timeout.tv_usec/1000;
            if( nTimeoutMS < 0 )
                nTimeoutMS = 0;
        }
        else
            nTimeoutMS = -1; // wait until something happens

        DoReleaseYield(nTimeoutMS);
    }
}

void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
{
    // poll
    struct pollfd aPoll;
    aPoll.fd = m_pTimeoutFDS[0];
    aPoll.events = POLLIN;
    aPoll.revents = 0;

    // release yield mutex
    sal_uLong nAcquireCount = ReleaseYieldMutex();

    (void)poll( &aPoll, 1, nTimeoutMS );

    // acquire yield mutex again
    AcquireYieldMutex( nAcquireCount );

    // clean up pipe
    if( (aPoll.revents & POLLIN) != 0 )
    {
        int buffer;
        while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
            continue;
    }
}

bool SvpSalInstance::AnyInput( sal_uInt16 nType )
{
    if( (nType & VCL_INPUT_TIMER) != 0 )
        return CheckTimeout( false );
    return false;
}

SalSession* SvpSalInstance::CreateSalSession()
{
    return NULL;
}

void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
{
    rReturnedBytes  = 1;
    rReturnedType   = AsciiCString;
    return const_cast<char*>("");
}

void SvpSalInstance::StopTimer()
{
    m_aTimeout.tv_sec   = 0;
    m_aTimeout.tv_usec  = 0;
    m_nTimeoutMS        = 0;
}

void SvpSalInstance::StartTimer( sal_uLong nMS )
{
    timeval aPrevTimeout (m_aTimeout);
    gettimeofday (&m_aTimeout, 0);

    m_nTimeoutMS  = nMS;
    m_aTimeout    += m_nTimeoutMS;

    if ((aPrevTimeout > m_aTimeout) || (aPrevTimeout.tv_sec == 0))
    {
        // Wakeup from previous timeout (or stopped timer).
        Wakeup();
    }
}

void SvpSalInstance::AddToRecentDocumentList(const OUString&, const OUString&, const OUString&)
{
}

SvpSalTimer::~SvpSalTimer()
{
}

void SvpSalTimer::Stop()
{
    m_pInstance->StopTimer();
}

void SvpSalTimer::Start( sal_uLong nMS )
{
    m_pInstance->StartTimer( nMS );
}

void SvpSalInstance::setBitCountFormatMapping( sal_uInt16 nBitCount,
                                            Format aFormat )
{
    m_aBitCountFormatMap[nBitCount] = aFormat;
}

Format SvpSalInstance::getFormatForBitCount( sal_uInt16 nBitCount )
{
    BitCountFormatMap::iterator aIt;
    if ( (aIt = m_aBitCountFormatMap.find( nBitCount )) != m_aBitCountFormatMap.end() )
    {
        return aIt->second;
    }

    switch( nBitCount )
    {
        case 1:
            return FORMAT_ONE_BIT_MSB_PAL;
        case 4:
            return FORMAT_FOUR_BIT_MSB_PAL;
        case 8:
            return FORMAT_EIGHT_BIT_PAL;
        case 16:
#ifdef OSL_BIGENDIAN
            return FORMAT_SIXTEEN_BIT_MSB_TC_MASK;
#else
            return FORMAT_SIXTEEN_BIT_LSB_TC_MASK;
#endif
        case 24:
            return FORMAT_TWENTYFOUR_BIT_TC_MASK;
        case 32:
            return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA;
        case 0:
#ifdef ANDROID
            return FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA;
#else
            return FORMAT_TWENTYFOUR_BIT_TC_MASK;
#endif
        default:
            return SVP_DEFAULT_BITMAP_FORMAT;
     }

}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#735342 silence Unchecked return value from library<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/poll.h>

#include <sal/types.h>

#include <vcl/apptypes.hxx>

#include "headless/svpinst.hxx"
#include "headless/svpframe.hxx"
#include "headless/svpdummies.hxx"
#include "headless/svpvd.hxx"
#ifdef IOS
#include "headless/svpgdi.hxx"
#include "quartz/salbmp.h"
#include "quartz/salgdi.h"
#include "quartz/salvd.h"
#endif
#include "headless/svpbmp.hxx"

#include <salframe.hxx>
#include <svdata.hxx>
#include <generic/gendata.hxx>
#include <basebmp/scanlineformats.hxx>
// FIXME: remove when we re-work the svp mainloop
#include <unx/salunxtime.h>

using namespace basebmp;

bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
{
    for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
         it != m_aFrames.end(); ++it )
    {
        if( *it == pFrame )
        {
            return true;
        }
    }
    return false;
}

SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;

SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
    SalGenericInstance( pMutex )
{
    m_aTimeout.tv_sec       = 0;
    m_aTimeout.tv_usec      = 0;
    m_nTimeoutMS            = 0;

    m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
    if (pipe (m_pTimeoutFDS) != -1)
    {
        // initialize 'wakeup' pipe.
        int flags;

        // set close-on-exec descriptor flag.
        if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
        {
            flags |= FD_CLOEXEC;
            fcntl (m_pTimeoutFDS[0], F_SETFD, flags);
        }
        if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
        {
            flags |= FD_CLOEXEC;
            fcntl (m_pTimeoutFDS[1], F_SETFD, flags);
        }

        // set non-blocking I/O flag.
        if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1)
        {
            flags |= O_NONBLOCK;
            (void)fcntl(m_pTimeoutFDS[0], F_SETFL, flags);
        }
        if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1)
        {
            flags |= O_NONBLOCK;
            (void)fcntl(m_pTimeoutFDS[1], F_SETFL, flags);
        }
    }
    m_aEventGuard = osl_createMutex();
    if( s_pDefaultInstance == NULL )
        s_pDefaultInstance = this;
}

SvpSalInstance::~SvpSalInstance()
{
    if( s_pDefaultInstance == this )
        s_pDefaultInstance = NULL;

    // close 'wakeup' pipe.
    close (m_pTimeoutFDS[0]);
    close (m_pTimeoutFDS[1]);
    osl_destroyMutex( m_aEventGuard );
}

void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
{
    if( osl_acquireMutex( m_aEventGuard ) )
    {
        m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
        osl_releaseMutex( m_aEventGuard );
    }
    Wakeup();
}

bool SvpSalInstance::PostedEventsInQueue()
{
    bool result = false;
    if( osl_acquireMutex( m_aEventGuard ) )
    {
        result = m_aUserEvents.size() > 0;
        osl_releaseMutex( m_aEventGuard );
    }
    return result;
}

void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
{
    m_aFrames.remove( pFrame );

    if( osl_acquireMutex( m_aEventGuard ) )
    {
        // cancel outstanding events for this frame
        if( ! m_aUserEvents.empty() )
        {
            std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
            do
            {
                if( it->m_pFrame    == pFrame )
                {
                    it = m_aUserEvents.erase( it );
                }
                else
                    ++it;
            } while( it != m_aUserEvents.end() );
        }
        osl_releaseMutex( m_aEventGuard );
    }
}

void SvpSalInstance::Wakeup()
{
    OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
}

bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
{
    bool bRet = false;
    if( m_aTimeout.tv_sec ) // timer is started
    {
        timeval aTimeOfDay;
        gettimeofday( &aTimeOfDay, 0 );
        if( aTimeOfDay >= m_aTimeout )
        {
            bRet = true;
            if( bExecuteTimers )
            {
                // timed out, update timeout
                m_aTimeout = aTimeOfDay;
                m_aTimeout += m_nTimeoutMS;

                osl::Guard< comphelper::SolarMutex > aGuard( mpSalYieldMutex );

                // notify
                ImplSVData* pSVData = ImplGetSVData();
                if( pSVData->mpSalTimer )
                    pSVData->mpSalTimer->CallCallback();
            }
        }
    }
    return bRet;
}

SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
{
    return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
}

SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
{
    return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
}

void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
{
    delete pFrame;
}

SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, bool )
{
    return new SvpSalObject();
}

void SvpSalInstance::DestroyObject( SalObject* pObject )
{
    delete pObject;
}

#ifndef IOS

SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics */,
                                                       long nDX, long nDY,
                                                       sal_uInt16 nBitCount,
                                                       const SystemGraphicsData* /* pData */ )
{
    SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
    pNew->SetSize( nDX, nDY );
    return pNew;
}

#endif

SalTimer* SvpSalInstance::CreateSalTimer()
{
    return new SvpSalTimer( this );
}

SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
{
    return new SvpImeStatus();
}

SalSystem* SvpSalInstance::CreateSalSystem()
{
    return new SvpSalSystem();
}

SalBitmap* SvpSalInstance::CreateSalBitmap()
{
#ifdef IOS
    return new QuartzSalBitmap();
#else
    return new SvpSalBitmap();
#endif
}

void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
    // first, check for already queued events.

    // release yield mutex
    std::list< SalUserEvent > aEvents;
    sal_uLong nAcquireCount = ReleaseYieldMutex();
    if( osl_acquireMutex( m_aEventGuard ) )
    {
        if( ! m_aUserEvents.empty() )
        {
            if( bHandleAllCurrentEvents )
            {
                aEvents = m_aUserEvents;
                m_aUserEvents.clear();
            }
            else
            {
                aEvents.push_back( m_aUserEvents.front() );
                m_aUserEvents.pop_front();
            }
        }
        osl_releaseMutex( m_aEventGuard );
    }
    // acquire yield mutex again
    AcquireYieldMutex( nAcquireCount );

    bool bEvent = !aEvents.empty();
    if( bEvent )
    {
        for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
        {
            if ( isFrameAlive( it->m_pFrame ) )
            {
                it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
                if( it->m_nEvent == SALEVENT_RESIZE )
                {
                    // this would be a good time to post a paint
                    const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
                    pSvpFrame->PostPaint(false);
                }
            }
        }
    }

    bEvent = CheckTimeout() || bEvent;

    if (bWait && ! bEvent )
    {
        int nTimeoutMS = 0;
        if (m_aTimeout.tv_sec) // Timer is started.
        {
            timeval Timeout;
            // determine remaining timeout.
            gettimeofday (&Timeout, 0);
            nTimeoutMS = m_aTimeout.tv_sec*1000 + m_aTimeout.tv_usec/1000
                         - Timeout.tv_sec*1000 - Timeout.tv_usec/1000;
            if( nTimeoutMS < 0 )
                nTimeoutMS = 0;
        }
        else
            nTimeoutMS = -1; // wait until something happens

        DoReleaseYield(nTimeoutMS);
    }
}

void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
{
    // poll
    struct pollfd aPoll;
    aPoll.fd = m_pTimeoutFDS[0];
    aPoll.events = POLLIN;
    aPoll.revents = 0;

    // release yield mutex
    sal_uLong nAcquireCount = ReleaseYieldMutex();

    (void)poll( &aPoll, 1, nTimeoutMS );

    // acquire yield mutex again
    AcquireYieldMutex( nAcquireCount );

    // clean up pipe
    if( (aPoll.revents & POLLIN) != 0 )
    {
        int buffer;
        while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
            continue;
    }
}

bool SvpSalInstance::AnyInput( sal_uInt16 nType )
{
    if( (nType & VCL_INPUT_TIMER) != 0 )
        return CheckTimeout( false );
    return false;
}

SalSession* SvpSalInstance::CreateSalSession()
{
    return NULL;
}

void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
{
    rReturnedBytes  = 1;
    rReturnedType   = AsciiCString;
    return const_cast<char*>("");
}

void SvpSalInstance::StopTimer()
{
    m_aTimeout.tv_sec   = 0;
    m_aTimeout.tv_usec  = 0;
    m_nTimeoutMS        = 0;
}

void SvpSalInstance::StartTimer( sal_uLong nMS )
{
    timeval aPrevTimeout (m_aTimeout);
    gettimeofday (&m_aTimeout, 0);

    m_nTimeoutMS  = nMS;
    m_aTimeout    += m_nTimeoutMS;

    if ((aPrevTimeout > m_aTimeout) || (aPrevTimeout.tv_sec == 0))
    {
        // Wakeup from previous timeout (or stopped timer).
        Wakeup();
    }
}

void SvpSalInstance::AddToRecentDocumentList(const OUString&, const OUString&, const OUString&)
{
}

SvpSalTimer::~SvpSalTimer()
{
}

void SvpSalTimer::Stop()
{
    m_pInstance->StopTimer();
}

void SvpSalTimer::Start( sal_uLong nMS )
{
    m_pInstance->StartTimer( nMS );
}

void SvpSalInstance::setBitCountFormatMapping( sal_uInt16 nBitCount,
                                            Format aFormat )
{
    m_aBitCountFormatMap[nBitCount] = aFormat;
}

Format SvpSalInstance::getFormatForBitCount( sal_uInt16 nBitCount )
{
    BitCountFormatMap::iterator aIt;
    if ( (aIt = m_aBitCountFormatMap.find( nBitCount )) != m_aBitCountFormatMap.end() )
    {
        return aIt->second;
    }

    switch( nBitCount )
    {
        case 1:
            return FORMAT_ONE_BIT_MSB_PAL;
        case 4:
            return FORMAT_FOUR_BIT_MSB_PAL;
        case 8:
            return FORMAT_EIGHT_BIT_PAL;
        case 16:
#ifdef OSL_BIGENDIAN
            return FORMAT_SIXTEEN_BIT_MSB_TC_MASK;
#else
            return FORMAT_SIXTEEN_BIT_LSB_TC_MASK;
#endif
        case 24:
            return FORMAT_TWENTYFOUR_BIT_TC_MASK;
        case 32:
            return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA;
        case 0:
#ifdef ANDROID
            return FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA;
#else
            return FORMAT_TWENTYFOUR_BIT_TC_MASK;
#endif
        default:
            return SVP_DEFAULT_BITMAP_FORMAT;
     }

}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vrj/Draw/Pf/PfInputHandler.h>

namespace vrj
{

PfInputHandler::PfInputHandler(pfPipeWindow* pWin, const std::string& displayName)
{
#ifdef VPR_OS_Win32
   mWinHandle = pWin->getWSWindow();
#else
   // Get the XWindow from that we are going to recieve events from.
   mXWindow = pWin->getWSWindow();

   // Create a new display connection to the X server.
   mXDisplay = XOpenDisplay( displayName.c_str());
#endif
}

#ifdef VPR_OS_Win32
void PfInputHandler::handlePerformerEvent(MSG message)
{
   // If we have a valid KeyboardMouseDevice, process
   // all keyboard/mouse events
   if ( NULL != mKeyboardMouseDevice )
   {
      // Forward events on to subclass. The magic of inheritance :)
      InputAreaWin32::updKeys( message );
   }
}
#else
void PfInputHandler::handlePerformerEvent(::XEvent& event)
{
   // If we have a valid KeyboardMouseDevice, process
   // all keyboard/mouse events
   if ( NULL != mKeyboardMouseDevice )
   {
      // Forward events on to subclass. The magic of inheritance :)
      InputAreaXWin::handleEvent( event );
   }
}
#endif

} // End of vrj namespace
<commit_msg>Bug fixed:	Compile failure with MIPSpro Compilers SF Bug#:	1097225<commit_after>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vrj/Draw/Pf/PfInputHandler.h>

namespace vrj
{

PfInputHandler::PfInputHandler(pfPipeWindow* pWin, const std::string& displayName)
{
#ifdef VPR_OS_Win32
   mWinHandle = pWin->getWSWindow();
#else
   // Get the XWindow from that we are going to recieve events from.
   mXWindow = pWin->getWSWindow();

   // Create a new display connection to the X server.
   mXDisplay = XOpenDisplay( displayName.c_str());
#endif
}

#ifdef VPR_OS_Win32
void PfInputHandler::handlePerformerEvent(MSG message)
{
   // If we have a valid KeyboardMouseDevice, process
   // all keyboard/mouse events
   if ( NULL != mKeyboardMouseDevice )
   {
      // Forward events on to subclass. The magic of inheritance :)
      InputAreaWin32::updKeys( message );
   }
}
#else
void PfInputHandler::handlePerformerEvent(::XEvent& event)
{
   // If we have a valid KeyboardMouseDevice, process
   // all keyboard/mouse events
   if ( NULL != mKeyboardMouseDevice )
   {
      // Forward events on to subclass. The magic of inheritance :)
      handleEvent(event);
   }
}
#endif

} // End of vrj namespace
<|endoftext|>


<commit_before><commit_msg>Remove a duplicate declaration of default_histogram_levels.<commit_after><|endoftext|>