Reliability system modeling and analysis with graph visualization
Project description
fiabilipym
Reliability system modeling and analysis with graph visualization.
fiabilipym is a modernized, Python 3 compatible distribution of the original
fiabilipy library, preserving the same public API, mathematical models,
and numerical behavior, while updating packaging, dependencies, and system
drawing. It also adds Monte Carlo aging with Weibull lifetimes for
simulation-based studies.
The goal of this project is compatibility first, modernization second.
Compatibility with fiabilipy
fiabilipym is designed to be a drop-in replacement for fiabilipy.
Guaranteed invariants:
- Same public API (
Component,System,Markov,Voter, …) - Same system construction semantics (
E→ components →S) - Same reliability / availability / MTTF mathematics
- Same symbolic and numeric results
Code written for fiabilipy 2.x runs unchanged (except for Python 2 → 3 syntax).
The examples below correspond directly to the “How to build a system” section of the original fiabilipy 2.4 documentation.
What it does
- Build reliability block diagrams
- Compute reliability, availability, maintainability, and MTTF
- Model systems using Markov processes
- Draw system graphs with Matplotlib
- Simulate aging with Weibull (Monte Carlo), yielding MTTF and R(t) curves
Canonical examples (identical behavior)
Building a component
from fiabilipym import Component
from sympy import Symbol
t = Symbol("t", positive=True)
comp = Component("C0", 1e-4)
comp.mttf
# 10000.0
comp.reliability(1000)
# 0.904837418035960
comp.reliability(t)
# exp(-0.0001*t)
comp.reliability(t=100)
# 0.990049833749168
Building a system (series)
from fiabilipym import Component, System
from sympy import Symbol
t = Symbol("t", positive=True)
power = Component("P0", 1e-6)
motor = Component("M0", 1e-3)
S = System()
S["E"] = [power]
S[power] = [motor]
S[motor] = "S"
S.mttf
# 1000000/1001
S.reliability(t)
# exp(-1001*t/1000000)
Visualization
Why Graphviz/pygraphviz is no longer required
The project moved away from a hard Graphviz/pygraphviz requirement for day-to-day usage and testing:
- Graphviz-based installs are fragile across environments (native binaries, headers, and PATH issues).
- Reproducibility was inconsistent across platforms, especially Windows/conda setups.
- For this project’s block-diagram needs, Graphviz introduced unnecessary operational overhead.
- A lightweight Matplotlib block-style approach now covers the primary visualization workflow.
System.draw() renders reliability block diagrams with Matplotlib.
import matplotlib
matplotlib.use("Agg") # use a non-interactive backend for CI/headless runs
import matplotlib.pyplot as plt
from fiabilipym import Component, System
motor = Component("M", 1e-4, 3e-2)
power = Component("P", 1e-6, 2e-4)
system = System()
system["E"] = [power]
system[power] = [motor]
system[motor] = "S"
system.draw()
plt.tight_layout()
plt.savefig("block_diagram.png", dpi=150)
Minimal Matplotlib-only block diagram example:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(5, 2))
ax.plot([0.1, 0.9], [0.5, 0.5], color="black", linewidth=1.5)
ax.text(0.08, 0.5, "E", va="center", ha="right")
ax.text(0.92, 0.5, "S", va="center", ha="left")
ax.add_patch(plt.Rectangle((0.4, 0.4), 0.2, 0.2, fill=False, linewidth=1.5))
ax.text(0.5, 0.5, "C1", va="center", ha="center")
ax.set_axis_off()
fig.tight_layout()
fig.savefig("minimal_block_diagram.png", dpi=150)
Monte Carlo aging (Weibull)
Use Weibull distributions to sample component lifetimes, then simulate system MTTF and R(t) curves with Monte Carlo.
import numpy as np
from fiabilipym import Component, System, Weibull, weibull_eta_from_lambda
beta = 2.0
lam0 = 1e-4
eta = weibull_eta_from_lambda(lam0, beta)
dist = Weibull(beta, eta)
C0 = Component("C0", lam0).with_distribution(dist)
C1 = Component("C1", lam0).with_distribution(dist)
C2 = Component("C2", lam0).with_distribution(dist)
S = System()
S["E"] = C0
S[C0] = [C1, C2]
S[C1] = "S"
S[C2] = "S"
T = np.linspace(0, 50000, 50)
mttf_hat, R_hat = S.monte_carlo(n=50000, grid_t=T, seed=42)
Voters (k-out-of-n) support Monte Carlo as well:
import numpy as np
from fiabilipym import Component, Voter, Weibull, weibull_eta_from_lambda
beta = 2.0
lam0 = 1e-4
eta = weibull_eta_from_lambda(lam0, beta)
dist = Weibull(beta, eta)
base = Component("C", lam0).with_distribution(dist)
voter = Voter(base, M=2, N=3)
T = np.linspace(0, 50000, 50)
mttf_hat, R_hat = voter.monte_carlo(n=50000, grid_t=T, seed=42)
Notebook-style demo (architectures + plots)
The included notebook fiabilipym_weibull_montecarlo_demo.ipynb builds the
five reference architectures and generates:
- MTTF bar plot
- Reliability R(t) curves
- Optional MTTF vs baseline lambda sweep (mean-matched)
- System drawings
If you want a code-only version, the snippet below mirrors the notebook's core:
import numpy as np
import matplotlib.pyplot as plt
from fiabilipym import Component, System, Voter, Weibull, weibull_eta_from_lambda
beta = 2.0
lam0 = 1e-4
eta0 = weibull_eta_from_lambda(lam0, beta)
def aging_component(name, lam, beta, eta, age0=0.0):
c = Component(name, lam).with_distribution(Weibull(beta, eta), age0=age0)
return c
def build_series3(lam, beta, eta):
c1, c2, c3 = (aging_component("C1", lam, beta, eta),
aging_component("C2", lam, beta, eta),
aging_component("C3", lam, beta, eta))
S = System()
S["E"] = c1
S[c1] = c2
S[c2] = c3
S[c3] = "S"
return S
def build_parallel3(lam, beta, eta):
c1, c2, c3 = (aging_component("C1", lam, beta, eta),
aging_component("C2", lam, beta, eta),
aging_component("C3", lam, beta, eta))
S = System()
S["E"] = [c1, c2, c3]
S[c1] = S[c2] = S[c3] = "S"
return S
def build_series_parallel_3stages(lam, beta, eta):
A1, A2 = aging_component("A1", lam, beta, eta), aging_component("A2", lam, beta, eta)
B1, B2 = aging_component("B1", lam, beta, eta), aging_component("B2", lam, beta, eta)
C1, C2 = aging_component("C1", lam, beta, eta), aging_component("C2", lam, beta, eta)
S = System()
S["E"] = [A1, A2]
S[A1] = S[A2] = "N1"
S["N1"] = [B1, B2]
S[B1] = S[B2] = "N2"
S["N2"] = [C1, C2]
S[C1] = S[C2] = "S"
return S
def build_parallel_series_3branches(lam, beta, eta):
A1, A2 = aging_component("A1", lam, beta, eta), aging_component("A2", lam, beta, eta)
B1, B2 = aging_component("B1", lam, beta, eta), aging_component("B2", lam, beta, eta)
C1, C2 = aging_component("C1", lam, beta, eta), aging_component("C2", lam, beta, eta)
S = System()
S["E"] = [A1, B1, C1]
S[A1] = A2
S[A2] = "S"
S[B1] = B2
S[B2] = "S"
S[C1] = C2
S[C2] = "S"
return S
def build_voter_2of3(lam, beta, eta):
base = aging_component("C", lam, beta, eta)
return Voter(base, M=2, N=3)
ARCH_BUILDERS = {
"Series (3)": build_series3,
"Parallel (3)": build_parallel3,
"Series–Parallel (3 stages)": build_series_parallel_3stages,
"Parallel–Series (3 branches)": build_parallel_series_3branches,
"Voter 2-out-of-3": build_voter_2of3,
}
T = np.linspace(0, 3.0 / lam0, 250)
mttf = {}
R_curves = {}
for name, builder in ARCH_BUILDERS.items():
obj = builder(lam0, beta, eta0)
m, R = obj.monte_carlo(n=50000, grid_t=T, seed=42)
mttf[name] = m
R_curves[name] = R
plt.figure()
plt.bar(list(mttf.keys()), list(mttf.values()))
plt.xticks(rotation=25, ha="right")
plt.ylabel("MTTF (Monte Carlo)")
plt.title("MTTF by architecture")
plt.tight_layout()
plt.show()
plt.figure()
for name, R in R_curves.items():
plt.plot(T, R, label=name)
plt.xlabel("Time t")
plt.ylabel("Reliability R(t)")
plt.ylim(0, 1.02)
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
Installation
pip install fiabilipym
Tests
Install test dependencies (editable install):
pip install -e ".[test]"
Run with pytest:
pytest -q
Run with unittest discovery:
python -m unittest discover -s tests
Equivalent uv-based commands:
uv run --extra test pytest -q
Alternative (stdlib unittest):
PYTHONPATH=src uv run python -m unittest discover -s tests
Package structure
fiabilipym/
├── changes.md
├── pyproject.toml
├── setup.py
├── README.md
├── src/
│ └── fiabilipym/
│ ├── __init__.py
│ ├── component.py
│ ├── distribution.py
│ ├── markov.py
│ ├── system.py
│ └── voter.py
├── fiabilipym_weibull_montecarlo_demo.ipynb
└── tests/
├── test_markov.py
├── test_system.py
├── test_monte_carlo_systems.py
└── test_voter_monte_carlo.py
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fiabilipym-2.0.1.tar.gz.
File metadata
- Download URL: fiabilipym-2.0.1.tar.gz
- Upload date:
- Size: 22.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11b64e5ebb371e66542d7f9d4d36c2ff45615081cf9e2410ab8ea15decb5ba72
|
|
| MD5 |
ee3013bea4ea6c562f44aac4f75c4920
|
|
| BLAKE2b-256 |
2af94f2e0947a6856467ed7c8d533024b2565ef337525264353fe749512fab20
|
File details
Details for the file fiabilipym-2.0.1-py3-none-any.whl.
File metadata
- Download URL: fiabilipym-2.0.1-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ca126b5d7ad13d8da54c51c029df1160b3d312bdc0dc86b4a61aa5dc457c4c0
|
|
| MD5 |
adca7433ada1d5b88fad70e0a8c941b7
|
|
| BLAKE2b-256 |
7757892e4af68c77c0f4f6850fe3ed8c61c7ecc793e3ed9c0cc42901b70f2863
|