MATLAB · chapter 3 of 13
Networks: motifs and random topologies
A network is just a signed adjacency matrix, so you can build one by hand, take a registered motif, or draw one at random.
By hand
S = zeros(3);
S(2, 1) = 1; % G1 activates G2
S(3, 2) = -1; % G2 represses G3
model = grn.buildModel(S, Labels = ["A", "B", "C"]);
Registered motifs
grn.motif(name) returns a struct with fields name, S, labels, and description. A second output is the parameter preset that grn.buildModel applies automatically when it is given the motif name. grn.catalog() lists them.
| Name | Genes | Structure | Preset behaviour | |||
|---|---|---|---|---|---|---|
"toggle" | 2 | u and v repress each other | Bistable: Hill 2, alpha = 5 | |||
"repressilator" | 3 | lacI -\ | tetR -\ | cI -\ | lacI | Limit-cycle oscillator: Hill 4, alpha = 10 |
"nar" | 1 | x represses itself | Fast, robust response | |||
"par" | 1 | x activates itself | Slow response, possibly bistable | |||
"ffl_coherent" | 3 | X -> Y, X -> Z, Y -> Z | Sign-sensitive delay (AND gate with multiplicative logic) | |||
"ffl_incoherent" | 3 | X -> Y, X -> Z, Y -\ | Z | Pulse generator | ||
"cascade" | Size (4) | G1 -> G2 -> ... | Linear activation chain | |||
"sim" | Size (4) | TF -> T1, T2, ... | Single-input module | |||
"bifan" | 4 | A, B -> C, D | Two regulators, two targets | |||
"goodwin" | 3 | X -> Y -> Z -\ | X | Oscillator: Hill 8, alpha = 10 |
m = grn.motif("cascade", Size = 6);
model = grn.buildModel(m); % labels kept, no preset
model = grn.buildModel("cascade"); % with the preset, Size 4
The presets set k, vmax, K, hill, gamma, and basal where the textbook behaviour depends on them. You can override any of them through Params.

Random topologies
[S, info] = grn.randomNetwork(n, ...) draws a signed adjacency with n genes.
| Option | Default | Meaning |
|---|---|---|
Topology | "erdosrenyi" | "erdosrenyi", "scalefree", "smallworld", or "modular" |
MeanDegree | 2 | Expected number of regulators per gene |
FractionRepressors | 0.4 | Probability that an edge represses |
SelfRegulation | 0 | Probability that a gene regulates itself |
Modules, WithinFraction | 4, 0.8 | Modular topology: number of modules and fraction of edges inside modules |
Rewire | 0.1 | Small-world topology: rewiring probability |
Seed | 0 | rng seed |
How each topology is drawn:
- Erdős–Rényi. Every ordered pair (i, j), i ≠ j, gets an edge independently with probability
MeanDegree / (n - 1). In-degrees are Poisson-like. - Scale-free. Genes are added one at a time. Each new gene picks
round(MeanDegree)regulators among the existing genes with probability proportional to their out-degree + 1. Early genes become hub transcription factors with many targets; in-degree stays narrow, which matches real regulatory networks better than an undirected Barabási–Albert graph. - Small-world. Each gene is regulated by its
round(MeanDegree)nearest neighbours on a ring; each edge is then rewired to a random regulator with probabilityRewire. - Modular. A stochastic block model with
Modulesequal blocks; edge probabilities are chosen so that a fractionWithinFractionof the expectedMeanDegree * nedges fall inside modules.info.modulesreturns the block of every gene.
After the topology, each edge is made repressing with probability FractionRepressors, and each gene gets a self-loop with probability SelfRegulation (sign drawn the same way). info.meanDegree reports the realised mean in-degree.


[S, info] = grn.randomNetwork(60, Topology = "modular", Modules = 3, ...
MeanDegree = 2.5, Seed = 4);
info
nnz(S), sum(S ~= 0, 2).'
info =
<a href="matlab:helpPopup('struct')" style="font-weight:bold">struct</a> with fields:
topology: "modular"
modules: [60×1 double]
meanDegree: 2.4500
options: [1×1 struct]
ans =
147
ans =
Columns 1 through 13
3 3 2 1 3 3 4 6 3 3 1 4 0
Columns 14 through 26
4 2 3 3 4 4 0 1 0 1 1 1 3
Columns 27 through 39
2 3 0 4 3 4 4 5 3 0 2 3 2
Columns 40 through 52
2 0 6 5 4 0 3 3 4 1 3 0 4
Columns 53 through 60
1 2 3 2 2 2 0 2Checking a network
A few one-liners that are useful before building a model:
nnz(S) % number of edges
sum(S ~= 0, 2).' % in-degree (regulators per gene)
sum(S ~= 0, 1) % out-degree (targets per gene)
find(~any(S, 2)).' % source genes: constitutive, no regulators
nnz(diag(S)) % self-regulating genes