<commit_before>/**
* \file
* Copyright 2018 Axel Huebl
*
* This file is part of alpaka.
*
* alpaka is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* alpaka 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with alpaka.
* If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <boost/predef.h>

#include <cstdint>

#if BOOST_COMP_CLANG
#   pragma clang diagnostic push
#   pragma clang diagnostic ignored "-Wold-style-cast"
#   pragma clang diagnostic push
#   pragma clang diagnostic ignored "-Wsign-conversion"
#endif
#if BOOST_COMP_GNUC
#   pragma GCC diagnostic push
#   pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#include <alpaka/rand/TinyMT/tinymt32.h>
#if BOOST_COMP_CLANG
#   pragma clang diagnostic pop
#   pragma clang diagnostic pop
#endif
#if BOOST_COMP_GNUC
#   pragma GCC diagnostic pop
#endif

namespace alpaka
{
namespace rand
{
namespace generator
{
namespace cpu
{
    //! Implementation of std::UniformRandomBitGenerator for TinyMT32
    struct TinyMTengine
    {
        using result_type = std::uint32_t;

        static constexpr result_type default_seed()
        {
            return 42u;
        }

        void seed( result_type value = default_seed() )
        {
            tinymt32_init( &prng, value );
        }

        TinyMTengine( std::uint32_t const & seedValue )
        {
            // parameters from TinyMT/jump/sample.c
            prng.mat1 = 0x8f7011ee;
            prng.mat2 = 0xfc78ff1f;
            prng.tmat = 0x3793fdff;

            seed( seedValue );
        }

        TinyMTengine() = delete;

        result_type operator()()
        {
            return tinymt32_generate_uint32( &prng );
        }

        static constexpr result_type min()
        {
            return 0u;
        }

        static constexpr result_type max()
        {
            return UINT32_MAX;
        }

        void discard( unsigned long long ) // z
        {
            // not implemented
            // tinymt32_jump( &prng, z, z );
        }

        tinymt32_t prng;
    };

} // namespace cpu
} // namespace generator
} // namespace rand
} // namespace alpaka
<commit_msg>TinyMT Engine: Default Seed<commit_after>/**
* \file
* Copyright 2018 Axel Huebl
*
* This file is part of alpaka.
*
* alpaka is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* alpaka 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with alpaka.
* If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <boost/predef.h>

#include <cstdint>

#if BOOST_COMP_CLANG
#   pragma clang diagnostic push
#   pragma clang diagnostic ignored "-Wold-style-cast"
#   pragma clang diagnostic push
#   pragma clang diagnostic ignored "-Wsign-conversion"
#endif
#if BOOST_COMP_GNUC
#   pragma GCC diagnostic push
#   pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#include <alpaka/rand/TinyMT/tinymt32.h>
#if BOOST_COMP_CLANG
#   pragma clang diagnostic pop
#   pragma clang diagnostic pop
#endif
#if BOOST_COMP_GNUC
#   pragma GCC diagnostic pop
#endif

namespace alpaka
{
namespace rand
{
namespace generator
{
namespace cpu
{
    //! Implementation of std::UniformRandomBitGenerator for TinyMT32
    struct TinyMTengine
    {
        using result_type = std::uint32_t;

        static constexpr result_type default_seed()
        {
            return 42u;
        }

        void seed( result_type value = default_seed() )
        {
            // parameters from TinyMT/jump/sample.c
            prng.mat1 = 0x8f7011ee;
            prng.mat2 = 0xfc78ff1f;
            prng.tmat = 0x3793fdff;

            tinymt32_init( &prng, value );
        }

        TinyMTengine( std::uint32_t const & seedValue )
        {
            seed( seedValue );
        }

        TinyMTengine()
        {
            std::uint32_t const magicSeed = 42u;
            seed( magicSeed );
        }

        result_type operator()()
        {
            return tinymt32_generate_uint32( &prng );
        }

        static constexpr result_type min()
        {
            return 0u;
        }

        static constexpr result_type max()
        {
            return UINT32_MAX;
        }

        void discard( unsigned long long ) // z
        {
            // not implemented
            // tinymt32_jump( &prng, z, z );
        }

        tinymt32_t prng;
    };

} // namespace cpu
} // namespace generator
} // namespace rand
} // namespace alpaka
<|endoftext|>


<commit_before>#include "acmacs-base/pybind11.hh"

// chart
#include "acmacs-chart-2/factory-import.hh"
#include "acmacs-chart-2/factory-export.hh"
#include "acmacs-chart-2/chart-modify.hh"

// merge
#include "acmacs-chart-2/merge.hh"

// ======================================================================

inline unsigned make_info_data(bool column_bases, bool tables, bool tables_for_sera, bool antigen_dates)
{
    using namespace acmacs::chart;
    return (column_bases ? info_data::column_bases : 0)         //
           | (tables ? info_data::tables : 0)                   //
           | (tables_for_sera ? info_data::tables_for_sera : 0) //
           | (antigen_dates ? info_data::dates : 0);
}

// ----------------------------------------------------------------------

inline acmacs::chart::ChartClone::clone_data clone_type(const std::string& type)
{
    using namespace acmacs::chart;
    if (type == "titers")
        return ChartClone::clone_data::titers;
    else if (type == "projections")
        return ChartClone::clone_data::projections;
    else if (type == "plot_spec")
        return ChartClone::clone_data::plot_spec;
    else if (type == "projections_plot_spec")
        return ChartClone::clone_data::projections_plot_spec;
    else
        throw std::invalid_argument{fmt::format("Unrecognized clone \"type\": \"{}\"", type)};
}

// ----------------------------------------------------------------------

template <typename AgSr> struct AgSrIndexes
{
    AgSrIndexes(std::shared_ptr<AgSr> a_ag_sr) : ag_sr{a_ag_sr}, indexes{a_ag_sr->all_indexes()} {}

    std::shared_ptr<AgSr> ag_sr;
    acmacs::chart::Indexes indexes;
};

// ----------------------------------------------------------------------

inline void py_chart(py::module_& mdl)
{
    using namespace pybind11::literals;
    using namespace acmacs::chart;

    py::class_<ChartModify, std::shared_ptr<ChartModify>>(mdl, "Chart") //
        .def(py::init([](const std::string& filename) { return std::make_shared<ChartModify>(import_from_file(filename)); }), py::doc("imports chart from a file"))

        .def(
            "clone",                                                                                //
            [](ChartModify& chart, const std::string& type) -> std::shared_ptr<ChartModify> { return std::make_shared<ChartClone>(chart, clone_type(type)); }, //
            "type"_a = "titers",                                                                                //
            py::doc(R"(type: "titers", "projections", "plot_spec", "projections_plot_spec")"))                                                                 //

        .def(
            "make_name",                                                            //
            [](const ChartModify& chart) { return chart.make_name(std::nullopt); }, //
            py::doc("returns name of the chart"))                                   //

        .def(
            "make_name",                                                                                //
            [](const ChartModify& chart, size_t projection_no) { return chart.make_name(projection_no); }, //
            "projection_no"_a,                                                                             //
            py::doc("returns name of the chart with the stress of the passed projection"))                 //

        .def("subtype", [](const ChartModify& chart) { return *chart.info()->virus_type(); })                            //
        .def("subtype_short", [](const ChartModify& chart) { return std::string{chart.info()->virus_type().h_or_b()}; }) //
        .def("subset", [](const ChartModify& chart) { return chart.info()->subset(); })                                  //
        .def("assay", [](const ChartModify& chart) { return *chart.info()->assay(); })                                   //
        .def("assay_hi_or_neut", [](const ChartModify& chart) { return chart.info()->assay().hi_or_neut(); })            //
        .def("lab", [](const ChartModify& chart) { return *chart.info()->lab(); })                                       //
        .def("rbc", [](const ChartModify& chart) { return *chart.info()->rbc_species(); })                               //
        .def("date", [](const ChartModify& chart) { return *chart.info()->date(Info::Compute::Yes); })                   //
        .def(
            "lineage", [](const ChartModify& chart) { return *chart.lineage(); }, py::doc("returns chart lineage: VICTORIA, YAMAGATA")) //

        .def("description",                                 //
             &Chart::description,                           //
             py::doc("returns chart one line description")) //

        .def(
            "make_info", //
            [](const ChartModify& chart, size_t max_number_of_projections_to_show, bool column_bases, bool tables, bool tables_for_sera, bool antigen_dates) {
                return chart.make_info(max_number_of_projections_to_show, make_info_data(column_bases, tables, tables_for_sera, antigen_dates));
            },                                                                                //
            "max_number_of_projections_to_show"_a = 20, "column_bases"_a = true, "tables"_a = false, "tables_for_sera"_a = false, "antigen_dates"_a = false, //
            py::doc("returns detailed chart description"))                                                                                //

        .def("number_of_antigens", &Chart::number_of_antigens)
        .def("number_of_sera", &Chart::number_of_sera)
        .def("number_of_projections", &Chart::number_of_projections)

        .def(
            "relax", //
            [](ChartModify& chart, size_t number_of_dimensions, size_t number_of_optimizations, const std::string& minimum_column_basis, bool dimension_annealing, bool rough,
               size_t /*number_of_best_distinct_projections_to_keep*/) {
                if (number_of_optimizations == 0)
                    number_of_optimizations = 100;
                chart.relax(number_of_optimizations_t{number_of_optimizations}, MinimumColumnBasis{minimum_column_basis}, acmacs::number_of_dimensions_t{number_of_dimensions},
                            use_dimension_annealing_from_bool(dimension_annealing), optimization_options{optimization_precision{rough ? optimization_precision::rough : optimization_precision::fine}});
                chart.projections_modify().sort();
            }, //
            "number_of_dimensions"_a = 2, "number_of_optimizations"_a = 0, "minimum_column_basis"_a = "none", "dimension_annealing"_a = false, "rough"_a = false,
            "number_of_best_distinct_projections_to_keep"_a = 5,                                                                              //
            py::doc{"makes one or more antigenic maps from random starting layouts, adds new projections, projections are sorted by stress"}) //

        .def(
            "relax_incremental", //
            [](ChartModify& chart, size_t number_of_optimizations, bool rough, size_t number_of_best_distinct_projections_to_keep, bool remove_source_projection, bool unmovable_non_nan_points) {
                if (number_of_optimizations == 0)
                    number_of_optimizations = 100;
                chart.relax_incremental(0, number_of_optimizations_t{number_of_optimizations},
                                        optimization_options{optimization_precision{rough ? optimization_precision::rough : optimization_precision::fine}},
                                        acmacs::chart::remove_source_projection{remove_source_projection ? acmacs::chart::remove_source_projection::yes : acmacs::chart::remove_source_projection::no},
                                        acmacs::chart::unmovable_non_nan_points{unmovable_non_nan_points ? acmacs::chart::unmovable_non_nan_points::yes : acmacs::chart::unmovable_non_nan_points::no});
                chart.projections_modify().sort();
            },                                                                                //
            "number_of_optimizations"_a = 0, "rough"_a = false, "number_of_best_distinct_projections_to_keep"_a = 5, "remove_source_projection"_a = true, "unmovable_non_nan_points"_a = false) //

        .def(
            "projection",                                                                                //
            [](ChartModify& chart, size_t projection_no) { return chart.projection_modify(projection_no); }, //
            "projection_no"_a = 0)                                                                           //

        .def("remove_all_projections",                                                   //
             [](ChartModify& chart) { return chart.projections_modify().remove_all(); }) //

        .def(
            "keep_projections",                                                                               //
            [](ChartModify& chart, size_t to_keep) { return chart.projections_modify().keep_just(to_keep); }, //
            "keep"_a)                                                                                //

        .def(
            "export",                                                                                //
            [](ChartModify& chart, const std::string& filename, const std::string& program_name) { acmacs::chart::export_factory(chart, filename, program_name); }, //
            "filename"_a, "program_name"_a)                                                                                //

        .def("antigen_indexes",                                                                                //
             [](ChartModify& chart) { return std::make_shared<AgSrIndexes<acmacs::chart::Antigens>>(chart.antigens()); }) //
        .def("serum_indexes",                                                                                //
             [](ChartModify& chart) { return std::make_shared<AgSrIndexes<acmacs::chart::Sera>>(chart.sera()); })         //
        ;

    // ----------------------------------------------------------------------

    py::class_<ProjectionModify, std::shared_ptr<ProjectionModify>>(mdl, "Projection") //
        .def(
            "stress",                                                                                //
            [](const ProjectionModify& projection, bool recalculate) { return projection.stress(recalculate ? RecalculateStress::if_necessary : RecalculateStress::no); }, //
            "recalculate"_a = false)                                                                                //
        ;

    py::class_<AgSrIndexes<acmacs::chart::Antigens>, std::shared_ptr<AgSrIndexes<acmacs::chart::Antigens>>>(mdl, "AntigenIndexes") //
        .def("__str__", [](const AgSrIndexes<acmacs::chart::Antigens>& indexes) { return fmt::format("AntigenIndexes({}){}", indexes.indexes.size(), indexes.indexes); })

        .def(
            "filter_lineage",
            [](AgSrIndexes<acmacs::chart::Antigens>& indexes, const std::string& lineage) {
                indexes.ag_sr->filter_lineage(indexes.indexes, acmacs::chart::BLineage{lineage});
                return indexes;
            },           //
            "lineage"_a) //
        ;

    py::class_<AgSrIndexes<acmacs::chart::Sera>, std::shared_ptr<AgSrIndexes<acmacs::chart::Sera>>>(mdl, "SerumIndexes") //
        .def("__str__", [](const AgSrIndexes<acmacs::chart::Sera>& indexes) { return fmt::format("SerumIndexes({}){}", indexes.indexes.size(), indexes.indexes); })

        .def(
            "filter_lineage",
            [](AgSrIndexes<acmacs::chart::Sera>& indexes, const std::string& lineage) {
                indexes.ag_sr->filter_lineage(indexes.indexes, acmacs::chart::BLineage{lineage});
                return indexes;
            },           //
            "lineage"_a) //
        ;
}

// ======================================================================

inline void py_merge(py::module_& mdl)
{
    using namespace pybind11::literals;
    using namespace acmacs::chart;

    mdl.def(
        "merge",
        [](std::shared_ptr<ChartModify> chart1, std::shared_ptr<ChartModify> chart2, const std::string& merge_type, const std::string& match, bool remove_distinct) {
            CommonAntigensSera::match_level_t match_level{CommonAntigensSera::match_level_t::automatic};
            if (match == "auto" || match == "automatic")
                match_level = CommonAntigensSera::match_level_t::automatic;
            else if (match == "strict")
                match_level = CommonAntigensSera::match_level_t::strict;
            else if (match == "relaxed")
                match_level = CommonAntigensSera::match_level_t::relaxed;
            else if (match == "ignored")
                match_level = CommonAntigensSera::match_level_t::ignored;
            else
                throw std::invalid_argument{fmt::format("Unrecognized \"match\": \"{}\"", match)};

            projection_merge_t merge_typ{projection_merge_t::type1};
            if (merge_type == "type1" || merge_type == "tables-only")
                merge_typ = projection_merge_t::type1;
            else if (merge_type == "type2" || merge_type == "incremental")
                merge_typ = projection_merge_t::type2;
            else if (merge_type == "type3")
                merge_typ = projection_merge_t::type3;
            else if (merge_type == "type4")
                merge_typ = projection_merge_t::type4;
            else if (merge_type == "type5")
                merge_typ = projection_merge_t::type5;
            else
                throw std::invalid_argument{fmt::format("Unrecognized \"merge_type\": \"{}\"", merge_type)};

            return merge(*chart1, *chart2, MergeSettings{match_level, merge_typ, remove_distinct});
        },                                                                                //
        "chart1"_a, "chart2"_a, "type"_a, "match"_a = "auto", "remove_distinct"_a = false, //
        py::doc(R"(merges two charts
type: "type1" ("tables-only"), "type2" ("incremental"), "type3", "type4", "type5"
      see https://github.com/acorg/acmacs-chart-2/blob/master/doc/merge-types.org
match: "strict", "relaxed", "ignored", "automatic" ("auto")
)"));

    py::class_<MergeReport>(mdl, "MergeReport")
        ;

} // py_merge

// ----------------------------------------------------------------------

// https://pybind11.readthedocs.io/en/latest/faq.html#how-can-i-reduce-the-build-time

PYBIND11_MODULE(acmacs, mdl)
{
    mdl.doc() = "Acmacs backend";
    py_chart(mdl);
    py_merge(mdl);
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>py: chart.remove_antigens_sera<commit_after>#include "acmacs-base/pybind11.hh"

// chart
#include "acmacs-chart-2/factory-import.hh"
#include "acmacs-chart-2/factory-export.hh"
#include "acmacs-chart-2/chart-modify.hh"

// merge
#include "acmacs-chart-2/merge.hh"

// ======================================================================

inline unsigned make_info_data(bool column_bases, bool tables, bool tables_for_sera, bool antigen_dates)
{
    using namespace acmacs::chart;
    return (column_bases ? info_data::column_bases : 0)         //
           | (tables ? info_data::tables : 0)                   //
           | (tables_for_sera ? info_data::tables_for_sera : 0) //
           | (antigen_dates ? info_data::dates : 0);
}

// ----------------------------------------------------------------------

inline acmacs::chart::ChartClone::clone_data clone_type(const std::string& type)
{
    using namespace acmacs::chart;
    if (type == "titers")
        return ChartClone::clone_data::titers;
    else if (type == "projections")
        return ChartClone::clone_data::projections;
    else if (type == "plot_spec")
        return ChartClone::clone_data::plot_spec;
    else if (type == "projections_plot_spec")
        return ChartClone::clone_data::projections_plot_spec;
    else
        throw std::invalid_argument{fmt::format("Unrecognized clone \"type\": \"{}\"", type)};
}

// ----------------------------------------------------------------------

template <typename AgSr> struct AgSrIndexes
{
    AgSrIndexes() = default;
    AgSrIndexes(std::shared_ptr<AgSr> a_ag_sr) : ag_sr{a_ag_sr}, indexes{a_ag_sr->all_indexes()} {}
    bool empty() const { return indexes.empty(); }

    std::shared_ptr<AgSr> ag_sr;
    acmacs::chart::Indexes indexes;
};

struct AntigenIndexes : public AgSrIndexes<acmacs::chart::Antigens> { using AgSrIndexes<acmacs::chart::Antigens>::AgSrIndexes; };
struct SerumIndexes : public AgSrIndexes<acmacs::chart::Sera> { using AgSrIndexes<acmacs::chart::Sera>::AgSrIndexes; };

// ----------------------------------------------------------------------

inline void py_chart(py::module_& mdl)
{
    using namespace pybind11::literals;
    using namespace acmacs::chart;

    py::class_<ChartModify, std::shared_ptr<ChartModify>>(mdl, "Chart") //
        .def(py::init([](const std::string& filename) { return std::make_shared<ChartModify>(import_from_file(filename)); }), py::doc("imports chart from a file"))

        .def(
            "clone",                                                                                //
            [](ChartModify& chart, const std::string& type) -> std::shared_ptr<ChartModify> { return std::make_shared<ChartClone>(chart, clone_type(type)); }, //
            "type"_a = "titers",                                                                                //
            py::doc(R"(type: "titers", "projections", "plot_spec", "projections_plot_spec")"))                                                                 //

        .def(
            "make_name",                                                            //
            [](const ChartModify& chart) { return chart.make_name(std::nullopt); }, //
            py::doc("returns name of the chart"))                                   //

        .def(
            "make_name",                                                                                //
            [](const ChartModify& chart, size_t projection_no) { return chart.make_name(projection_no); }, //
            "projection_no"_a,                                                                             //
            py::doc("returns name of the chart with the stress of the passed projection"))                 //

        .def("subtype", [](const ChartModify& chart) { return *chart.info()->virus_type(); })                            //
        .def("subtype_short", [](const ChartModify& chart) { return std::string{chart.info()->virus_type().h_or_b()}; }) //
        .def("subset", [](const ChartModify& chart) { return chart.info()->subset(); })                                  //
        .def("assay", [](const ChartModify& chart) { return *chart.info()->assay(); })                                   //
        .def("assay_hi_or_neut", [](const ChartModify& chart) { return chart.info()->assay().hi_or_neut(); })            //
        .def("lab", [](const ChartModify& chart) { return *chart.info()->lab(); })                                       //
        .def("rbc", [](const ChartModify& chart) { return *chart.info()->rbc_species(); })                               //
        .def("date", [](const ChartModify& chart) { return *chart.info()->date(Info::Compute::Yes); })                   //
        .def(
            "lineage", [](const ChartModify& chart) { return *chart.lineage(); }, py::doc("returns chart lineage: VICTORIA, YAMAGATA")) //

        .def("description",                                 //
             &Chart::description,                           //
             py::doc("returns chart one line description")) //

        .def(
            "make_info", //
            [](const ChartModify& chart, size_t max_number_of_projections_to_show, bool column_bases, bool tables, bool tables_for_sera, bool antigen_dates) {
                return chart.make_info(max_number_of_projections_to_show, make_info_data(column_bases, tables, tables_for_sera, antigen_dates));
            },                                                                                //
            "max_number_of_projections_to_show"_a = 20, "column_bases"_a = true, "tables"_a = false, "tables_for_sera"_a = false, "antigen_dates"_a = false, //
            py::doc("returns detailed chart description"))                                                                                //

        .def("number_of_antigens", &Chart::number_of_antigens)
        .def("number_of_sera", &Chart::number_of_sera)
        .def("number_of_projections", &Chart::number_of_projections)

        .def(
            "relax", //
            [](ChartModify& chart, size_t number_of_dimensions, size_t number_of_optimizations, const std::string& minimum_column_basis, bool dimension_annealing, bool rough,
               size_t /*number_of_best_distinct_projections_to_keep*/) {
                if (number_of_optimizations == 0)
                    number_of_optimizations = 100;
                chart.relax(number_of_optimizations_t{number_of_optimizations}, MinimumColumnBasis{minimum_column_basis}, acmacs::number_of_dimensions_t{number_of_dimensions},
                            use_dimension_annealing_from_bool(dimension_annealing), optimization_options{optimization_precision{rough ? optimization_precision::rough : optimization_precision::fine}});
                chart.projections_modify().sort();
            }, //
            "number_of_dimensions"_a = 2, "number_of_optimizations"_a = 0, "minimum_column_basis"_a = "none", "dimension_annealing"_a = false, "rough"_a = false,
            "number_of_best_distinct_projections_to_keep"_a = 5,                                                                              //
            py::doc{"makes one or more antigenic maps from random starting layouts, adds new projections, projections are sorted by stress"}) //

        .def(
            "relax_incremental", //
            [](ChartModify& chart, size_t number_of_optimizations, bool rough, size_t number_of_best_distinct_projections_to_keep, bool remove_source_projection, bool unmovable_non_nan_points) {
                if (number_of_optimizations == 0)
                    number_of_optimizations = 100;
                chart.relax_incremental(0, number_of_optimizations_t{number_of_optimizations},
                                        optimization_options{optimization_precision{rough ? optimization_precision::rough : optimization_precision::fine}},
                                        acmacs::chart::remove_source_projection{remove_source_projection ? acmacs::chart::remove_source_projection::yes : acmacs::chart::remove_source_projection::no},
                                        acmacs::chart::unmovable_non_nan_points{unmovable_non_nan_points ? acmacs::chart::unmovable_non_nan_points::yes : acmacs::chart::unmovable_non_nan_points::no});
                chart.projections_modify().sort();
            },                                                                                //
            "number_of_optimizations"_a = 0, "rough"_a = false, "number_of_best_distinct_projections_to_keep"_a = 5, "remove_source_projection"_a = true, "unmovable_non_nan_points"_a = false) //

        .def(
            "projection",                                                                                //
            [](ChartModify& chart, size_t projection_no) { return chart.projection_modify(projection_no); }, //
            "projection_no"_a = 0)                                                                           //

        .def("remove_all_projections",                                                   //
             [](ChartModify& chart) { return chart.projections_modify().remove_all(); }) //

        .def(
            "keep_projections",                                                                               //
            [](ChartModify& chart, size_t to_keep) { return chart.projections_modify().keep_just(to_keep); }, //
            "keep"_a)                                                                                //

        .def(
            "export",                                                                                //
            [](ChartModify& chart, const std::string& filename, const std::string& program_name) { acmacs::chart::export_factory(chart, filename, program_name); }, //
            "filename"_a, "program_name"_a)                                                                                //

        .def("antigen_indexes",                                                                     //
             [](ChartModify& chart) { return std::make_shared<AntigenIndexes>(chart.antigens()); }) //
        .def("serum_indexes",                                                                       //
             [](ChartModify& chart) { return std::make_shared<SerumIndexes>(chart.sera()); })       //
        .def(
            "remove_antigens_sera",
            [](ChartModify& chart, std::shared_ptr<AntigenIndexes> antigens, std::shared_ptr<SerumIndexes> sera, bool remove_projections) {
                if (remove_projections)
                    chart.projections_modify().remove_all();
                if (!antigens->empty())
                    chart.remove_antigens(acmacs::ReverseSortedIndexes{*antigens->indexes});
                if (!sera->empty())
                    chart.remove_sera(acmacs::ReverseSortedIndexes{*sera->indexes});
            },                                                                          //
            "antigens"_a = nullptr, "sera"_a = nullptr, "remove_projections"_a = false) //
        ;

    // ----------------------------------------------------------------------

    py::class_<ProjectionModify, std::shared_ptr<ProjectionModify>>(mdl, "Projection") //
        .def(
            "stress",                                                                                //
            [](const ProjectionModify& projection, bool recalculate) { return projection.stress(recalculate ? RecalculateStress::if_necessary : RecalculateStress::no); }, //
            "recalculate"_a = false)                                                                                //
        ;

    py::class_<AntigenIndexes, std::shared_ptr<AntigenIndexes>>(mdl, "AntigenIndexes") //
        .def("__str__", [](const AntigenIndexes& indexes) { return fmt::format("AntigenIndexes({}){}", indexes.indexes.size(), indexes.indexes); })
        .def("empty", &AntigenIndexes::empty)

        .def(
            "filter_lineage",
            [](AntigenIndexes& indexes, const std::string& lineage) {
                indexes.ag_sr->filter_lineage(indexes.indexes, acmacs::chart::BLineage{lineage});
                return indexes;
            },           //
            "lineage"_a) //
        ;

    py::class_<SerumIndexes, std::shared_ptr<SerumIndexes>>(mdl, "SerumIndexes") //
        .def("__str__", [](const SerumIndexes& indexes) { return fmt::format("SerumIndexes({}){}", indexes.indexes.size(), indexes.indexes); })
        .def("empty", &SerumIndexes::empty)

        .def(
            "filter_lineage",
            [](SerumIndexes& indexes, const std::string& lineage) {
                indexes.ag_sr->filter_lineage(indexes.indexes, acmacs::chart::BLineage{lineage});
                return indexes;
            },           //
            "lineage"_a) //
        ;
}

// ======================================================================

inline void py_merge(py::module_& mdl)
{
    using namespace pybind11::literals;
    using namespace acmacs::chart;

    mdl.def(
        "merge",
        [](std::shared_ptr<ChartModify> chart1, std::shared_ptr<ChartModify> chart2, const std::string& merge_type, const std::string& match, bool remove_distinct) {
            CommonAntigensSera::match_level_t match_level{CommonAntigensSera::match_level_t::automatic};
            if (match == "auto" || match == "automatic")
                match_level = CommonAntigensSera::match_level_t::automatic;
            else if (match == "strict")
                match_level = CommonAntigensSera::match_level_t::strict;
            else if (match == "relaxed")
                match_level = CommonAntigensSera::match_level_t::relaxed;
            else if (match == "ignored")
                match_level = CommonAntigensSera::match_level_t::ignored;
            else
                throw std::invalid_argument{fmt::format("Unrecognized \"match\": \"{}\"", match)};

            projection_merge_t merge_typ{projection_merge_t::type1};
            if (merge_type == "type1" || merge_type == "tables-only")
                merge_typ = projection_merge_t::type1;
            else if (merge_type == "type2" || merge_type == "incremental")
                merge_typ = projection_merge_t::type2;
            else if (merge_type == "type3")
                merge_typ = projection_merge_t::type3;
            else if (merge_type == "type4")
                merge_typ = projection_merge_t::type4;
            else if (merge_type == "type5")
                merge_typ = projection_merge_t::type5;
            else
                throw std::invalid_argument{fmt::format("Unrecognized \"merge_type\": \"{}\"", merge_type)};

            return merge(*chart1, *chart2, MergeSettings{match_level, merge_typ, remove_distinct});
        },                                                                                //
        "chart1"_a, "chart2"_a, "type"_a, "match"_a = "auto", "remove_distinct"_a = false, //
        py::doc(R"(merges two charts
type: "type1" ("tables-only"), "type2" ("incremental"), "type3", "type4", "type5"
      see https://github.com/acorg/acmacs-chart-2/blob/master/doc/merge-types.org
match: "strict", "relaxed", "ignored", "automatic" ("auto")
)"));

    py::class_<MergeReport>(mdl, "MergeReport")
        ;

} // py_merge

// ----------------------------------------------------------------------

// https://pybind11.readthedocs.io/en/latest/faq.html#how-can-i-reduce-the-build-time

PYBIND11_MODULE(acmacs, mdl)
{
    mdl.doc() = "Acmacs backend";
    py_chart(mdl);
    py_merge(mdl);
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_CONSTANTS_HPP
#define LIBBITCOIN_CONSTANTS_HPP

#include <cstddef>
#include <cstdint>
#include <bitcoin/bitcoin/compat.hpp>
#include <bitcoin/bitcoin/define.hpp>
#include <bitcoin/bitcoin/math/hash_number.hpp>

namespace libbitcoin {

// Generic constants.

BC_CONSTEXPR int64_t min_int64 = MIN_INT64;
BC_CONSTEXPR int64_t max_int64 = MAX_INT64;
BC_CONSTEXPR int32_t min_int32 = MIN_INT32;
BC_CONSTEXPR int32_t max_int32 = MAX_INT32;
BC_CONSTEXPR uint64_t max_uint64 = MAX_UINT64;
BC_CONSTEXPR uint32_t max_uint32 = MAX_UINT32;
BC_CONSTEXPR uint16_t max_uint16 = MAX_UINT16;
BC_CONSTEXPR uint8_t max_uint8 = MAX_UINT8;
BC_CONSTEXPR uint8_t byte_bits = 8;

// Debian complains about missing UINTPTR_MAX definition for some weird reason.
#ifdef UINTPTR_MAX
    BC_CONSTEXPR uint64_t max_size_t = UINTPTR_MAX;
#else
    BC_CONSTEXPR uint64_t max_size_t = std::numeric_limits<size_t>::max();
#endif

// Bitcoin constants.

BC_CONSTEXPR uint32_t reward_interval = 210000;
BC_CONSTEXPR uint32_t protocol_version = 60000;
BC_CONSTEXPR uint32_t coinbase_maturity = 100;
BC_CONSTEXPR uint32_t initial_block_reward = 50;
BC_CONSTEXPR uint32_t max_work_bits = 0x1d00ffff;
BC_CONSTEXPR uint32_t max_input_sequence = max_uint32;

// Deprecated (use more descriptive).
BC_CONSTEXPR uint32_t max_bits = max_work_bits;
BC_CONSTEXPR uint32_t max_sequence = max_input_sequence;
BC_CONSTEXPR uint32_t block_reward = initial_block_reward;

// Threshold for nLockTime: below this value it is interpreted as block number,
// otherwise as UNIX timestamp. [Tue Nov 5 00:53:20 1985 UTC]
BC_CONSTEXPR uint32_t locktime_threshold = 500000000;

BC_CONSTFUNC uint64_t max_money_recursive(uint64_t current)
{
    return (current > 0) ? current + max_money_recursive(current >> 1) : 0;
}

BC_CONSTFUNC uint64_t coin_price(uint64_t value=1)
{
    return value * 100000000;
}

BC_CONSTFUNC uint64_t max_money()
{
    return reward_interval *
        max_money_recursive(coin_price(initial_block_reward));
}

#ifdef ENABLE_TESTNET
    // Block 514 is the first block after [Feb 15 2014].
    // Testnet started bip16 before mainnet.
    BC_CONSTEXPR uint32_t bip16_switchover_timestamp = 1333238400;
    BC_CONSTEXPR uint32_t bip16_switchover_height = 514;
    BC_CONSTEXPR uint16_t protocol_port = 18333;
#else
    // [April 1 2012]
    BC_CONSTEXPR uint32_t bip16_switchover_timestamp = 1333238400;
    BC_CONSTEXPR uint32_t bip16_switchover_height = 173805;
    BC_CONSTEXPR uint16_t protocol_port = 8333;
#endif

// Constants, sort of.
BC_API hash_number max_target();
BC_API uint32_t magic_value();

} // namespace libbitcoin

#endif
<commit_msg>Add network version constant.<commit_after>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_CONSTANTS_HPP
#define LIBBITCOIN_CONSTANTS_HPP

#include <cstddef>
#include <cstdint>
#include <bitcoin/bitcoin/compat.hpp>
#include <bitcoin/bitcoin/define.hpp>
#include <bitcoin/bitcoin/math/hash_number.hpp>

namespace libbitcoin {

// Generic constants.

BC_CONSTEXPR int64_t min_int64 = MIN_INT64;
BC_CONSTEXPR int64_t max_int64 = MAX_INT64;
BC_CONSTEXPR int32_t min_int32 = MIN_INT32;
BC_CONSTEXPR int32_t max_int32 = MAX_INT32;
BC_CONSTEXPR uint64_t max_uint64 = MAX_UINT64;
BC_CONSTEXPR uint32_t max_uint32 = MAX_UINT32;
BC_CONSTEXPR uint16_t max_uint16 = MAX_UINT16;
BC_CONSTEXPR uint8_t max_uint8 = MAX_UINT8;
BC_CONSTEXPR uint8_t byte_bits = 8;

// Debian complains about missing UINTPTR_MAX definition for some weird reason.
#ifdef UINTPTR_MAX
    BC_CONSTEXPR uint64_t max_size_t = UINTPTR_MAX;
#else
    BC_CONSTEXPR uint64_t max_size_t = std::numeric_limits<size_t>::max();
#endif

// Network protocol

// 70001 for version.relay, we do not yet fully support this level.
BC_CONSTEXPR uint32_t protocol_version = 70001;

//TODO:  We haven't yet established a minimum required peer version.
BC_CONSTEXPR uint32_t peer_minimum_version = 0;

// Consensus constants.
BC_CONSTEXPR uint32_t reward_interval = 210000;
BC_CONSTEXPR uint32_t coinbase_maturity = 100;
BC_CONSTEXPR uint32_t initial_block_reward = 50;
BC_CONSTEXPR uint32_t max_work_bits = 0x1d00ffff;
BC_CONSTEXPR uint32_t max_input_sequence = max_uint32;

// Deprecated (use more descriptive).
BC_CONSTEXPR uint32_t max_bits = max_work_bits;
BC_CONSTEXPR uint32_t max_sequence = max_input_sequence;
BC_CONSTEXPR uint32_t block_reward = initial_block_reward;

// Threshold for nLockTime: below this value it is interpreted as block number,
// otherwise as UNIX timestamp. [Tue Nov 5 00:53:20 1985 UTC]
BC_CONSTEXPR uint32_t locktime_threshold = 500000000;

BC_CONSTFUNC uint64_t max_money_recursive(uint64_t current)
{
    return (current > 0) ? current + max_money_recursive(current >> 1) : 0;
}

BC_CONSTFUNC uint64_t coin_price(uint64_t value=1)
{
    return value * 100000000;
}

BC_CONSTFUNC uint64_t max_money()
{
    return reward_interval *
        max_money_recursive(coin_price(initial_block_reward));
}

#ifdef ENABLE_TESTNET
    // Block 514 is the first block after [Feb 15 2014].
    // Testnet started bip16 before mainnet.
    BC_CONSTEXPR uint32_t bip16_switchover_timestamp = 1333238400;
    BC_CONSTEXPR uint32_t bip16_switchover_height = 514;
    BC_CONSTEXPR uint16_t protocol_port = 18333;
#else
    // [April 1 2012]
    BC_CONSTEXPR uint32_t bip16_switchover_timestamp = 1333238400;
    BC_CONSTEXPR uint32_t bip16_switchover_height = 173805;
    BC_CONSTEXPR uint16_t protocol_port = 8333;
#endif

// Constants, sort of.
BC_API hash_number max_target();
BC_API uint32_t magic_value();

} // namespace libbitcoin

#endif
<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_SELECTIONLISTENER_HPP
#define GCN_SELECTIONLISTENER_HPP

#include <string>

#include "guichan/actionevent.hpp"
#include "guichan/platform.hpp"

namespace gcn
{
    /**
     * Listener of value change events from Widgets. To be able to
     * listen for value changes you must make a class which inherits
     * from this class and implements the valueChanged function.
     *
     * @see ListBox::addSelectionListener
     * @author Olof Naessn
     * @since 0.8.0
     */
    class GCN_CORE_DECLSPEC SelectionListener
    {
    public:

        /**
         * Destructor.
         */
        virtual ~SelectionListener() { }

        /**
         * Called when a value has been changed in a Widget. It is used
         * to be able to recieve a notification that a value has been changed.
         *
         * @param event the event of the value change.
         * @since 0.8.0
         */
        virtual void valueChanged(const Event& event) = 0;

    };
}

#endif // end GCN_SELECTIONLISTENER_HPP
<commit_msg>Has been changed to utilise the SelectionEvent class.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_SELECTIONLISTENER_HPP
#define GCN_SELECTIONLISTENER_HPP

#include <string>

#include "guichan/selectionevent.hpp"
#include "guichan/platform.hpp"

namespace gcn
{
    /**
     * Listener of value change events from Widgets. To be able to
     * listen for value changes you must make a class which inherits
     * from this class and implements the valueChanged function.
     *
     * @see ListBox::addSelectionListener
     * @author Olof Naessn
     * @since 0.8.0
     */
    class GCN_CORE_DECLSPEC SelectionListener
    {
    public:

        /**
         * Destructor.
         */
        virtual ~SelectionListener() { }

        /**
         * Called when a value has been changed in a Widget. It is used
         * to be able to recieve a notification that a value has been changed.
         *
         * @param event the event of the value change.
         * @since 0.8.0
         */
        virtual void valueChanged(const SelectionEvent& event) = 0;

    };
}

#endif // end GCN_SELECTIONLISTENER_HPP
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifdef TORRENT_DISK_STATS
#include <fstream>
#endif

#include "libtorrent/storage.hpp"
#include <boost/thread/thread.hpp>
#include <boost/function.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/pool/pool.hpp>
#include <boost/noncopyable.hpp>
#include "libtorrent/config.hpp"

namespace libtorrent
{

	struct disk_io_job
	{
		disk_io_job()
			: action(read)
			, buffer(0)
			, buffer_size(0)
			, piece(0)
			, offset(0)
			, priority(0)
		{}

		enum action_t
		{
			read
			, write
			, hash
			, move_storage
			, release_files
			, delete_files
		};

		action_t action;

		char* buffer;
		size_type buffer_size;
		boost::intrusive_ptr<piece_manager> storage;
		// arguments used for read and write
		int piece, offset;
		// used for move_storage. On errors, this is set
		// to the error message
		std::string str;

		// priority decides whether or not this
		// job will skip entries in the queue or
		// not. It always skips in front of entries
		// with lower priority
		int priority;

		// this is called when operation completes
		boost::function<void(int, disk_io_job const&)> callback;
	};

	// this is a singleton consisting of the thread and a queue
	// of disk io jobs
	struct disk_io_thread : boost::noncopyable
	{
		disk_io_thread(int block_size = 16 * 1024);
		~disk_io_thread();

#ifdef TORRENT_STATS
		int disk_allocations() const
		{ return m_allocations; }
#endif

		// aborts read operations
		void stop(boost::intrusive_ptr<piece_manager> s);
		void add_job(disk_io_job const& j
			, boost::function<void(int, disk_io_job const&)> const& f
			= boost::function<void(int, disk_io_job const&)>());

#ifndef NDEBUG
		disk_io_job find_job(boost::intrusive_ptr<piece_manager> s
			, int action, int piece) const;
#endif
		// keep track of the number of bytes in the job queue
		// at any given time. i.e. the sum of all buffer_size.
		// this is used to slow down the download global download
		// speed when the queue buffer size is too big.
		size_type queue_buffer_size() const
		{ return m_queue_buffer_size; }

		void operator()();

		char* allocate_buffer();
		void free_buffer(char* buf);

	private:

		typedef boost::recursive_mutex mutex_t;
		mutable mutex_t m_mutex;
		boost::condition m_signal;
		bool m_abort;
		std::deque<disk_io_job> m_jobs;
		size_type m_queue_buffer_size;

		// memory pool for read and write operations
		boost::pool<> m_pool;

#ifndef NDEBUG
		int m_block_size;
		disk_io_job m_current;
#endif

#ifdef TORRENT_DISK_STATS
		std::ofstream m_log;
#endif
#ifdef TORRENT_STATS
		int m_allocations;
#endif

		// thread for performing blocking disk io operations
		boost::thread m_disk_io_thread;
	};

}

<commit_msg>added missing include guard to disk_io_thread.hpp<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_DISK_IO_THREAD
#define TORRENT_DISK_IO_THREAD

#ifdef TORRENT_DISK_STATS
#include <fstream>
#endif

#include "libtorrent/storage.hpp"
#include <boost/thread/thread.hpp>
#include <boost/function.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/pool/pool.hpp>
#include <boost/noncopyable.hpp>
#include "libtorrent/config.hpp"

namespace libtorrent
{

	struct disk_io_job
	{
		disk_io_job()
			: action(read)
			, buffer(0)
			, buffer_size(0)
			, piece(0)
			, offset(0)
			, priority(0)
		{}

		enum action_t
		{
			read
			, write
			, hash
			, move_storage
			, release_files
			, delete_files
		};

		action_t action;

		char* buffer;
		size_type buffer_size;
		boost::intrusive_ptr<piece_manager> storage;
		// arguments used for read and write
		int piece, offset;
		// used for move_storage. On errors, this is set
		// to the error message
		std::string str;

		// priority decides whether or not this
		// job will skip entries in the queue or
		// not. It always skips in front of entries
		// with lower priority
		int priority;

		// this is called when operation completes
		boost::function<void(int, disk_io_job const&)> callback;
	};

	// this is a singleton consisting of the thread and a queue
	// of disk io jobs
	struct disk_io_thread : boost::noncopyable
	{
		disk_io_thread(int block_size = 16 * 1024);
		~disk_io_thread();

#ifdef TORRENT_STATS
		int disk_allocations() const
		{ return m_allocations; }
#endif

		// aborts read operations
		void stop(boost::intrusive_ptr<piece_manager> s);
		void add_job(disk_io_job const& j
			, boost::function<void(int, disk_io_job const&)> const& f
			= boost::function<void(int, disk_io_job const&)>());

#ifndef NDEBUG
		disk_io_job find_job(boost::intrusive_ptr<piece_manager> s
			, int action, int piece) const;
#endif
		// keep track of the number of bytes in the job queue
		// at any given time. i.e. the sum of all buffer_size.
		// this is used to slow down the download global download
		// speed when the queue buffer size is too big.
		size_type queue_buffer_size() const
		{ return m_queue_buffer_size; }

		void operator()();

		char* allocate_buffer();
		void free_buffer(char* buf);

	private:

		typedef boost::recursive_mutex mutex_t;
		mutable mutex_t m_mutex;
		boost::condition m_signal;
		bool m_abort;
		std::deque<disk_io_job> m_jobs;
		size_type m_queue_buffer_size;

		// memory pool for read and write operations
		boost::pool<> m_pool;

#ifndef NDEBUG
		int m_block_size;
		disk_io_job m_current;
#endif

#ifdef TORRENT_DISK_STATS
		std::ofstream m_log;
#endif
#ifdef TORRENT_STATS
		int m_allocations;
#endif

		// thread for performing blocking disk io operations
		boost::thread m_disk_io_thread;
	};

}

#endif

<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2016 ScyllaDB
 */

#pragma once

#include <seastar/core/future.hh>
#include <seastar/core/chunked_fifo.hh>
#include <stdexcept>
#include <exception>
#include <memory>
#include <seastar/core/timer.hh>
#include <seastar/core/lowres_clock.hh>
#include <seastar/core/timed_out_error.hh>

namespace seastar {

template<typename T>
struct dummy_expiry {
    void operator()(T&) noexcept {};
};

template<typename... T>
struct promise_expiry {
    void operator()(promise<T...>& pr) noexcept {
        pr.set_exception(std::make_exception_ptr(timed_out_error()));
    };
};

/// Container for elements with support for expiration of entries.
///
/// OnExpiry is a functor which will be called with a reference to T right before it expires.
/// T is removed and destroyed from the container immediately after OnExpiry returns.
/// OnExpiry callback must not modify the container, it can only modify its argument.
///
/// The container can only be moved before any elements are pushed.
///
template <typename T, typename OnExpiry = dummy_expiry<T>, typename Clock = lowres_clock>
class expiring_fifo {
public:
    using clock = Clock;
    using time_point = typename Clock::time_point;
private:
    struct entry {
        std::optional<T> payload; // disengaged means that it's expired
        timer<Clock> tr;
        entry(T&& payload_) : payload(std::move(payload_)) {}
        entry(const T& payload_) : payload(payload_) {}
        entry(T payload_, expiring_fifo& ef, time_point timeout)
                : payload(std::move(payload_))
                , tr([this, &ef] {
                    ef._on_expiry(*payload);
                    payload = std::nullopt;
                    --ef._size;
                    ef.drop_expired_front();
                })
        {
            tr.arm(timeout);
        }
        entry(entry&& x) = delete;
        entry(const entry& x) = delete;
    };

    // If engaged, represents the first element.
    // This is to avoid large allocations done by chunked_fifo for single-element cases.
    // expiring_fifo is used to implement wait lists in synchronization primitives
    // and in some uses it's common to have at most one waiter.
    std::unique_ptr<entry> _front;

    // There is an invariant that the front element is never expired.
    chunked_fifo<entry> _list;
    OnExpiry _on_expiry;
    size_t _size = 0;

    // Ensures that front() is not expired by dropping expired elements from the front.
    void drop_expired_front() {
        while (!_list.empty() && !_list.front().payload) {
            _list.pop_front();
        }
        if (_front && !_front->payload) {
            _front.reset();
        }
    }
public:
    expiring_fifo() = default;
    expiring_fifo(OnExpiry on_expiry) : _on_expiry(std::move(on_expiry)) {}

    expiring_fifo(expiring_fifo&& o) noexcept
            : expiring_fifo() {
        // entry objects hold a reference to this so non-empty containers cannot be moved.
        assert(o._size == 0);
    }

    /// Checks if container contains any elements
    ///
    /// \note Inside OnExpiry callback, the expired element is still contained.
    ///
    /// \return true if and only if there are any elements contained.
    bool empty() const {
        return _size == 0;
    }

    /// Equivalent to !empty()
    explicit operator bool() const {
        return !empty();
    }

    /// Returns a reference to the element in the front.
    /// Valid only when !empty().
    T& front() {
        if (_front) {
            return *_front->payload;
        }
        return *_list.front().payload;
    }

    /// Returns a reference to the element in the front.
    /// Valid only when !empty().
    const T& front() const {
        if (_front) {
            return *_front->payload;
        }
        return *_list.front().payload;
    }

    /// Returns the number of elements contained.
    ///
    /// \note Expired elements are not contained. Expiring element is still contained when OnExpiry is called.
    size_t size() const {
        return _size;
    }

    /// Reserves storage in the container for at least 'size' elements.
    /// Note that expired elements may also take space when they are not in the front of the queue.
    ///
    /// Doesn't give any guarantees about exception safety of subsequent push_back().
    void reserve(size_t size) {
        return _list.reserve(size);
    }

    /// Adds element to the back of the queue.
    /// The element will never expire.
    void push_back(const T& payload) {
        if (_size == 0) {
            _front = std::make_unique<entry>(payload);
        } else {
            _list.emplace_back(payload);
        }
        ++_size;
    }

    /// Adds element to the back of the queue.
    /// The element will never expire.
    void push_back(T&& payload) {
        if (_size == 0) {
            _front = std::make_unique<entry>(std::move(payload));
        } else {
            _list.emplace_back(std::move(payload));
        }
        ++_size;
    }

    /// Adds element to the back of the queue.
    /// The element will expire when timeout is reached, unless it is time_point::max(), in which
    /// case it never expires.
    void push_back(T&& payload, time_point timeout) {
        if (timeout == time_point::max()) {
            push_back(std::move(payload));
            return;
        }
        if (_size == 0) {
            _front = std::make_unique<entry>(std::move(payload), *this, timeout);
        } else {
            _list.emplace_back(std::move(payload), *this, timeout);
        }
        ++_size;
    }

    /// Removes the element at the front.
    /// Can be called only if !empty().
    void pop_front() {
        if (_front) {
            _front.reset();
        } else {
            _list.pop_front();
        }
        --_size;
        drop_expired_front();
    }
};

}
<commit_msg>allow move assign empty expiring_fifo<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2016 ScyllaDB
 */

#pragma once

#include <seastar/core/future.hh>
#include <seastar/core/chunked_fifo.hh>
#include <stdexcept>
#include <exception>
#include <memory>
#include <seastar/core/timer.hh>
#include <seastar/core/lowres_clock.hh>
#include <seastar/core/timed_out_error.hh>

namespace seastar {

template<typename T>
struct dummy_expiry {
    void operator()(T&) noexcept {};
};

template<typename... T>
struct promise_expiry {
    void operator()(promise<T...>& pr) noexcept {
        pr.set_exception(std::make_exception_ptr(timed_out_error()));
    };
};

/// Container for elements with support for expiration of entries.
///
/// OnExpiry is a functor which will be called with a reference to T right before it expires.
/// T is removed and destroyed from the container immediately after OnExpiry returns.
/// OnExpiry callback must not modify the container, it can only modify its argument.
///
/// The container can only be moved before any elements are pushed.
///
template <typename T, typename OnExpiry = dummy_expiry<T>, typename Clock = lowres_clock>
class expiring_fifo {
public:
    using clock = Clock;
    using time_point = typename Clock::time_point;
private:
    struct entry {
        std::optional<T> payload; // disengaged means that it's expired
        timer<Clock> tr;
        entry(T&& payload_) : payload(std::move(payload_)) {}
        entry(const T& payload_) : payload(payload_) {}
        entry(T payload_, expiring_fifo& ef, time_point timeout)
                : payload(std::move(payload_))
                , tr([this, &ef] {
                    ef._on_expiry(*payload);
                    payload = std::nullopt;
                    --ef._size;
                    ef.drop_expired_front();
                })
        {
            tr.arm(timeout);
        }
        entry(entry&& x) = delete;
        entry(const entry& x) = delete;
    };

    // If engaged, represents the first element.
    // This is to avoid large allocations done by chunked_fifo for single-element cases.
    // expiring_fifo is used to implement wait lists in synchronization primitives
    // and in some uses it's common to have at most one waiter.
    std::unique_ptr<entry> _front;

    // There is an invariant that the front element is never expired.
    chunked_fifo<entry> _list;
    OnExpiry _on_expiry;
    size_t _size = 0;

    // Ensures that front() is not expired by dropping expired elements from the front.
    void drop_expired_front() {
        while (!_list.empty() && !_list.front().payload) {
            _list.pop_front();
        }
        if (_front && !_front->payload) {
            _front.reset();
        }
    }
public:
    expiring_fifo() = default;
    expiring_fifo(OnExpiry on_expiry) : _on_expiry(std::move(on_expiry)) {}

    expiring_fifo(expiring_fifo&& o) noexcept
            : expiring_fifo(std::move(o._on_expiry)) {
        // entry objects hold a reference to this so non-empty containers cannot be moved.
        assert(o._size == 0);
    }

    expiring_fifo& operator=(expiring_fifo&& o) noexcept {
        if (this != &o) {
            this->~expiring_fifo();
            new (this) expiring_fifo(std::move(o));
        }
        return *this;
    }

    /// Checks if container contains any elements
    ///
    /// \note Inside OnExpiry callback, the expired element is still contained.
    ///
    /// \return true if and only if there are any elements contained.
    bool empty() const {
        return _size == 0;
    }

    /// Equivalent to !empty()
    explicit operator bool() const {
        return !empty();
    }

    /// Returns a reference to the element in the front.
    /// Valid only when !empty().
    T& front() {
        if (_front) {
            return *_front->payload;
        }
        return *_list.front().payload;
    }

    /// Returns a reference to the element in the front.
    /// Valid only when !empty().
    const T& front() const {
        if (_front) {
            return *_front->payload;
        }
        return *_list.front().payload;
    }

    /// Returns the number of elements contained.
    ///
    /// \note Expired elements are not contained. Expiring element is still contained when OnExpiry is called.
    size_t size() const {
        return _size;
    }

    /// Reserves storage in the container for at least 'size' elements.
    /// Note that expired elements may also take space when they are not in the front of the queue.
    ///
    /// Doesn't give any guarantees about exception safety of subsequent push_back().
    void reserve(size_t size) {
        return _list.reserve(size);
    }

    /// Adds element to the back of the queue.
    /// The element will never expire.
    void push_back(const T& payload) {
        if (_size == 0) {
            _front = std::make_unique<entry>(payload);
        } else {
            _list.emplace_back(payload);
        }
        ++_size;
    }

    /// Adds element to the back of the queue.
    /// The element will never expire.
    void push_back(T&& payload) {
        if (_size == 0) {
            _front = std::make_unique<entry>(std::move(payload));
        } else {
            _list.emplace_back(std::move(payload));
        }
        ++_size;
    }

    /// Adds element to the back of the queue.
    /// The element will expire when timeout is reached, unless it is time_point::max(), in which
    /// case it never expires.
    void push_back(T&& payload, time_point timeout) {
        if (timeout == time_point::max()) {
            push_back(std::move(payload));
            return;
        }
        if (_size == 0) {
            _front = std::make_unique<entry>(std::move(payload), *this, timeout);
        } else {
            _list.emplace_back(std::move(payload), *this, timeout);
        }
        ++_size;
    }

    /// Removes the element at the front.
    /// Can be called only if !empty().
    void pop_front() {
        if (_front) {
            _front.reset();
        } else {
            _list.pop_front();
        }
        --_size;
        drop_expired_front();
    }
};

}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file data.hpp
 * \brief Contains basic data manipulation functions.
 */

#ifndef CPP_UTILS_DATA_HPP
#define CPP_UTILS_DATA_HPP

#include <numeric>  //for std::accumulate
#include <cmath>    //for std::sqrt

#include "assert.hpp"

/*!
 * \namespace cpp
 * \brief cpp_utils main namespace
 */
namespace cpp {

/*!
 * \brief Compute the mean of values of the given range
 * \param first Start of the range
 * \param last End of the range
 * \return the mean of the values of the given range
 */
template<typename Iterator>
double mean(Iterator first, Iterator last){
    return std::accumulate(first, last, 0.0) / std::distance(first, last);
}

/*!
 * \brief Compute the mean of values in the given container.
 * \param container The container to compute the mean from.
 * \return the mean of the values in the given container.
 */
template<typename Container>
double mean(const Container& container){
    return mean(std::begin(container), std::end(container));
}

/*!
 * \brief Compute the variance of values of the given range
 * \param first Start of the range
 * \param last End of the range
 * \param mean The mean of the range
 * \return the variance of the values of the given range
 */
template<typename Iterator>
double variance(Iterator first, Iterator last, double mean){
    double var = 0.0;
    for(auto it = first; it != last; ++it){
        var += (*it - mean) * (*it - mean);
    }
    return var / std::distance(first, last);
}

/*!
 * \brief Compute the variance of values in the given container.
 * \param container The container to compute the mean from.
 * \param mean The mean of the range
 * \return the variance of the values in the given container.
 */
template<typename Container>
double variance(const Container& container, double mean){
    return variance(std::begin(container), std::end(container), mean);
}

/*!
 * \brief Compute the deviation of values of the given range
 * \param first Start of the range
 * \param last End of the range
 * \param mean The mean of the range
 * \return the standard deviation of the values of the given range
 */
template<typename Iterator>
double stddev(Iterator first, Iterator last, double mean){
    return std::sqrt(variance(first, last, mean));
}

/*!
 * \brief Compute the standard deviation of values in the given container.
 * \param container The container to compute the mean from.
 * \param mean The mean of the range
 * \return the standard deviation of the values in the given container.
 */
template<typename Container>
double stddev(const Container& container, double mean){
    return std::sqrt(variance(std::begin(container), std::end(container), mean));
}

/*!
 * \brief Normalize all the values of the container
 * \param container The container to normalize
 *
 * The values are normalized so the range has zero-mean and unit-variance.
 */
template<typename Container>
void normalize(Container& container){
    //normalize to zero-mean
    auto m = mean(container);
    for(auto& v : container){
        v -= m;
    }

    //normalize to unit variance
    auto s = variance(container, 0.0);

    if(s != 0.0){
        for(auto& v : container){
            v /= s;
        }
    }
}

/*!
 * \brief Normalize each value contained in the given range.
 * \param first Start of the range
 * \param last End of the range
 *
 * The values are normalized so the range has zero-mean and unit-variance.
 */
template<typename Iterator>
void normalize_each(Iterator first, Iterator last){
    for(; first != last; ++first){
        normalize(*first);
    }
}

/*!
 * \brief Normalize each value contained in the given range.
 * \param container The container holding the ranges to normalize.
 *
 * The values are normalized so the range has zero-mean and unit-variance.
 */
template<typename Container>
void normalize_each(Container& values){
    normalize_each(std::begin(values), std::end(values));
}

} //end of the cpp namespace

#endif //CPP_UTILS_ALGORITHM_HPP
<commit_msg>Revert "Improve data normalization"<commit_after>//=======================================================================
// Copyright (c) 2013-2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file data.hpp
 * \brief Contains basic data manipulation functions.
 */

#ifndef CPP_UTILS_DATA_HPP
#define CPP_UTILS_DATA_HPP

#include <numeric>  //for std::accumulate
#include <cmath>    //for std::sqrt

#include "assert.hpp"

/*!
 * \namespace cpp
 * \brief cpp_utils main namespace
 */
namespace cpp {

/*!
 * \brief Compute the mean of values of the given range
 * \param first Start of the range
 * \param last End of the range
 * \return the mean of the values of the given range
 */
template<typename Iterator>
double mean(Iterator first, Iterator last){
    return std::accumulate(first, last, 0.0) / std::distance(first, last);
}

/*!
 * \brief Compute the mean of values in the given container.
 * \param container The container to compute the mean from.
 * \return the mean of the values in the given container.
 */
template<typename Container>
double mean(const Container& container){
    return mean(std::begin(container), std::end(container));
}

/*!
 * \brief Compute the standard deviation of values of the given range
 * \param first Start of the range
 * \param last End of the range
 * \param mean The mean of the range
 * \return the standard deviation of the values of the given range
 */
template<typename Iterator>
double stddev(Iterator first, Iterator last, double mean){
    double std = 0.0;
    for(auto it = first; it != last; ++it){
        std += (*it - mean) * (*it - mean);
    }
    return std::sqrt(std / std::distance(first, last));
}

/*!
 * \brief Compute the standard deviation of values in the given container.
 * \param container The container to compute the mean from.
 * \param mean The mean of the range
 * \return the standard deviation of the values in the given container.
 */
template<typename Container>
double stddev(const Container& container, double mean){
    return stddev(std::begin(container), std::end(container), mean);
}

/*!
 * \brief Normalize all the values of the container
 * \param container The container to normalize
 *
 * The values are normalized so the range has zero-mean and unit-variance.
 */
template<typename Container>
void normalize(Container& container){
    //normalize to zero-mean
    auto m = mean(container);
    for(auto& v : container){
        v -= m;
    }

    //normalize to unit variance
    auto s = stddev(container, 0.0);

    if(s != 0.0){
        for(auto& v : container){
            v /= s;
        }
    }
}

/*!
 * \brief Normalize each value contained in the given range.
 * \param first Start of the range
 * \param last End of the range
 *
 * The values are normalized so the range has zero-mean and unit-variance.
 */
template<typename Iterator>
void normalize_each(Iterator first, Iterator last){
    for(; first != last; ++first){
        normalize(*first);
    }
}

/*!
 * \brief Normalize each value contained in the given range.
 * \param container The container holding the ranges to normalize.
 *
 * The values are normalized so the range has zero-mean and unit-variance.
 */
template<typename Container>
void normalize_each(Container& values){
    normalize_each(std::begin(values), std::end(values));
}

} //end of the cpp namespace

#endif //CPP_UTILS_ALGORITHM_HPP
<|endoftext|>


<commit_before>#include "InitScreen.hpp"

const std::string rd::InitScreen::SPLASH_PATH = "../images/800px-Devastation-thin.png";
const std::string rd::InitScreen::FONT_PATH = "../fonts/FreeMono.ttf";

rd::InitScreen::InitScreen()
{

}

bool rd::InitScreen::init()
{
    //-- Find the real path to the resources with ResourceFinder
    yarp::os::ResourceFinder rf;
    rf.setDefaultContext("robotDevastation");
    rf.setDefaultConfigFile("robotDevastation.ini");

    //-- Load splash screen resource
    image = IMG_Load(rf.findFileByName(SPLASH_PATH).c_str());
    if (image == NULL)
    {
        RD_ERROR("Unable to load splash screen (resource: %s)!\n SDL_image Error: %s\n", SPLASH_PATH.c_str(), IMG_GetError())
        return false;
    }

    //-- Load the font
    font = TTF_OpenFont(rf.findFileByName(FONT_PATH).c_str(), 28);
    if (font == NULL)
    {
        RD_ERROR("Unable to load font: %s %s \n", rf.findFileByName(FONT_PATH).c_str(), TTF_GetError());
        return false;
    }

    //-- Create text from font
    SDL_Color text_color = {0,255,0,0};
    text_surface = TTF_RenderText_Solid(font, "Press any key to start", text_color);

    screen = NULL;
    return true;
}

bool rd::InitScreen::cleanup()
{
    SDL_FreeSurface(screen);
    SDL_FreeSurface(image);
    SDL_FreeSurface(text_surface);
    SDL_DestroyWindow(window);
    screen = NULL;
    image = NULL;
    text_surface = NULL;
    window = NULL;
    return true;
}

bool rd::InitScreen::show()
{
    if (window == NULL)
    {
        //-- Init screen
        window = SDL_CreateWindow("Robot Devastation",
                                  SDL_WINDOWPOS_UNDEFINED,
                                  SDL_WINDOWPOS_UNDEFINED,
                                  image->w,
                                  image->h+text_surface->h,
                                  SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);  // 16, SDL_DOUBLEBUF
        if (!window)
        {
            RD_ERROR("Unable to set video mode: %s\n", SDL_GetError());
            return false;
        }

        //Get window surface
        screen = SDL_GetWindowSurface( window );
    }
    //-- Clear screen
    SDL_FillRect(screen, NULL, 0x000000);

    //-- Draw splash
    SDL_Rect splash_rect = {0,0, image->w, image->h};
    SDL_BlitSurface(image, NULL, screen, &splash_rect);

    //-- Draw text
    SDL_Rect text_rect = {(image->w-text_surface->w)/2,image->h, text_surface->w, text_surface->h};
    SDL_BlitSurface(text_surface, NULL, screen, &text_rect);

    SDL_UpdateWindowSurface(window); //Refresh the screen
    SDL_Delay(20); //Wait a bit :)

    return true;
}

rd::InitScreen::~InitScreen()
{
}
<commit_msg>extra checks on found resource<commit_after>#include "InitScreen.hpp"

const std::string rd::InitScreen::SPLASH_PATH = "../images/800px-Devastation-thin.png";
const std::string rd::InitScreen::FONT_PATH = "../fonts/FreeMono.ttf";

rd::InitScreen::InitScreen()
{

}

bool rd::InitScreen::init()
{
    //-- Find the real path to the resources with ResourceFinder
    yarp::os::ResourceFinder rf;
    rf.setDefaultContext("robotDevastation");
    rf.setDefaultConfigFile("robotDevastation.ini");

    //-- Load splash screen resource
    yarp::os::ConstString splashPath = rf.findFileByName(SPLASH_PATH);
    if (splashPath == "")
    {
        RD_ERROR("Unable to find splash screen (resource: %s)!\n", splashPath.c_str())
        return false;
    }
    image = IMG_Load(splashPath.c_str());
    if (image == NULL)
    {
        RD_ERROR("Unable to load splash screen (resource: %s)!\n SDL_image Error: %s\n", splashPath.c_str(), IMG_GetError())
        return false;
    }

    //-- Load the font
    font = TTF_OpenFont(rf.findFileByName(FONT_PATH).c_str(), 28);
    if (font == NULL)
    {
        RD_ERROR("Unable to load font: %s %s \n", rf.findFileByName(FONT_PATH).c_str(), TTF_GetError());
        return false;
    }

    //-- Create text from font
    SDL_Color text_color = {0,255,0,0};
    text_surface = TTF_RenderText_Solid(font, "Press any key to start", text_color);

    screen = NULL;
    return true;
}

bool rd::InitScreen::cleanup()
{
    SDL_FreeSurface(screen);
    SDL_FreeSurface(image);
    SDL_FreeSurface(text_surface);
    SDL_DestroyWindow(window);
    screen = NULL;
    image = NULL;
    text_surface = NULL;
    window = NULL;
    return true;
}

bool rd::InitScreen::show()
{
    if (window == NULL)
    {
        //-- Init screen
        window = SDL_CreateWindow("Robot Devastation",
                                  SDL_WINDOWPOS_UNDEFINED,
                                  SDL_WINDOWPOS_UNDEFINED,
                                  image->w,
                                  image->h+text_surface->h,
                                  SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);  // 16, SDL_DOUBLEBUF
        if (!window)
        {
            RD_ERROR("Unable to set video mode: %s\n", SDL_GetError());
            return false;
        }

        //Get window surface
        screen = SDL_GetWindowSurface( window );
    }
    //-- Clear screen
    SDL_FillRect(screen, NULL, 0x000000);

    //-- Draw splash
    SDL_Rect splash_rect = {0,0, image->w, image->h};
    SDL_BlitSurface(image, NULL, screen, &splash_rect);

    //-- Draw text
    SDL_Rect text_rect = {(image->w-text_surface->w)/2,image->h, text_surface->w, text_surface->h};
    SDL_BlitSurface(text_surface, NULL, screen, &text_rect);

    SDL_UpdateWindowSurface(window); //Refresh the screen
    SDL_Delay(20); //Wait a bit :)

    return true;
}

rd::InitScreen::~InitScreen()
{
}
<|endoftext|>


<commit_before>#include <hop_bits/optimisationAlgorithm/samplingBasedAlgorithm/gridSearch.hpp>

namespace hop {
  GridSearch::GridSearch(
      const std::shared_ptr<OptimisationProblem> optimisationProblem)
    : SamplingBasedAlgorithm(optimisationProblem),
      candidateObjectiveValue_(std::numeric_limits<double>::infinity()),
      candidateSoftConstraintValue_(std::numeric_limits<double>::infinity()) {

  }

  void GridSearch::optimiseImplementation() {
    numberOfSamples_ = arma::conv_to<arma::Col<arma::uword>>::from(arma::ceil(maximalNumberOfIterations_ * (optimisationProblem_->getUpperBounds() - optimisationProblem_->getLowerBounds()) / arma::sum(optimisationProblem_->getUpperBounds() - optimisationProblem_->getLowerBounds())));

    sampleParameters_.clear();
    for (std::size_t n = 0; n < optimisationProblem_->getNumberOfDimensions(); ++n) {
      sampleParameters_.push_back(arma::linspace(optimisationProblem_->getLowerBounds().at(n), optimisationProblem_->getUpperBounds().at(n), numberOfSamples_.at(n)));
    }

    bestSoftConstraintValue_ = std::numeric_limits<double>::infinity();
    bestObjectiveValue_ = std::numeric_limits<double>::infinity();

    sampleIndicies_ = arma::zeros<arma::Col<arma::uword>>(sampleParameters_.size());
    do {
      ++numberOfIterations_;

      for(std::size_t n = 0; n < sampleIndicies_.n_elem; ++n) {
        candidateParameter_.at(n) = sampleParameters_.at(n).at(sampleIndicies_.at(n));
      }

      ++sampleIndicies_.at(0);
      for(std::size_t n = 0; n < sampleIndicies_.n_elem - 1; ++n) {
        if(sampleIndicies_.at(n) >= numberOfSamples_.at(n)) {
           ++sampleIndicies_.at(n + 1);
        }
      }

      candidateParameter_ = candidateParameter_;
      candidateSoftConstraintValue_ = optimisationProblem_->getSoftConstraintsValue(candidateParameter_);
      candidateObjectiveValue_ = optimisationProblem_->getObjectiveValue(candidateParameter_);

      if(candidateSoftConstraintValue_ < bestSoftConstraintValue_ || candidateSoftConstraintValue_ == bestSoftConstraintValue_ && candidateObjectiveValue_ < bestObjectiveValue_) {
        bestParameter_ = candidateParameter_;
        bestSoftConstraintValue_ = candidateSoftConstraintValue_;
        bestObjectiveValue_ = candidateObjectiveValue_;
      }
    } while(!isFinished() && !isTerminated());
  }

  std::string GridSearch::to_string() const noexcept {
    return "GridSearch";
  }
}
<commit_msg>devel: Added sampling factor parameterisation<commit_after>#include <hop_bits/optimisationAlgorithm/samplingBasedAlgorithm/gridSearch.hpp>

#include <iostream>

namespace hop {
  GridSearch::GridSearch(
      const std::shared_ptr<OptimisationProblem> optimisationProblem)
    : SamplingBasedAlgorithm(optimisationProblem),
      candidateObjectiveValue_(std::numeric_limits<double>::infinity()),
      candidateSoftConstraintValue_(std::numeric_limits<double>::infinity()) {
    setSamplingFactors(arma::ones(optimisationProblem_->getNumberOfDimensions()) / static_cast<double>(optimisationProblem_->getNumberOfDimensions()));
}

  void GridSearch::optimiseImplementation() {
    arma::Col<double> scaledSamplingFactors = samplingFactors_.at(0) / samplingFactors_;
    numberOfSamples_ = arma::conv_to<arma::Col<arma::uword>>::from(scaledSamplingFactors * std::pow(maximalNumberOfIterations_ / arma::prod(scaledSamplingFactors), 1.0 / static_cast<double>(optimisationProblem_->getNumberOfDimensions())));

    sampleParameters_.clear();
    for (std::size_t n = 0; n < optimisationProblem_->getNumberOfDimensions(); ++n) {
      sampleParameters_.push_back(arma::linspace(optimisationProblem_->getLowerBounds().at(n), optimisationProblem_->getUpperBounds().at(n), numberOfSamples_.at(n)));
    }

    bestSoftConstraintValue_ = std::numeric_limits<double>::infinity();
    bestObjectiveValue_ = std::numeric_limits<double>::infinity();

    sampleIndicies_ = arma::zeros<arma::Col<arma::uword>>(sampleParameters_.size());
    candidateParameter_.set_size(optimisationProblem_->getNumberOfDimensions());
    do {
      ++numberOfIterations_;

      for(std::size_t n = 0; n < sampleIndicies_.n_elem; ++n) {
        candidateParameter_.at(n) = sampleParameters_.at(n).at(sampleIndicies_.at(n));
      }

      ++sampleIndicies_.at(0);
      for(std::size_t n = 0; n < sampleIndicies_.n_elem - 1; ++n) {
        if(sampleIndicies_.at(n) >= numberOfSamples_.at(n)) {
          sampleIndicies_.at(n) = 0;
           ++sampleIndicies_.at(n + 1);
        }
      }

      candidateSoftConstraintValue_ = optimisationProblem_->getSoftConstraintsValue(candidateParameter_);
      candidateObjectiveValue_ = optimisationProblem_->getObjectiveValue(candidateParameter_);

      if(candidateSoftConstraintValue_ < bestSoftConstraintValue_ || candidateSoftConstraintValue_ == bestSoftConstraintValue_ && candidateObjectiveValue_ < bestObjectiveValue_) {
        bestParameter_ = candidateParameter_;
        bestSoftConstraintValue_ = candidateSoftConstraintValue_;
        bestObjectiveValue_ = candidateObjectiveValue_;
      }
    } while(!isFinished() && !isTerminated());
  }

  void GridSearch::setSamplingFactors(
      const arma::Col<double>& samplingFactors) {
    if(samplingFactors.n_elem != optimisationProblem_->getNumberOfDimensions()) {

    } else if(arma::sum(samplingFactors) != 1) {

    }

    samplingFactors_ = samplingFactors;
  }

  std::string GridSearch::to_string() const noexcept {
    return "GridSearch";
  }
}
<|endoftext|>