boofun.analysis.canalization
Canalization Analysis for Boolean Functions.
Canalization is a concept from systems biology where certain input values “dominate” and determine the output regardless of other inputs.
A Boolean function f is canalizing if there exists: - A variable x_i - A canalizing input a ∈ {0, 1} - A canalized output b ∈ {0, 1}
Such that: f(x_1, …, x_i=a, …, x_n) = b for all other inputs.
References: - Kauffman, S.A. (1969). Metabolic stability and epigenesis in randomly
constructed genetic nets. Journal of Theoretical Biology.
Kadelka, C. et al. (2023). Collectively canalizing Boolean functions. Advances in Applied Mathematics.
Functions
Compute edge effectiveness for each variable. |
|
Compute effective degree: sum of edge effectiveness. |
|
Compute the canalizing depth of a Boolean function. |
|
Find all canalizing variables and their canalizing inputs/outputs. |
|
Find all essential (non-degenerate) variables. |
|
Classify each input variable by its type. |
|
Find groups of symmetric (interchangeable) variables. |
|
Compute input redundancy: fraction of inputs that are redundant. |
|
Determine if a Boolean function is canalizing. |
|
|
Determine if a Boolean function is k-canalizing. |
Determine if a Boolean function is nested canalizing (NCF). |
Classes
High-level analyzer for canalization properties. |
- boofun.analysis.canalization.is_canalizing(f: BooleanFunction) bool[source]
Determine if a Boolean function is canalizing.
A function is canalizing if there exists at least one variable x_i and a value a ∈ {0,1} such that fixing x_i = a forces the output to a constant value, regardless of other inputs.
- Parameters:
f – Boolean function to test
- Returns:
True if function is canalizing, False otherwise
Example
>>> import boofun as bf >>> bf.AND(3).is_canalizing() # AND canalizes on 0 True >>> bf.parity(3).is_canalizing() # Parity is not canalizing False
- boofun.analysis.canalization.get_canalizing_variables(f: BooleanFunction) List[Dict][source]
Find all canalizing variables and their canalizing inputs/outputs.
- Parameters:
f – Boolean function to analyze
- Returns:
‘variable’: index of canalizing variable
’canalizing_input’: the input value (0 or 1) that canalizes
’canalized_output’: the forced output value (0 or 1)
- Return type:
List of dicts, each containing
Example
>>> import boofun as bf >>> bf.AND(3).get_canalizing_variables() [{'variable': 0, 'canalizing_input': 0, 'canalized_output': 0}, ...]
- boofun.analysis.canalization.get_canalizing_depth(f: BooleanFunction) int[source]
Compute the canalizing depth of a Boolean function.
The canalizing depth is the maximum k such that the function is k-canalizing (has k layers of nested canalization).
A function is k-canalizing if: 1. It has a canalizing variable x_i1 with input a1 → output b1 2. The subfunction f|_{x_i1 ≠ a1} is (k-1)-canalizing
- Parameters:
f – Boolean function to analyze
- Returns:
Canalizing depth (0 for non-canalizing functions)
Example
>>> import boofun as bf >>> bf.AND(3).get_canalizing_depth() # AND is fully nested canalizing 3 >>> bf.parity(3).get_canalizing_depth() # Parity has depth 0 0
- boofun.analysis.canalization.is_k_canalizing(f: BooleanFunction, k: int) bool[source]
Determine if a Boolean function is k-canalizing.
A function is k-canalizing if it has at least k layers of nested canalization.
- Parameters:
f – Boolean function to test
k – Required canalizing depth (0 ≤ k ≤ n)
- Returns:
True if function is at least k-canalizing
Example
>>> import boofun as bf >>> bf.AND(3).is_k_canalizing(3) # AND is fully nested True >>> bf.parity(3).is_k_canalizing(1) # Parity is not even 1-canalizing False
- boofun.analysis.canalization.is_nested_canalizing(f: BooleanFunction) bool[source]
Determine if a Boolean function is nested canalizing (NCF).
A function on n variables is nested canalizing if it has canalizing depth n (every variable is canalizing in some layer).
NCFs are important in biological modeling.
- Parameters:
f – Boolean function to test
- Returns:
True if function is nested canalizing
Example
>>> import boofun as bf >>> bf.AND(3).is_nested_canalizing() # AND is NCF True >>> bf.majority(3).is_nested_canalizing() # Majority is not NCF False
- boofun.analysis.canalization.get_essential_variables(f: BooleanFunction) List[int][source]
Find all essential (non-degenerate) variables.
A variable is essential if there exists some input where flipping that variable changes the output.
- Parameters:
f – Boolean function to analyze
- Returns:
List of indices of essential variables
Example
>>> import boofun as bf >>> len(bf.AND(3).get_essential_variables()) 3
- boofun.analysis.canalization.get_input_types(f: BooleanFunction) Dict[int, str][source]
Classify each input variable by its type.
Types: - “positive”: f is monotone increasing in this variable - “negative”: f is monotone decreasing in this variable - “conditional”: f depends on this variable non-monotonically - “non-essential”: f does not depend on this variable
- Parameters:
f – Boolean function to analyze
- Returns:
Dict mapping variable index to type string
Example
>>> import boofun as bf >>> bf.AND(3).get_input_types() {0: 'positive', 1: 'positive', 2: 'positive'}
- boofun.analysis.canalization.get_symmetry_groups(f: BooleanFunction) List[Set[int]][source]
Find groups of symmetric (interchangeable) variables.
Two variables are symmetric if swapping their values in any input does not change the function’s output.
- Parameters:
f – Boolean function to analyze
- Returns:
List of sets, where each set contains indices of variables that are mutually symmetric.
Example
>>> import boofun as bf >>> bf.AND(3).get_symmetry_groups() # All variables symmetric [{0, 1, 2}] >>> bf.dictator(3, 0).get_symmetry_groups() [{1, 2}, {0}] # Only non-dictator vars symmetric
- boofun.analysis.canalization.input_redundancy(f: BooleanFunction) float[source]
Compute input redundancy: fraction of inputs that are redundant.
Input redundancy quantifies how many inputs are not needed to determine the output on average. Constant functions have redundancy 1, parity has redundancy 0.
This is computed as: k_r / n where k_r is the average number of redundant inputs across all input combinations.
- Parameters:
f – Boolean function to analyze
- Returns:
Input redundancy in [0, 1]
Note
This is a simplified version. For full CANA-style redundancy, install the CANA package.
- boofun.analysis.canalization.edge_effectiveness(f: BooleanFunction) ndarray[source]
Compute edge effectiveness for each variable.
Edge effectiveness measures how much flipping a variable influences the output. This is related to the influence but normalized differently.
e_i = Pr[f(x) ≠ f(x ⊕ e_i)]
This is equivalent to the influence Inf_i[f].
- Parameters:
f – Boolean function to analyze
- Returns:
Array of effectiveness values in [0, 1]
- boofun.analysis.canalization.effective_degree(f: BooleanFunction) float[source]
Compute effective degree: sum of edge effectiveness.
This is equivalent to the total influence I[f].
- Parameters:
f – Boolean function to analyze
- Returns:
Effective degree (= total influence)
- class boofun.analysis.canalization.CanalizationAnalyzer(f: BooleanFunction)[source]
High-level analyzer for canalization properties.
Example
>>> import boofun as bf >>> analyzer = CanalizationAnalyzer(bf.AND(4)) >>> analyzer.summary()
- __init__(f: BooleanFunction)[source]
Initialize analyzer.
- Parameters:
f – Boolean function to analyze