# Sensitivity¶

The neet.sensitivity module provides a collection of functions for computing measures of sensitivity of networks, i.e. the degree to which perturbations of the network state propogate and spread. This module also provides a collection of functions for identifying “canalizing edges”: edges for which a state of the source node uniquely determines the state of the target regardless of other sources.

## API Documentation¶

### Sensitivity Measures¶

neet.sensitivity.sensitivity(net, state, transitions=None)[source]

Calculate Boolean network sensitivity, as defined in [Shmulevich2004]

The sensitivity of a Boolean function $$f$$ on state vector $$x$$ is the number of Hamming neighbors of $$x$$ on which the function value is different than on $$x$$.

This calculates the average sensitivity over all $$N$$ boolean functions, where $$N$$ is the size of net.

Examples

>>> sensitivity(s_pombe, [0, 0, 0, 0, 0, 1, 1, 0, 0])
1.0
>>> sensitivity(s_pombe, [0, 1, 1, 0, 1, 0, 0, 1, 0])
0.4444444444444444
>>> sensitivity(c_elegans, [0, 0, 0, 0, 0, 0, 0, 0])
1.75
>>> sensitivity(c_elegans, [1, 1, 1, 1, 1, 1, 1, 1])
1.25

Parameters: net – neet boolean network state – a single network state, represented as a list of node states transitions (list or None) – a list of precomputed state transitions (optional)
neet.sensitivity.average_sensitivity(net, states=None, weights=None, calc_trans=True)[source]

Calculate average Boolean network sensitivity, as defined in [Shmulevich2004].

The sensitivity of a Boolean function $$f$$ on state vector $$x$$ is the number of Hamming neighbors of $$x$$ on which the function value is different than on $$x$$.

The average sensitivity is an average taken over initial states.

Examples

>>> average_sensitivity(c_elegans)
1.265625
>>> average_sensitivity(c_elegans, states=[[0, 0, 0, 0, 0, 0, 0, 0],
... [1, 1, 1, 1, 1, 1, 1, 1]])
...
1.5
>>> average_sensitivity(c_elegans, states=[[0, 0, 0, 0, 0, 0, 0, 0],
... [1, 1, 1, 1, 1, 1, 1, 1]],weights=[0.9, 0.1])
...
1.7
>>> average_sensitivity(c_elegans, states=[[0, 0, 0, 0, 0, 0, 0, 0],
... [1, 1, 1, 1, 1, 1, 1, 1]], weights=[9, 1])
...
1.7

Parameters: net – NEET boolean network states – Optional list or generator of states. If None, all states are used. weights – Optional list or generator of weights for each state. If None, each state is equally weighted. If states and weights are both None, an algorithm is used to efficiently make use of sparse connectivity. the average sensitivity of net
neet.sensitivity.lambdaQ(net, **kwargs)[source]

Calculate sensitivity eigenvalue, the largest eigenvalue of the sensitivity matrix average_difference_matrix().

This is analogous to the eigenvalue calculated in [Pomerance2009].

Examples

>>> lambdaQ(s_pombe)
0.8265021276831896
>>> lambdaQ(c_elegans)
1.263099227661824

Parameters: net – a neet boolean network the sensitivity eigenvalue ($$\lambda_Q$$) of net

### Canalization Functions¶

neet.sensitivity.is_canalizing(net, node_i, neighbor_j)[source]

Determine whether a given network edge is canalizing: if node_i’s value at $$t+1$$ is fully determined when neighbor_j’s value has a particular value at $$t$$, regardless of the values of other nodes, then there is a canalizing edge from neighbor_j to node_i.

According to (Stauffer 1987), “A rule … is called forcing, or canalizing, if at least one of its $$K$$ arguments has the property that the result of the function is already fixed if this argument has one particular value, regardless of the values for the $$K-1$$ other arguments.” Note that this is a definition for whether a node’s rule is canalizing, whereas this function calculates whether a specific edge is canalizing. Under this definition, if a node has any incoming canalizing edges, then its rule is canalizing.

Examples

>>> is_canalizing(s_pombe, 1, 2)
True
>>> is_canalizing(s_pombe, 2, 1)
False
>>> is_canalizing(c_elegans, 7, 7)
True
>>> is_canalizing(c_elegans, 1, 3)
True
>>> is_canalizing(c_elegans, 4, 3)
False

Parameters: net – a neet boolean network node_i – target node index neighbor_j – source node index True if the edge (neighbor_j, node_i) is canalizing, or None if the edge does not exist
neet.sensitivity.canalizing_edges(net)[source]

Return a set of tuples corresponding to the edges in the network that are canalizing. Each tuple consists of two node indices, corresponding to an edge from the second node to the first node (so that the second node controls the first node in a canalizing manner).

Examples

>>> canalizing_edges(s_pombe)
{(1, 2), (5, 4), (0, 0), (1, 3), (4, 5), (5, 6), (5, 7), (1, 4), (8, 4), (5, 2), (5, 3)}
>>> canalizing_edges(c_elegans)
{(1, 2), (3, 2), (1, 3), (7, 6), (6, 0), (7, 7)}

Parameters: net – a neet boolean network the set of canalizing edges as in the form (target, source)
neet.sensitivity.canalizing_nodes(net)[source]

Find the nodes of the network which have at least one incoming canalizing edge.

Examples

>>> canalizing_nodes(s_pombe)
{0, 1, 4, 5, 8}
>>> canalizing_nodes(c_elegans)
{1, 3, 6, 7}

Parameters: net – a neet boolean network the set indices of nodes with at least one canalizing input edge

### Utility Functions¶

neet.sensitivity.difference_matrix(net, state, transitions=None)[source]

Returns matrix answering the question: Starting at the given state, does flipping the state of node j change the state of node i?

Examples

>>> difference_matrix(s_pombe, [0, 0, 0, 0, 0, 0, 0, 0, 0])
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 1., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 0., 0., 1.],
[0., 0., 0., 1., 0., 0., 0., 0., 1.],
[0., 0., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 0., 1., 0., 1.],
[0., 1., 0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1., 0., 0., 0., 0.]])
>>> difference_matrix(c_elegans, [0, 0, 0, 0, 0, 0, 0, 0])
array([[1., 0., 0., 0., 0., 0., 0., 1.],
[0., 0., 1., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 1., 1., 0., 1.],
[0., 0., 0., 0., 0., 1., 1., 0.],
[1., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 1.]])

Parameters: net – a neet boolean network state – the starting state transitions (list or None) – a precomputed list of state transitions (optional)
neet.sensitivity.average_difference_matrix(net, states=None, weights=None, calc_trans=True)[source]

Averaged over states, what is the probability that node i’s state is changed by a single bit flip of node j?

Examples

>>> average_difference_matrix(s_pombe)
array([[0.    , 0.    , 0.    , 0.    , 0.    , 0.    , 0.    , 0.    ,
0.    ],
[0.    , 0.    , 0.25  , 0.25  , 0.25  , 0.    , 0.    , 0.    ,
0.    ],
[0.25  , 0.25  , 0.25  , 0.    , 0.    , 0.25  , 0.    , 0.    ,
0.25  ],
[0.25  , 0.25  , 0.    , 0.25  , 0.    , 0.25  , 0.    , 0.    ,
0.25  ],
[0.    , 0.    , 0.    , 0.    , 0.    , 1.    , 0.    , 0.    ,
0.    ],
[0.    , 0.    , 0.0625, 0.0625, 0.0625, 0.    , 0.0625, 0.0625,
0.    ],
[0.    , 0.5   , 0.    , 0.    , 0.    , 0.    , 0.5   , 0.    ,
0.5   ],
[0.    , 0.5   , 0.    , 0.    , 0.    , 0.    , 0.    , 0.5   ,
0.5   ],
[0.    , 0.    , 0.    , 0.    , 1.    , 0.    , 0.    , 0.    ,
0.    ]])
>>> average_difference_matrix(c_elegans)
array([[0.25  , 0.25  , 0.    , 0.    , 0.    , 0.25  , 0.25  , 0.25  ],
[0.    , 0.    , 0.5   , 0.5   , 0.    , 0.    , 0.    , 0.    ],
[0.5   , 0.    , 0.5   , 0.    , 0.5   , 0.    , 0.    , 0.    ],
[0.    , 0.    , 1.    , 0.    , 0.    , 0.    , 0.    , 0.    ],
[0.    , 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.    , 0.3125],
[0.5   , 0.    , 0.    , 0.    , 0.    , 0.5   , 0.5   , 0.    ],
[1.    , 0.    , 0.    , 0.    , 0.    , 0.    , 0.    , 0.    ],
[0.    , 0.    , 0.    , 0.    , 0.    , 0.    , 0.5   , 0.5   ]])

Parameters: states (list or None) – If None, average over all possible states. Otherwise, providing a list of states will calculate the average over only those states. calc_trans (bool) – Optionally pre-calculate all transitions. Only used when states or weights argument is not None. boolean numpy array