.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/reliability/lifetimes/plot_04_epstein_sobel_life_testing.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_reliability_lifetimes_plot_04_epstein_sobel_life_testing.py: Epstein and Sobel's exponential life testing (1953) =================================================== How long must a test run, and with how many units, to demonstrate an MTBF? Epstein and Sobel (1953) showed that for exponential lives the *total time on test* :math:`T`, summed over failed and surviving units, carries all the information: :math:`\hat\theta = T/r` after :math:`r` failures, and :math:`2T/\theta` is chi-square with :math:`2r` degrees of freedom. That gives exact confidence bounds (:func:`~engineeringkit.reliability.mtbf_confidence_bounds`). The example stops a test of 12 units at the fourth failure, many times over, and checks that the 90% bounds catch the true MTBF 90% of the time. .. GENERATED FROM PYTHON SOURCE LINES 17-22 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from engineeringkit.reliability import exponential_mttf, exponential_reliability, failure_rate_from_mtbf, mtbf_confidence_bounds .. GENERATED FROM PYTHON SOURCE LINES 23-29 One test -------- Components with a failure rate of :math:`2\times10^{-4}` per hour (time unit: hours). Twelve go on test; the test stops at the fourth failure, so eight units are still running. .. GENERATED FROM PYTHON SOURCE LINES 29-41 .. code-block:: Python lam = 2e-4 theta = exponential_mttf(lam) n, r = 12, 4 rng = np.random.default_rng(1953) life = np.sort(rng.exponential(theta, n)) total = life[:r].sum() + (n - r) * life[r - 1] low, high = mtbf_confidence_bounds(total, r, confidence=0.9) print(f"test stopped at {life[r - 1]:.0f} h, total time on test {total:.0f} h") print(f"MTBF estimate {total / r:.0f} h, 90% bounds [{low:.0f}, {high:.0f}] h (true {theta:.0f} h)") print(f"estimated failure rate {failure_rate_from_mtbf(total / r):.2e}/h") .. rst-class:: sphx-glr-script-out .. code-block:: none test stopped at 2502 h, total time on test 23477 h MTBF estimate 5869 h, 90% bounds [3028, 17183] h (true 5000 h) estimated failure rate 1.70e-04/h .. GENERATED FROM PYTHON SOURCE LINES 42-44 Repeat the test 300 times ------------------------- .. GENERATED FROM PYTHON SOURCE LINES 44-69 .. code-block:: Python tests = 300 bounds = [] for _ in range(tests): life = np.sort(rng.exponential(theta, n)) bounds.append(mtbf_confidence_bounds(life[:r].sum() + (n - r) * life[r - 1], r, 0.9)) bounds = np.array(bounds) covered = (bounds[:, 0] <= theta) & (theta <= bounds[:, 1]) print(f"intervals containing the true MTBF: {covered.mean():.1%}") fig, axes = plt.subplots(1, 2, figsize=(9.5, 3.8)) show = np.arange(60) axes[0].vlines(show, bounds[show, 0], bounds[show, 1], colors=np.where(covered[show], "C0", "C3")) axes[0].axhline(theta, color="k", lw=1) axes[0].set(yscale="log", xlabel="test", ylabel="MTBF [h]", title="90% bounds, 60 of the tests") t = np.linspace(0, 3 * theta, 200) axes[1].plot(t, exponential_reliability(t, lam), label="true") axes[1].fill_between(t, exponential_reliability(t, 1 / low), exponential_reliability(t, 1 / high), alpha=0.3, label="90% band, first test") axes[1].set(xlabel="time [h]", ylabel="reliability") axes[1].legend() fig.tight_layout() assert abs(covered.mean() - 0.9) < 0.05 plt.show() .. image-sg:: /api/gallery/reliability/lifetimes/images/sphx_glr_plot_04_epstein_sobel_life_testing_001.png :alt: 90% bounds, 60 of the tests :srcset: /api/gallery/reliability/lifetimes/images/sphx_glr_plot_04_epstein_sobel_life_testing_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none intervals containing the true MTBF: 90.0% .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.071 seconds) .. _sphx_glr_download_api_gallery_reliability_lifetimes_plot_04_epstein_sobel_life_testing.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/reliability/lifetimes/plot_04_epstein_sobel_life_testing.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_04_epstein_sobel_life_testing.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_04_epstein_sobel_life_testing.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_04_epstein_sobel_life_testing.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_