Open mensch72 opened 3 years ago
fixed
attribute to Variable
and verifying that no change is attempted or has happened in set_value(s)
and Runner
.@leander-j : please review this user story to see whether it would work for you in the granovetter model! I imagine we could then together code a generic component imitation
that can do all sorts of imitation, either simple, or complex, or Granovetter-style with thresholds. It could use the following specification attributes and parameter variables:
imitation_variables
: list of variable objects that will be imitatedimitation_networks
: dict specifying a network object for each of these variablesimitation_rates
: dict specifying a rate in units D.years**-1 per variableimitation_types
: dict specifying either 'simple' or 'threshold' per variable (to be extended later)
'simple'
means one neighbor is drawn at random and is imitated'threshold'
means a certain number or fraction of the neighbors are drawn at random and if at least a certain value-specific threshold of them agree on that value, that value is imitated. in that case, we specify further:imitation_n_neighbors
: dict by variable specifying how many neighbors are drawnimitation_neighbor_fractions
: dict by variable specifying what fraction of the neighbors are drawn (alternatively to n_neighbors)imitation_thresholds
: dict specifying for each variable either a what fraction of the drawn neighbors need to agree for an imitation, or specifying another dict keyed by variable value specifying such fractions.Example:
# things the user cannot change:
imitation_variables = [A.Individual.is_active, A.Individual.savings_rate]
imitation_types = { A.Individual.is_active: 'threshold', A.Individual.savings_rate: 'simple' }
# things the user can change:
imitation.imitation_rates.default = { A.Individual.is_active: 1.0 / D.weeks, A.Individual.savings_rate: 3.0 / D.years }
imitation.imitation_neighbor_fractions.default = { A.Individual.is_active: 1.0 } # -> always look at all nighbors
imitation.imitation_thresholds.default = { A.Individual.is_active: { True: 0.4, False: 0.6 } } # -> it is easier to get active than to get inactive
I think it makes a lot of sense that way. Assigning some nodes an unchangable state (maybe via thresholds) as well as probabilities for imitation are some additional features needed. The chosen network object should not be reassignable but it might evolve in time as well
When composing a model, the model composer can...
A fixed variable cannot be changed by the model user or by any component. This is verified at runtime.
Example use case: Specify that environmental friendliness and savings rate will be imitated, one with simple contagion, the other with complex contagion, with some default imitation rates: