Skip to content

File bubbles-bones.hpp

File List > epiworld > globalevents > bubbles-bones.hpp

Go to the documentation of this file

#ifndef EPIWORLD_GLOBALEVENTS_BUBBLES_BONES_HPP
#define EPIWORLD_GLOBALEVENTS_BUBBLES_BONES_HPP

// Standard library headers (vector, memory, string, unordered_map, utility,
// algorithm, stdexcept) are included at global scope by epiworld.hpp; this file
// is only ever included from within `namespace epiworld`, so it must not
// re-include system headers here.
#include "../config.hpp"

enum class BubbleFlavor {
    Household,
    Peer
};

enum class BubbleTies {
    Existing,
    Complete
};

template<typename TSeq>
class Bubbles;

template<typename TSeq = EPI_DEFAULT_TSEQ>
class BubbleTool : public Tool<TSeq> {
private:

    std::string _event_name;                  
    Bubbles<TSeq> * _policy = nullptr;        

public:

    BubbleTool(std::string name, std::string event_name);

    epiworld_double get_susceptibility_reduction(
        VirusPtr<TSeq> & v,
        Model<TSeq> * model
    ) override;

    std::unique_ptr<Tool<TSeq>> clone_ptr() const override;

};

template<typename TSeq = EPI_DEFAULT_TSEQ>
class Bubbles final : public GlobalEvent<TSeq> {
private:

    std::vector< size_t > household_id;
    BubbleFlavor flavor;
    size_t group_size;               
    size_t max_households;           
    epiworld_double transmission_factor; 
    int start_day;
    int end_day;
    int rewire_every;
    std::string param_name;          
    BubbleTies ties;                 

    // Per-model state. Copied with the intervention, so each model (including
    // each per-thread copy made by run_multiple) owns its own partition.
    std::vector< int > bubble_id;    

    std::vector< std::pair< size_t, size_t > > created_ties;
    int ties_epoch = -1;             
    int model_id   = -1;             
    int last_epoch = -1;             

    class HeldTies {
    public:
        HeldTies(Model<TSeq> * model, const Bubbles<TSeq> & self);
        void focus(size_t a);
        bool contains(size_t b) const;
    private:
        std::vector< size_t > start;    
        std::vector< size_t > partner;  
        std::vector< char > marked;     
        size_t focused = 0u;
    };

    void partition_household(Model<TSeq> * model, HeldTies & held);
    void partition_peer(Model<TSeq> * model, HeldTies & held);

    void _setup(Model<TSeq> * model);

    void build_ties(Model<TSeq> * model);

    void sync_ties(Model<TSeq> * model);

    bool wants_ties(Model<TSeq> * model) const;

    void withdraw_ties(Model<TSeq> * model, bool hand_over);

    Bubbles<TSeq> * heir_of(Model<TSeq> * model, size_t i, size_t j);

public:

    Bubbles(
        std::vector< size_t > household_id,
        BubbleFlavor flavor,
        size_t group_size,
        epiworld_double transmission_factor = 0.0,
        int start_day = 0,
        int end_day = -1,
        int rewire_every = 0,
        std::string name = "Social bubble",
        size_t max_households = 2u,
        std::string param_name = "Bubble transmission factor",
        BubbleTies ties = BubbleTies::Existing
    );

    static Bubbles<TSeq> * get_from(
        Model<TSeq> & model,
        const std::string & name = "Social bubble"
    );

    void compute_partition(Model<TSeq> * model);

    const std::vector< int > & get_bubble_id() const;

    BubbleFlavor get_flavor() const;

    BubbleTies get_ties() const;

    void set_ties(BubbleTies ties);

    const std::vector< std::pair< size_t, size_t > > & get_created_ties() const;

    void restore_network(Model<TSeq> * model);

    const std::string & get_param_name() const;

    bool is_active(int today) const;

    int get_last_epoch() const;

    epiworld_double susceptibility_reduction(
        const Agent<TSeq> * p,
        const Agent<TSeq> * transmitter,
        Model<TSeq> * model
    ) const;

    void reset(Model<TSeq> * model) override;

    void operator()(Model<TSeq> * model, int day) override;

    std::unique_ptr< GlobalEvent<TSeq> > clone_ptr() const override;

};

#endif