Skip to content

Knowledge

Bases: BaseExposure

Source code in titan/exposures/knowledge.py
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
class Knowledge(base_exposure.BaseExposure):
    name: str = "knowledge"
    stats: List[str] = ["knowledge_aware"]
    """
    Knowledge collects the following stats:

    * knowledge_aware - number of agents with active knowledge
    """

    def __init__(self, agent: "ag.Agent"):
        super().__init__(agent)

        self.active = False
        self.opinion = 0.0

    def init_agent(self, pop: "population.Population", time: int):
        """
        Initialize the agent for this exposure during population initialization (`Population.create_agent`).  Called only on exposures that are enabled per the params.

        Stochastically make agent aware, if aware, set the opinion from the params.

        args:
            pop: the population this agent is a part of
            time: the current time step
        """
        knowledge_params = self.agent.location.params.knowledge
        if pop.pop_random.random() < knowledge_params.init:
            self.active = True

        # Initialize all agents with some opinion, may or may not be active
        self.opinion = utils.get_cumulative_bin(
            pop.pop_random, knowledge_params.opinion.init
        )

    def update_agent(self, model: "model.TITAN"):
        """
        Update the agent for this exposure for a time step.  Called once per time step in `TITAN.update_all_agents`.

        If the knowledge start_time has happened, stochastically convert agents.

        args:
            model: the instance of TITAN currently being run
        """
        knowledge_params = self.agent.location.params.knowledge
        if (
            model.time >= knowledge_params.start_time
            and not self.active
            and model.run_random.random() < knowledge_params.prob
        ):
            self.convert(model)

    def set_stats(self, stats: Dict[str, int], time: int):
        if self.active:
            stats["knowledge_aware"] += 1

    @staticmethod
    def expose(
        model: "model.TITAN",
        interaction: str,
        rel: "ag.Relationship",
        num_acts: int,
    ):
        """
        Expose a relationship to the exposure for a number of acts for a specific interaction type.  Typically, this determines if the exposure can cause conversion/change in one of the agents, then if so, determines the probability of that and then converts the succeptible agent.

        If transmission stochastically occurs, either convert the unaware agent, or if both agents aware, have the higher influence agent influce their partner.

        args:
            model: The running model
            interaction: The type of interaction (e.g. sex, injection)
            rel: The relationship where the interaction is occuring
            num_acts: The number of acts of that interaction
        """
        assert (
            model.params.model.network.enable
        ), "Network must be enabled for knowledge exposure"

        # agent/partner ordering is irrelevant at this point for knowledge transmission
        p = rel.agent1.knowledge.get_transmission_probability(  # type: ignore[attr-defined]
            model, interaction, rel.agent2, num_acts
        )

        if model.run_random.random() < p:
            agent1_aware = rel.agent1.knowledge.active  # type: ignore[attr-defined]
            agent2_aware = rel.agent2.knowledge.active  # type: ignore[attr-defined]

            if agent1_aware and agent2_aware:
                influence(model, rel)
            elif agent1_aware:
                rel.agent2.knowledge.convert(model)  # type: ignore[attr-defined]
            elif agent2_aware:
                rel.agent1.knowledge.convert(model)  # type: ignore[attr-defined]

    def get_transmission_probability(
        self,
        model: "model.TITAN",
        interaction: str,
        partner: "ag.Agent",
        num_acts: int,
    ) -> float:
        """
        Get the probability of knowledge/opinion transmission in this relationship

        args:
            model: The running model
            interaction: The interaction type (e.g. `pca`)
            partner: The agent's partner
            num_acts: The number of interactions the agents had

        returns:
            the probability of knowledge/opinion transmission
        """
        if not interaction == "pca":
            return 0.0

        if self.active and partner.knowledge.active:  # type: ignore[attr-defined]
            p = model.params.knowledge.opinion.prob
        else:
            p = model.params.knowledge.prob

        return utils.total_probability(p, num_acts)

    def convert(self, model: "model.TITAN"):
        """
        Make an agent aware, stochastically make knowledge aware if their opinion meets the threshold.

        args:
            model: The running model
        """
        params = self.agent.location.params.knowledge
        self.active = True  # type: ignore[attr-defined]
        if (
            self.opinion > params.opinion.threshold  # type: ignore[attr-defined]
            and model.run_random.random() < params.feature.prob
        ):
            agent_attr = getattr(self.agent, params.feature.name)
            agent_attr.initiate(model, force=True)

stats: List[str] = ['knowledge_aware'] class-attribute instance-attribute

Knowledge collects the following stats:

  • knowledge_aware - number of agents with active knowledge

convert(model)

Make an agent aware, stochastically make knowledge aware if their opinion meets the threshold.

Parameters:

Name Type Description Default
model TITAN

The running model

required
Source code in titan/exposures/knowledge.py
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
def convert(self, model: "model.TITAN"):
    """
    Make an agent aware, stochastically make knowledge aware if their opinion meets the threshold.

    args:
        model: The running model
    """
    params = self.agent.location.params.knowledge
    self.active = True  # type: ignore[attr-defined]
    if (
        self.opinion > params.opinion.threshold  # type: ignore[attr-defined]
        and model.run_random.random() < params.feature.prob
    ):
        agent_attr = getattr(self.agent, params.feature.name)
        agent_attr.initiate(model, force=True)

expose(model, interaction, rel, num_acts) staticmethod

Expose a relationship to the exposure for a number of acts for a specific interaction type. Typically, this determines if the exposure can cause conversion/change in one of the agents, then if so, determines the probability of that and then converts the succeptible agent.

If transmission stochastically occurs, either convert the unaware agent, or if both agents aware, have the higher influence agent influce their partner.

Parameters:

Name Type Description Default
model TITAN

The running model

required
interaction str

The type of interaction (e.g. sex, injection)

required
rel Relationship

The relationship where the interaction is occuring

required
num_acts int

The number of acts of that interaction

required
Source code in titan/exposures/knowledge.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
@staticmethod
def expose(
    model: "model.TITAN",
    interaction: str,
    rel: "ag.Relationship",
    num_acts: int,
):
    """
    Expose a relationship to the exposure for a number of acts for a specific interaction type.  Typically, this determines if the exposure can cause conversion/change in one of the agents, then if so, determines the probability of that and then converts the succeptible agent.

    If transmission stochastically occurs, either convert the unaware agent, or if both agents aware, have the higher influence agent influce their partner.

    args:
        model: The running model
        interaction: The type of interaction (e.g. sex, injection)
        rel: The relationship where the interaction is occuring
        num_acts: The number of acts of that interaction
    """
    assert (
        model.params.model.network.enable
    ), "Network must be enabled for knowledge exposure"

    # agent/partner ordering is irrelevant at this point for knowledge transmission
    p = rel.agent1.knowledge.get_transmission_probability(  # type: ignore[attr-defined]
        model, interaction, rel.agent2, num_acts
    )

    if model.run_random.random() < p:
        agent1_aware = rel.agent1.knowledge.active  # type: ignore[attr-defined]
        agent2_aware = rel.agent2.knowledge.active  # type: ignore[attr-defined]

        if agent1_aware and agent2_aware:
            influence(model, rel)
        elif agent1_aware:
            rel.agent2.knowledge.convert(model)  # type: ignore[attr-defined]
        elif agent2_aware:
            rel.agent1.knowledge.convert(model)  # type: ignore[attr-defined]

get_transmission_probability(model, interaction, partner, num_acts)

Get the probability of knowledge/opinion transmission in this relationship

Parameters:

Name Type Description Default
model TITAN

The running model

required
interaction str

The interaction type (e.g. pca)

required
partner Agent

The agent's partner

required
num_acts int

The number of interactions the agents had

required

Returns:

Type Description
float

the probability of knowledge/opinion transmission

Source code in titan/exposures/knowledge.py
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def get_transmission_probability(
    self,
    model: "model.TITAN",
    interaction: str,
    partner: "ag.Agent",
    num_acts: int,
) -> float:
    """
    Get the probability of knowledge/opinion transmission in this relationship

    args:
        model: The running model
        interaction: The interaction type (e.g. `pca`)
        partner: The agent's partner
        num_acts: The number of interactions the agents had

    returns:
        the probability of knowledge/opinion transmission
    """
    if not interaction == "pca":
        return 0.0

    if self.active and partner.knowledge.active:  # type: ignore[attr-defined]
        p = model.params.knowledge.opinion.prob
    else:
        p = model.params.knowledge.prob

    return utils.total_probability(p, num_acts)

init_agent(pop, time)

Initialize the agent for this exposure during population initialization (Population.create_agent). Called only on exposures that are enabled per the params.

Stochastically make agent aware, if aware, set the opinion from the params.

Parameters:

Name Type Description Default
pop Population

the population this agent is a part of

required
time int

the current time step

required
Source code in titan/exposures/knowledge.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def init_agent(self, pop: "population.Population", time: int):
    """
    Initialize the agent for this exposure during population initialization (`Population.create_agent`).  Called only on exposures that are enabled per the params.

    Stochastically make agent aware, if aware, set the opinion from the params.

    args:
        pop: the population this agent is a part of
        time: the current time step
    """
    knowledge_params = self.agent.location.params.knowledge
    if pop.pop_random.random() < knowledge_params.init:
        self.active = True

    # Initialize all agents with some opinion, may or may not be active
    self.opinion = utils.get_cumulative_bin(
        pop.pop_random, knowledge_params.opinion.init
    )

update_agent(model)

Update the agent for this exposure for a time step. Called once per time step in TITAN.update_all_agents.

If the knowledge start_time has happened, stochastically convert agents.

Parameters:

Name Type Description Default
model TITAN

the instance of TITAN currently being run

required
Source code in titan/exposures/knowledge.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def update_agent(self, model: "model.TITAN"):
    """
    Update the agent for this exposure for a time step.  Called once per time step in `TITAN.update_all_agents`.

    If the knowledge start_time has happened, stochastically convert agents.

    args:
        model: the instance of TITAN currently being run
    """
    knowledge_params = self.agent.location.params.knowledge
    if (
        model.time >= knowledge_params.start_time
        and not self.active
        and model.run_random.random() < knowledge_params.prob
    ):
        self.convert(model)