Skip to content

Partnering

get_mean_rel_duration(params)

Find the average partnership duration by bond type

Parameters:

Name Type Description Default
params parse_params.ObjMap

The current model's parameters

required
Source code in titan/partnering.py
def get_mean_rel_duration(params: "parse_params.ObjMap"):
    """
    Find the average partnership duration by bond type

    args:
        params: The current model's parameters
    """
    mean_rel_duration: Dict[str, Dict] = {}
    for bond in params.partnership.duration:
        mean_rel_duration[bond] = {}
        for race in params.classes.races:
            if params.partnership.duration[bond][race].type == "bins":
                weights = []
                vals = []
                dur_bins = params.partnership.duration[bond][race].bins
                for bins in dur_bins:
                    if bins > 1:
                        weights.append(dur_bins[bins].prob - dur_bins[bins - 1].prob)
                    else:
                        weights.append(dur_bins[bins].prob)
                    vals.append(np.average([dur_bins[bins].min, dur_bins[bins].max]))
                mean_rel_duration[bond][race] = np.average(vals, weights=weights)
            else:
                mean_rel_duration[bond][race] = params.partnership.duration[bond][
                    race
                ].distribution.mean
            assert (
                mean_rel_duration[bond][race] > 0
            ), "All bonds must have a positive duration!"

    return mean_rel_duration

get_partnership_duration(params, rand_gen, bond_type, race)

Get duration of a relationship drawn from bins or a distribution per the params [params.partnership.duration]

Parameters:

Name Type Description Default
params parse_params.ObjMap

model parameters

required
rand_gen

np random number generator

required
bond_type str

type of bond for the relationship whose duration is being determined

required

Returns:

Type Description
int

number of time steps the partnership should endure

Source code in titan/partnering.py
def get_partnership_duration(
    params: "parse_params.ObjMap", rand_gen, bond_type: str, race: Optional[str]
) -> int:
    """
    Get duration of a relationship drawn from bins or a distribution per the params [params.partnership.duration]

    args:
        params: model parameters
        rand_gen: np random number generator
        bond_type: type of bond for the relationship whose duration is being determined

    returns:
        number of time steps the partnership should endure
    """

    if params.partnership.duration[bond_type][race].type == "bins":
        dur_info = params.partnership.duration[bond_type][race].bins
        i = utils.get_independent_bin(rand_gen, dur_info)
        duration = utils.safe_random_int(dur_info[i].min, dur_info[i].max, rand_gen)

    else:
        dist = params.partnership.duration[bond_type][race].distribution
        duration = int(utils.safe_dist(dist, rand_gen))

    return duration

select_partner(agent, partnerable_agents, sex_partners, pwid_agents, params, rand_gen, bond_type)

Get a partner for the agent.

Parameters:

Name Type Description Default
agent agent.Agent

agent in need of a partner

required
partnerable_agents Set[agent.Agent]

agents that can be selected as a partner

required
sex_partners Dict

mapping from sex_type to agents in the population that can sleep with that sex_type

required
pwid_agents agent.AgentSet

agents with drug_type==="Inj"

required
params parse_params.ObjMap

model parameters

required
rand_gen

random number generator

required
bond_type str

type of relationship that is being formed with the partner

required

Returns:

Type Description
Optional[agent.Agent]

new partner or None

Source code in titan/partnering.py
def select_partner(
    agent: "agent.Agent",
    partnerable_agents: Set["agent.Agent"],
    sex_partners: Dict,
    pwid_agents: "agent.AgentSet",
    params: "parse_params.ObjMap",
    rand_gen,
    bond_type: str,
) -> Optional["agent.Agent"]:
    """
    Get a partner for the agent.

    args:
        agent : agent in need of a partner
        partnerable_agents: agents that can be selected as a partner
        sex_partners: mapping from sex_type to agents in the population that can sleep with that sex_type
        pwid_agents: agents with `drug_type==="Inj"`
        params: model parameters
        rand_gen: random number generator
        bond_type: type of relationship that is being formed with the partner

    returns:
        new partner or `None`
    """
    eligible = copy(partnerable_agents)
    eligible -= agent.get_partners()
    eligible -= {agent}

    acts_allowed = params.classes.bond_types[bond_type].acts_allowed

    if "injection" in acts_allowed:
        eligible &= pwid_agents.members

    if "sex" in acts_allowed:
        eligible &= sex_partners[agent.sex_type]

    # short circuit to avoid attempting to assort with no eligible partners
    if not eligible:
        return None

    if params.features.assort_mix:
        match_fns = get_match_fns(
            params.assort_mix.values(), agent, bond_type, rand_gen
        )
        # if no definitions match this agent, don't try to assort
        if len(match_fns) > 0:
            for partner in utils.safe_shuffle(eligible, rand_gen):
                if is_assortable(partner, match_fns):
                    return partner
            return None

    return utils.safe_random_choice(eligible, rand_gen)

sex_possible(agent_sex_type, partner_sex_type, sex_types)

Determine if sex is possible.

Parameters:

Name Type Description Default
agent_sex_type str

name of agent's sex type

required
partner_sex_type str

name of partner's sex type

required
sex_types parse_params.ObjMap

params defining in scope sex types

required

Returns:

Type Description
bool

whether sex is possible between agents of these sex types

Source code in titan/partnering.py
@utils.memo
def sex_possible(
    agent_sex_type: str, partner_sex_type: str, sex_types: "parse_params.ObjMap"
) -> bool:
    """
    Determine if sex is possible.

    args:
        agent_sex_type: name of agent's sex type
        partner_sex_type: name of partner's sex type
        sex_types: params defining in scope sex types

    returns:
        whether sex is possible between agents of these sex types
    """

    # Check input
    if agent_sex_type not in sex_types:
        raise ValueError(f"Invalid agent_sex_type! {agent_sex_type}")
    if partner_sex_type not in sex_types:
        raise ValueError(f"Invalid partner_sex_type! {partner_sex_type}")

    agent_match = agent_sex_type in sex_types[partner_sex_type].sleeps_with
    partner_match = partner_sex_type in sex_types[agent_sex_type].sleeps_with

    return agent_match and partner_match