Skip to content

Demonstration testing

A demonstration test shows, at a confidence level, that a design meets a reliability target. You test n units and allow up to failures of them to fail; if no more fail, the design has demonstrated the target. These functions plan such a test from the target, and say what a finished test demonstrated. They fit nothing: surpyval fits the data a test produces.

How many units?

A unit passes if it survives the mission time. With no failures allowed, n units demonstrate a reliability R at confidence C when R ** n ≤ 1 − C: were the reliability only R, so many successes in a row would be that unlikely. This is the success run:

from repyability import demonstrated_reliability, demonstration_sample_size

demonstration_sample_size(0.95, confidence=0.95)              # -> 59
demonstration_sample_size(0.95, confidence=0.95, failures=1)  # -> 93
demonstrated_reliability(59, confidence=0.95)                 # -> 0.9505

Allowing failures keeps one unlucky unit from failing a good design, at the cost of more units. With failures allowed, the plan is the smallest n for which that many failures or fewer have a chance of at most 1 − C at the target (the binomial distribution). demonstrated_reliability gives the reliability a finished test demonstrated: the Clopper–Pearson lower bound, which with no failures is surpyval's success_run.

Testing longer instead: Weibayes

When the lifetime's Weibull shape β is known, from past data or the failure mode, each unit can run for k missions instead of one. A unit that survives k missions survives one with reliability R when its reliability over the test is R ** (k ** β), so fewer units are needed:

from repyability import demonstration_test_multiple

demonstration_sample_size(0.95, 0.95, test_multiple=2.0, shape=2.0)   # -> 15
demonstration_test_multiple(0.95, 20, 0.95, shape=2.0)                # -> 1.709

demonstration_test_multiple answers the other way round: how many missions each of a given number of units must run. For wear-out (β > 1) a longer test pays off quickly; at β = 1 test time and units trade one for one; for early failures (β < 1) a longer test saves few units.

Constant failure rate: test time for an MTBF

When the failure rate does not change with age, it is the total unit time that counts, however it is spread over the units, and failed units can be repaired or replaced and the test carried on. A test of total time T that ends with at most r failures demonstrates an MTBF θ at confidence C when T ≥ θ χ²(C; 2r + 2) / 2:

from repyability import demonstrated_mtbf, mtbf_test_time

mtbf_test_time(1000.0, confidence=0.9)               # -> 2302.6
mtbf_test_time(1000.0, confidence=0.9, failures=2)   # -> 5322.3
demonstrated_mtbf(2302.6, confidence=0.9)            # -> 1000.0

What a plan risks

A plan's operating characteristic is the chance that a design passes it, given the design's true reliability. At the target it is at most 1 − C: the consumer's risk of accepting a design no better than the target. For a good design, one minus it is the producer's risk of rejecting it:

from repyability import demonstration_pass_probability, mtbf_pass_probability

demonstration_pass_probability(0.95, 59)               # -> 0.0485   at the target
demonstration_pass_probability(0.99, 59)               # -> 0.5527   a much better design
demonstration_pass_probability(0.99, 93, failures=1)   # -> 0.7616   the same, allowing a failure
mtbf_pass_probability(3000.0, 2302.6)                  # -> 0.4642   three times the MTBF

A test that allows no failures often fails a good design: the one above would reject a design of 99% reliability 45% of the time. Allowing a failure, with the more units that needs, cuts that to 24%.

Plans that keep both risks

demonstration_plan and mtbf_demonstration_plan design the test from both risks at once (#184): the smallest test that a design at the target passes with a chance of at most 1 − confidence, and that a good design, which should pass, fails with a chance of at most producer_risk:

from repyability import demonstration_plan, mtbf_demonstration_plan

plan = demonstration_plan(0.9, 0.95, confidence=0.9, producer_risk=0.2)
plan.n, plan.failures            # (128, 8)   128 units, at most 8 failing
plan.consumer_risk               # -> 0.097   a design at 90% passes
plan.producer_risk               # -> 0.192   one at 95% fails
demonstration_pass_probability(0.95, 22)   # -> 0.324   the success run of 22 units passes it a third of the time
mtbf = mtbf_demonstration_plan(1000.0, 2000.0, confidence=0.9, producer_risk=0.2)
mtbf.test_time, mtbf.failures    # about 14,206 unit hours, at most 9 failures
mtbf.test_time                   # -> 14206

For each number of failures allowed, from none, the fewest units (or the least test time) that keep the consumer's risk pass a good design most often; the first that keeps the producer's risk too is the smallest plan of all. A good design close to the target needs many failures allowed, and many units: the closer, the more. Given n= and the lifetime's shape, demonstration_plan searches the test length instead, and with test_multiple and shape, it plans an extended (Weibayes) test of that length. The MTBF plans are MIL-HDBK-781's fixed-length plans, for a discrimination ratio good_mtbf / mtbf; the handbook lets some of its plans exceed a risk a little for a shorter test, where these keep both. The result is a DemonstrationPlan.