Skip to content

Propagation

dissmodel.models.ca.propagation.Propagation

Bases: CellularAutomaton

Stochastic spatial propagation cellular automaton.

Active cells (ON) spread to inactive neighbors with probability :attr:prob. Once a cell becomes active, it stays active permanently. The neighborhood is based on K-nearest neighbors (KNN, k=4).

Parameters:

Name Type Description Default
gdf GeoDataFrame

GeoDataFrame with geometries and a state attribute.

required
**kwargs Any

Extra keyword arguments forwarded to :class:~dissmodel.geo.CellularAutomaton.

{}

Examples:

>>> from dissmodel.geo import regular_grid
>>> from dissmodel.core import Environment
>>> gdf = regular_grid(dimension=(20, 20), resolution=1, attrs={"state": 0})
>>> env = Environment(end_time=15)
>>> prop = Propagation(gdf=gdf)
>>> prop.initialize()
Source code in dissmodel/models/ca/propagation.py
 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
class Propagation(CellularAutomaton):
    """
    Stochastic spatial propagation cellular automaton.

    Active cells (``ON``) spread to inactive neighbors with probability
    :attr:`prob`. Once a cell becomes active, it stays active permanently.
    The neighborhood is based on K-nearest neighbors (KNN, k=4).

    Parameters
    ----------
    gdf : geopandas.GeoDataFrame
        GeoDataFrame with geometries and a ``state`` attribute.
    **kwargs :
        Extra keyword arguments forwarded to
        :class:`~dissmodel.geo.CellularAutomaton`.

    Examples
    --------
    >>> from dissmodel.geo import regular_grid
    >>> from dissmodel.core import Environment
    >>> gdf = regular_grid(dimension=(20, 20), resolution=1, attrs={"state": 0})
    >>> env = Environment(end_time=15)
    >>> prop = Propagation(gdf=gdf)
    >>> prop.initialize()
    """

    #: Probability of an inactive cell becoming active per step
    #: if it has at least one active neighbor.
    prob: float

    #: Initial proportion of active cells (0.0 – 1.0).
    initial_density: float

    def setup(
        self,
        prob: float = 0.1,
        initial_density: float = 0.4,
    ) -> None:
        """
        Configure the model and build the neighborhood.

        Parameters
        ----------
        prob : float, optional
            Probability of activation per step for inactive cells adjacent
            to at least one active cell, by default 0.1.
        initial_density : float, optional
            Initial proportion of active cells, by default 0.4.
        """
        self.prob = prob
        self.initial_density = initial_density
        self.create_neighborhood(strategy=KNN, k=4, use_index=True)

    def initialize(self) -> None:
        """
        Fill the grid with a random initial state.

        Uses :attr:`initial_density` to determine the proportion of
        cells that start as active. The remaining cells start as inactive.
        """
        fill(
            strategy=FillStrategy.RANDOM_SAMPLE,
            gdf=self.gdf,
            attr="state",
            data={
                PropagationState.OFF: 1 - self.initial_density,
                PropagationState.ON:  self.initial_density,
            },
            seed=42,
        )

    def rule(self, idx: Any) -> int:
        """
        Apply the stochastic propagation rule to cell ``idx``.

        Parameters
        ----------
        idx : any
            Index of the cell being evaluated.

        Returns
        -------
        int
            New state for the cell:

            - ``ON`` if already active (cells never deactivate).
            - ``ON`` with probability :attr:`prob` if inactive and has
              at least one active neighbor.
            - ``OFF`` otherwise.
        """
        state = self.gdf.loc[idx, self.state_attr]

        if state == PropagationState.ON:
            return PropagationState.ON

        has_active_neighbor = (
            self.neighbor_values(idx, self.state_attr) == PropagationState.ON
        ).any()

        if has_active_neighbor and np.random.rand() < self.prob:
            return PropagationState.ON

        return PropagationState.OFF

initialize()

Fill the grid with a random initial state.

Uses :attr:initial_density to determine the proportion of cells that start as active. The remaining cells start as inactive.

Source code in dissmodel/models/ca/propagation.py
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def initialize(self) -> None:
    """
    Fill the grid with a random initial state.

    Uses :attr:`initial_density` to determine the proportion of
    cells that start as active. The remaining cells start as inactive.
    """
    fill(
        strategy=FillStrategy.RANDOM_SAMPLE,
        gdf=self.gdf,
        attr="state",
        data={
            PropagationState.OFF: 1 - self.initial_density,
            PropagationState.ON:  self.initial_density,
        },
        seed=42,
    )

rule(idx)

Apply the stochastic propagation rule to cell idx.

Parameters:

Name Type Description Default
idx any

Index of the cell being evaluated.

required

Returns:

Type Description
int

New state for the cell:

  • ON if already active (cells never deactivate).
  • ON with probability :attr:prob if inactive and has at least one active neighbor.
  • OFF otherwise.
Source code in dissmodel/models/ca/propagation.py
 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
def rule(self, idx: Any) -> int:
    """
    Apply the stochastic propagation rule to cell ``idx``.

    Parameters
    ----------
    idx : any
        Index of the cell being evaluated.

    Returns
    -------
    int
        New state for the cell:

        - ``ON`` if already active (cells never deactivate).
        - ``ON`` with probability :attr:`prob` if inactive and has
          at least one active neighbor.
        - ``OFF`` otherwise.
    """
    state = self.gdf.loc[idx, self.state_attr]

    if state == PropagationState.ON:
        return PropagationState.ON

    has_active_neighbor = (
        self.neighbor_values(idx, self.state_attr) == PropagationState.ON
    ).any()

    if has_active_neighbor and np.random.rand() < self.prob:
        return PropagationState.ON

    return PropagationState.OFF

setup(prob=0.1, initial_density=0.4)

Configure the model and build the neighborhood.

Parameters:

Name Type Description Default
prob float

Probability of activation per step for inactive cells adjacent to at least one active cell, by default 0.1.

0.1
initial_density float

Initial proportion of active cells, by default 0.4.

0.4
Source code in dissmodel/models/ca/propagation.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def setup(
    self,
    prob: float = 0.1,
    initial_density: float = 0.4,
) -> None:
    """
    Configure the model and build the neighborhood.

    Parameters
    ----------
    prob : float, optional
        Probability of activation per step for inactive cells adjacent
        to at least one active cell, by default 0.1.
    initial_density : float, optional
        Initial proportion of active cells, by default 0.4.
    """
    self.prob = prob
    self.initial_density = initial_density
    self.create_neighborhood(strategy=KNN, k=4, use_index=True)

dissmodel.models.ca.propagation.PropagationState

Bases: IntEnum

Possible states for a cell in :class:Propagation.

Attributes:

Name Type Description
OFF int

Inactive cell, can be activated by neighbors.

ON int

Active cell, spreads to neighbors.

Source code in dissmodel/models/ca/propagation.py
13
14
15
16
17
18
19
20
21
22
23
24
25
class PropagationState(IntEnum):
    """
    Possible states for a cell in :class:`Propagation`.

    Attributes
    ----------
    OFF : int
        Inactive cell, can be activated by neighbors.
    ON : int
        Active cell, spreads to neighbors.
    """
    OFF = 0
    ON  = 1