Skip to contents

Runs a 'PractRand' battery on the bits from source, reporting results at doubling lengths from min_bytes to max_bytes, as PractRand's RNG_test does.

Usage

pract_test(
  source,
  battery = c("core", "expanded"),
  min_bytes = 2^20,
  max_bytes = 2^34,
  stop_on_failure = TRUE,
  folding = TRUE,
  seed = NULL
)

Arguments

source

A source of bits, from pract_raw(), pract_fun(), pract_rng() or pract_interleave().

battery

The 'PractRand' battery: "core", the recommended set of tests, or "expanded", a wider and slower set.

min_bytes, max_bytes

The shortest and longest lengths tested, in bytes: powers of two of at least 1024.

stop_on_failure

If TRUE, stop at the first length where the source fails.

folding

If TRUE, also run the tests on PractRand's standard foldings of the data (for example its low bits), by the source's word size.

seed

The seed of the generator PractRand uses inside some tests, a whole number from 0 to 2^53 - 1. NULL uses 0, so runs are reproducible.

Value

A data frame of class zurngtest_result, with one row per test result at each length: bytes (the length), test (the test name), p_value and evaluation (PractRand's label). Its attributes are failed_at, the first length with a failure or NA; stopped, why the run ended before max_bytes without a failure ("source" when the source ended, "interrupt" or "practrand") or NA; source, a description of the source; and elapsed, the run time in seconds.

Details

Each test result is evaluated with PractRand's own labels and thresholds, as its RNG_test evaluates them; see the Evaluations section. A source has failed at the first length with any result labelled "FAIL".

Evaluations

'PractRand' scores each result in decimal digits: about \(\log_{10}(1/p)\) for its p-value \(p\), less \(\log_{10}(1/w)\) for its share \(w\) of the weight of all the results, so the more results a run has, the more improbable one must be to stand out. With 100 equally weighted results, a p-value of \(10^{-5}\) scores about 3. The labels, by score, are:

ScoreEvaluation
0normal
above 0normalish
above 1unusual
above 2mildly suspicious
above 3suspicious
above 4very suspicious
above 6VERY SUSPICIOUS
above 8.5FAIL
above 12, 17, 25, 45, 85, 165, 325, 999FAIL ! to FAIL !!!!!!!!

"unusual" results are expected now and then in a long run of a good generator; a "FAIL" is not.

A result with no valid p-value has NA for p_value and evaluation, and is left out of the evaluation of the others. 'PractRand' 0.96's expanded battery gives such results from its NS3 tests even on good input; RNG_test stops on them.

A source that ends early (a raw vector or connection with fewer bytes than max_bytes) ends the run: the last rows are at the number of bytes tested, rounded down to a whole kilobyte. If it ends before min_bytes, that is an error. An interrupt also ends the run, and returns the results of the lengths completed before it, as does an error raised by PractRand itself, which the NS3 tests of the expanded battery can raise on heavily failing input; both are reported in a warning of class zurngtest_stopped. Any other error, such as a failed allocation, is an error. The result's stopped attribute says why a run ended early.

Examples

# A repeating pattern fails at once
pattern <- pract_raw(rep(as.raw(0:255), 2^8))
pract_test(pattern, min_bytes = 2^16, max_bytes = 2^16)
#> PractRand 0.96 test of raw vector of 65536 bytes
#> length= 64 kilobytes (2^16 bytes)
#>   Test Name                         p-value       Evaluation
#>   BCFN(2+0,13-9U)                    0.00e+00     FAIL !!!!!!!
#>   BCFN(2+1,13-9U)                    0.00e+00     FAIL !!!!!!!
#>   BCFN(2+2,13-9U)                   1.87e-244     FAIL !!!!!!
#>   DC6-9x1Bytes-1                     0.00e+00     FAIL !!!!!!!!
#>   Gap-16:A                           0.00e+00     FAIL !!!!!!!!
#>   Gap-16:B                           0.00e+00     FAIL !!!!!!!!
#>   Gap-16:C                           1.00e+00     FAIL !!!!!!
#>   FPF/16:(1,14-8)                    1.00e+00     very suspicious
#>   FPF/16:(2,14-8)                    0.00e+00     FAIL !!!!!!!!
#>   FPF/16:(3,14-9)                    0.00e+00     FAIL !!!!!!!
#>   FPF/16:(4,14-10)                   0.00e+00     FAIL !!!!!!!
#>   FPF/16:(5,14-11)                  1.53e-233     FAIL !!!!!!
#>   FPF/16:(6,14-11)                  1.53e-233     FAIL !!!!!!
#>   FPF/16:all                         0.00e+00     FAIL !!!!!!!!
#>   FPF/16:cross                       0.00e+00     FAIL !!!!!!!!
#>   BDayS2(4,24)[18]                  6.01e-200     FAIL !!!!!!
#>   BRank(12):score:64(7)              1.00e+00     FAIL !!!!!!!!
#>   mod3n(5):(0,9-6)                   0.00e+00     FAIL !!!!!!!
#>   mod3n(5):(1,9-6)                   0.00e+00     FAIL !!!!!!!
#>   mod3n(5):(2,9-6)                  7.09e-218     FAIL !!!!!!
#>   mod3n(5):(3,9-6)                  4.43e-102     FAIL !!!!!
#>   [Low1/8]BCFN(2+0,13-9U)            0.00e+00     FAIL !!!!!!!
#>   [Low1/8]DC6-9x1Bytes-1             0.00e+00     FAIL !!!!!!!!
#>   [Low1/8]Gap-16:A                   0.00e+00     FAIL !!!!!!!!
#>   [Low1/8]Gap-16:B                   0.00e+00     FAIL !!!!!!!!
#>   [Low1/8]Gap-16:C                   1.00e+00     FAIL !!!!!
#>   [Low1/8]FPF/16:(1,14-10)           0.00e+00     FAIL !!!!!!!!
#>   [Low1/8]FPF/16:all                 0.00e+00     FAIL !!!!!!!!
#>   [Low1/8]FPF/16:cross               0.00e+00     FAIL !!!!!!!!
#>   [Low1/8]mod3n(5):(0,9-6)           0.00e+00     FAIL !!!!!!!
#>   [Low1/8]mod3n(5):(1,9-6)          8.40e-217     FAIL !!!!!!
#>   [Low1/8]mod3n(5):(2,9-6)          3.13e-106     FAIL !!!!!
#>   [Low4/32]BCFN(2+0,13-9U)           0.00e+00     FAIL !!!!!!!
#>   [Low4/32]DC6-9x1Bytes-1            0.00e+00     FAIL !!!!!!!!
#>   [Low4/32]Gap-16:A                  0.00e+00     FAIL !!!!!!!!
#>   [Low4/32]Gap-16:B                  0.00e+00     FAIL !!!!!!!!
#>   [Low4/32]Gap-16:C                  1.00e+00     FAIL !!!!!
#>   [Low4/32]FPF/16:cross              0.00e+00     FAIL !!!!!!!!
#>   [Low4/32]mod3n(5):(0,9-6)          0.00e+00     FAIL !!!!!!!
#>   [Low4/32]mod3n(5):(1,9-6)         8.57e-217     FAIL !!!!!!
#>   [Low4/32]mod3n(5):(2,9-6)         3.13e-106     FAIL !!!!!
#>   [Low1/32]DC6-9x1Bytes-1            0.00e+00     FAIL !!!!!!!
#>   [Low1/32]FPF/16:cross              0.00e+00     FAIL !!!!!!!!
#>   [Low1/32]mod3n(5):(0,9-6)          0.00e+00     FAIL !!!!!!!
#>   [Low1/32]mod3n(5):(1,9-6)         8.57e-217     FAIL !!!!!!
#>   [Low1/32]mod3n(5):(2,9-6)         3.13e-106     FAIL !!!!!
#> Failed at 64 kilobytes (2^16 bytes), time= 0.2 seconds

# R's own generator, as bytes
bytes <- pract_fun(
  function(n) as.raw(sample.int(256L, n, replace = TRUE) - 1L),
  bits = 8
)
pract_test(bytes, min_bytes = 2^16, max_bytes = 2^17)
#> PractRand 0.96 test of function function(n) as.raw(sample.int(256L, n, replace = TRUE) - 1L), 8-bit words
#> length= 64 kilobytes (2^16 bytes)
#>   no anomalies in 36 test result(s)
#> length= 128 kilobytes (2^17 bytes)
#>   no anomalies in 42 test result(s)
#> No failure, time= 0.2 seconds