What this page covers.
How to combine step-level preferences (e.g., sequential reactions or parallel branches) into a single, bounded pathway preference. The trick is to work in rapidity space for linearity, use positive weights for emphasis, and then map back—so the result stays bounded, collapse-safe, and order-independent.
Plain-language overview
- Sequential or parallel, same recipe: treat each step/branch as a bounded preference, move to rapidity for linear combination, then return to the bounded channel.
- Weights with intent: choose positive weights to reflect emphasis (default is stoichiometric emphasis per step). Publish your policy.
- Stream-friendly: you can fold steps in any order; partial sums yield the same final result.
- Sign intuition: if all steps lean the same way, the pooled pathway leans that way too; mixed signs resolve by the weighted rapidities.
- Safety: clamp each step’s alignment before any inverse map; guard the denominator; publish the guards in the manifest.
Plain ASCII formulas (copy-ready)
Definition (canonical)
# step k has bounded alignment a_k in (-1, 1) and weight w_k > 0
# default weight: w_k := sum_over_reactants_in_step_k( abs(m) ^ gamma ), gamma >= 0
u_total = sum_k( w_k * atanh(a_k) )
W_total = sum_k( w_k )
a_total = tanh( u_total / max(W_total, eps_w) ) # eps_w > 0
Interpretation
# a_total is the pooled pathway preference (bounded, dimensionless).
# If each a_k is the per-step RSI under the same conditions,
# then a_total is the pathway-level RSI.
Guards and inputs
# clamp every a_k to |a_k| <= 1 - eps_a before atanh(a_k) (eps_a > 0)
# choose w_k explicitly; the default preserves stoichiometric emphasis
# use eps_w > 0 to guard W_total
Invariants and guarantees
# boundedness:
abs(a_total) < 1
# order-independence (commutative over multisets of steps/branches)
# associativity/streaming:
# fold in any order; partial sums of (u_total, W_total) give the same result
# collapse compatibility:
# pooling acts only on alignment; magnitude collapse remains classical
# sign behavior:
# if all a_k share the same sign, a_total has that sign; mixed signs resolve by weighted rapidities
Minimal pseudocode (ASCII)
pool_steps(a_list, w_list, eps_a=1e-12, eps_w=1e-12):
U, W = 0.0, 0.0
for k in 1..len(a_list):
a = a_list[k]
w = w_list[k] # default: sum_over_reactants_in_step_k(abs(m)^gamma)
a = sign(a) * min(abs(a), 1 - eps_a)
U = U + w * atanh(a)
W = W + w
a_total = tanh( U / max(W, eps_w) )
return sign(a_total) * min(abs(a_total), 1 - eps_a)
Navigation
Previous – Invariants & Scale/Weight Robustness (3.5, 3.6)
Next – Interpreting Magnitude & Minimal Algorithm (3.8, 3.9)