The probability of a top event, minimal cut sets, importance measures, system reliability and mean time to failure.
How the precision is kept
Probabilities are 64-bit, and the top event is computed by factoring on repeated events, not by a bound. Several formulas subtract from 1 (1 − e^(−λt), 1 − Π(1 − p)), which loses digits when probabilities are small. One of them, the unavailability of a periodically tested standby item, returns wrong values for λτ between 1e-9 and about 1e-6. Mean time to failure is a Simpson integral over 4000 steps.
Open item. Use expm1 and log1p for 1 − e^(−x) and 1 − Π(1 − p), and a series for the standby unavailability when λτ is small.
Calculations under this policy
10 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
logic.jsShared shell, every app64-bit10 calculationsReviewed
The probability of an event from a fixed value, a failure rate and time, a test interval, or repair data.
failed by t: 1 − e^(−λt); tested every τ: 1 − (1 − e^(−λτ)) ÷ (λτ), or λτ ÷ 2 below 1e-9; repairable: MTTR ÷ (MTTF + MTTR)
1 − e^(−x) is formed by subtraction, so its relative error is about 1e-16 ÷ x. The standby form subtracts twice: its error is about 1e-16 ÷ x against a result of x ÷ 2. At λτ = 1e-6 it is right to about 4 digits, at 1e-8 it is off by about 20 %, and at 2e-9 it returns a negative number. Below 1e-9 the series value λτ ÷ 2 is used.
logic.js
lines 4 to 18
/**
* Fault trees and reliability block diagrams on one coherent-logic core.
* fault tree node: { event: 'id' } | { and: [nodes] } | { or: [nodes] } | { koon: [nodes], k } (k or more of the children occur)
* events: { id: { p } | { lambda, t } | { lambda, tau } | { mttf, mttr } }
* The same event id used twice is the SAME event (a repeated event); probability is then computed exactly by factoring (Shannon expansion),
* so repeated events never get multiplied as if independent. Cut sets: MOCUS (Fussell & Vesely 1972) with absorption.
*/
export function eventProbability(e) {
if (e == null) return NaN;
if (e.p != null) return e.p;
if (e.lambda != null && e.t != null) return 1 - Math.exp(-e.lambda * e.t); // non-repairable, failed by time t
if (e.lambda != null && e.tau != null) { const x = e.lambda * e.tau; return x < 1e-9 ? x / 2 : 1 - (1 - Math.exp(-x)) / x; } // standby tested every tau: mean unavailability
if (e.mttf != null && e.mttr != null) return e.mttr / (e.mttf + e.mttr); // repairable, steady state
return NaN;
}
At least k of n events
64-bit
The probability that k or more of a set of independent events occur.
the distribution of the count, built one event at a time, summed from k up
A dynamic program of products and sums of probabilities. All terms are non-negative, so nothing cancels.
logic.js
lines 24 to 28
/** P(k or more of independent events with probabilities ps occur): the Poisson-binomial tail by dynamic programming. */
export function atLeast(k, ps) {
let d = [1]; for (const p of ps) { const nd = new Array(d.length + 1).fill(0); for (let i = 0; i < d.length; i++) { nd[i] += d[i] * (1 - p); nd[i + 1] += d[i] * p; } d = nd; }
let s = 0; for (let i = Math.max(0, k); i < d.length; i++) s += d[i]; return s;
}
AND, OR and voting gates
64-bit
The probability of a gate from its inputs when no event is repeated.
AND: Π pᵢ; OR: 1 − Π (1 − pᵢ)
The OR gate takes 1 minus a product close to 1. For inputs of 1e-9 and 2e-9 it returns 3.000000026e-9 where the true value is 2.999999998e-9: about 8 digits. The smaller the probabilities, the fewer digits remain.
logic.js
lines 30 to 37
function prob(n, p) {
switch (kind(n)) {
case 'event': return p.get(n.event);
case 'and': return kids(n).reduce((a, c) => a * prob(c, p), 1);
case 'or': return 1 - kids(n).reduce((a, c) => a * (1 - prob(c, p)), 1);
default: return atLeast(n.k, kids(n).map((c) => prob(c, p)));
}
}
Top event with repeated events
64-bit
The probability of the top event when the same event appears in several places.
P = p_x × P(tree | x occurs) + (1 − p_x) × P(tree | x does not)
A repeated event is conditioned on, so it is never multiplied with itself as if independent. The recursion doubles for each repeated event; the caller stops at 22.
logic.js
lines 76 to 83
function exact(n, p) {
if (n === true) return 1; if (n === false) return 0;
const ls = leaves(n), count = new Map(); for (const l of ls) count.set(l, (count.get(l) || 0) + 1);
const rep = [...count].filter(([, c]) => c > 1).map(([id]) => id);
if (!rep.length) return prob(n, p);
const x = rep[0], px = p.get(x);
return px * exact(condition(n, x, true), p) + (1 - px) * exact(condition(n, x, false), p);
}
Cut set probabilities and bounds
64-bit
The probability of each minimal cut set and two bounds on the top event.
Each cut set probability is a product. The rare-event value is a plain sum; the upper bound has the same 1 − product cancellation as the OR gate.
logic.js
lines 117 to 118
const csP = cs.sets.map((s) => s.reduce((a, e) => a * p.get(e), 1)), rare = Math.min(1, csP.reduce((a, b) => a + b, 0)), mcub = 1 - csP.reduce((a, b) => a * (1 - b), 1);
if (cs.truncated) probs.push(problem('cutsets-truncated', 'warning', 'There are more cut sets than the limit; the list and its bounds are incomplete.', []));
Importance measures
64-bit
How much each event matters to the top event.
Birnbaum = P(top | p = 1) − P(top | p = 0); Fussell–Vesely = (P − P₀) ÷ P; RAW = P₁ ÷ P; RRW = P ÷ P₀
Two full recomputations per event. Fussell–Vesely subtracts two top probabilities, which are nearly equal for an event that matters little, so small importances have few digits.
logic.js
lines 123 to 126
if (top != null) for (const id of count.keys()) {
const hi = exact(tree, new Map(p).set(id, 1)), lo = exact(tree, new Map(p).set(id, 0)), pi = p.get(id);
imp[id] = { p: pi, birnbaum: hi - lo, criticality: P > 0 ? (hi - lo) * pi / P : 0, fussellVesely: P > 0 ? (P - lo) / P : 0, raw: P > 0 ? hi / P : null, rrw: lo > 0 ? P / lo : null };
}
Reliability of a component
64-bit
The chance a block still works at the mission time.
R = e^(−λt); Weibull: R = e^(−(t ÷ η)^β)
Direct 64-bit evaluation. The block diagram then uses 1 − R as the failure probability, which loses digits when R is close to 1.
logic.js
lines 139 to 144
export function compReliability(c, t) {
if (c.r != null) return c.r;
if (c.lambda != null) return Math.exp(-c.lambda * t);
if (c.weibull) return Math.exp(-Math.pow(t / c.weibull.eta, c.weibull.beta));
return NaN;
}
Block diagram reliability
64-bit
The reliability of series, parallel and k-of-n arrangements.
series = OR of failures; parallel = AND; reliability = 1 − P(failure)
The diagram is turned into failure logic and solved as a fault tree. Reliability is 1 minus the top probability, so for a very reliable system the unreliability is the number that keeps its digits.
logic.js
lines 152 to 161
export function rbd(node, comps, t) {
const events = {}, probs = [];
for (const [id, c] of Object.entries(comps)) { const r = compReliability(c, t); events[id] = { p: 1 - r }; if (!(r >= 0 && r <= 1)) probs.push(problem('rbd-r', 'error', `Block "${id}" gives a reliability of ${r}.`, [{ id }])); }
const koonBad = (n) => (n.koon && !(Number.isInteger(n.k) && n.k >= 1 && n.k <= n.koon.length)) || [n.series, n.parallel, n.koon].some((c) => c && c.some(koonBad));
if (koonBad(node)) probs.push(problem('rbd-koon', 'error', 'A k-of-n block needs k between 1 and n.', []));
if (probs.length) return { ok: false, problems: probs, method: M_RBD };
const ft = faultTree(toFailure(node), events);
if (!ft.ok) return { ok: false, problems: ft.problems, method: M_RBD };
return { ok: true, reliability: 1 - ft.top, unreliability: ft.top, cutSets: ft.cutSets, importance: ft.importance, problems: ft.problems, method: M_RBD };
}
Mean time to failure
64-bit
The mean life of a system that is not repaired.
MTTF = ∫ R(t) dt by Simpson's rule, 4000 steps, to the time R ≤ 1e-9
The horizon is found by doubling from 1 time unit, so it can be up to twice the time needed, and the step is the horizon ÷ 4000. The result has the error of Simpson's rule at that step, and the tail beyond the horizon is left out.
logic.js
lines 163 to 170
/** Mean time to failure of a non-repairable diagram: ∫ R(t) dt by Simpson's rule to the time R falls below 1e-9 (or `horizon`). */
export function rbdMttf(node, comps, { horizon = null, steps = 4000 } = {}) {
let H = horizon;
if (H == null) { H = 1; while (H < 1e12 && rbd(node, comps, H).reliability > 1e-9) H *= 2; }
const n = steps - (steps % 2), h = H / n; let s = 0;
for (let i = 0; i <= n; i++) { const r = rbd(node, comps, i * h).reliability; s += r * (i === 0 || i === n ? 1 : i % 2 ? 4 : 2); }
return { mttf: s * h / 3, horizon: H, method: M_RBD };
}
Common-cause split
64-bit
The independent and the shared part of a failure rate.
independent = λ (1 − β); common = λ β
Two multiplications in 64-bit, with 1 − β formed by one subtraction.
logic.js
lines 172 to 173
/** Beta-factor common cause (IEC 61508-6 Annex D, simple form): the part of a unit's failure rate shared by the whole redundant group. */
export function betaFactor(lambda, beta) { return { independent: lambda * (1 - beta), common: lambda * beta }; }
In detail
Method
Shannon expansion on repeated events; MOCUS cut sets with absorption (the file cites Fussell and Vesely 1972); Poisson-binomial tail for k-of-n gates; rare-event and min-cut upper bounds; Birnbaum, criticality, Fussell–Vesely, risk achievement and risk reduction importance; Simpson's rule.
Number types
64-bit numbers.
Tolerances
The standby unavailability switches to λτ ÷ 2 below λτ = 1e-9. The integration horizon is doubled from 1 until the reliability is at most 1e-9, or until 1e12.
Checked by
The engines test compares a top event with 1 − 0.99 × 0.98 and a block diagram reliability with its closed form, both within 1e-4.
Limits
Factoring is limited to 22 repeated events; above that only the bounds are given. Cut sets are cut off at 20,000 inside an AND gate.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.