Voss
1
The Voss
driver produces sequences which reputedly emulate
1/f noise. Each sample value is the sum of
N sample-and-hold streams, where N is
a user-selected parameter implemented as Voss.depth
.
The decision of whether a given stream should sample (obtain a new value from
java.util.Random.nextDouble()
) or hold (retain the
previous stream value) happens for every sample in stream 0, for every other sample in stream 1, for every third sample in stream 2, and
for every k+1st sample for stream k.
The Voss process is one of several approaches to generating sequences which
exert control over distances between consecutive samples. Others include
Brownian
and
Rosy
.
Figure 1 illustrates Voss
output with five sequences of
200 samples generated with varying sample-and-hold stream counts.
Voss.next()
. For each row
of graphs, the leftward graph displays samples in time-series while the rightward graph presents a histogram analyzed from the same samples.
The vertical x axes for both graphs represent the driver domain from zero to unity; the horizontal k axis of the time-series graph (left) plots ordinal sequence numbers; the horizontal f(x) axis of the histogram (right) plots the relative concentration of samples at each point in the driver domain.
Probability theory has an insight called the Central Limit Theorem which asserts that as N increases, adding together N random variables with mean μ and deviation σ will produce a bell curve centered around Nμ with deviation √Nσ. Since the held samples in one stream range uniformly from zero to unity, each stream has mean μ = 0.5 and deviation σ = √12 = 0.29. Since the sequences in Figure 1 present the average of all sample-and-hold streams, the bell curve will be centered around Nμ/N = μ = 0.5 and its the deviation around this center will be √Nσ/N = σ/√N = 0.29/√N.
The limiting case of depth = 1
is standard randomness of Lehmer
.
As depth
increases, values cluster ever-more closely around 0.5, converging ultimately to a flat line.
Figure 2 takes the sequence shown in the second row Figure 1 and breaks out what happens in bit 1 (zero or one-half), bit 2 (zero or one-quarter), bit 3 (zero or one-eighth), bit 4 (zero or one-sixteenth), and the residual bits (continuous between zero and one-sixteenth).
Voss.next()
for depth = 5
.
The bit-specific graphs in Figure 2 transition back and forth between a set state (bit value 1) and a clear state (bit value 0).
Table 1 statistically analyses
of sample the actual stats for these bit-specific graphs. By comparison with the equivalent table for the
Lehmer
driver, probability has shifted
away from single samples between transitions toward multiple samples between transitions.
Transitions | 1 Sample | 2 Samples | 3 Samples | 4 Samples | 5 or more | |
---|---|---|---|---|---|---|
Actual Bit 1 | 61 | 26% | 27% | 16% | 6% | 22% |
Actual Bit 2 | 73 | 28% | 30% | 19% | 4% | 13% |
Actual Bit 3 | 86 | 38% | 20% | 10% | 8% | 11% |
Actual Bit 4 | 99 | 49% | 21% | 13% | 12% | 4% |
Figures 3 (a) through 3 (d) plot the range of sample-to-sample differences along the vertical Δx axis against the relative concentrations of these values along the horizontal f(Δx) axis.
Table 2 compares depth parameter settings with measured deviations for Δx around zero.
Graph | Parametric Depth Setting | Actual Sample-to-Sample Deviation |
---|---|---|
Figure 3 (a) | 3 | 0.185 |
Figure 3 (b) | 5 | 0.125 |
Figure 3 (c) | 8 | 0.0774 |
Figure 3 (d) | 13 | 0.0523 |
Figure 4 presents a trend graph of histogram tallies for 4-nibble patterns generated using
Voss.next()
with
depth = 5
. The most frequent patterns were:
8 | 8 | 8 | 8 |
7 | 7 | 7 | 7 |
8 | 8 | 7 | 7 |
7 | 7 | 8 | 8 |
All of which had comparable tallies representing less than 1% presence. The distinguishing feature of these patterns is that they concentrate in the middle 2/16ths of the driver range.
The conclusion from Figure 4 is that the Brownian
driver
fails the 4-nibble independence test.
Voss
implementation class.
The type hierarchy for Voss
is:
DriverBase
extends WriteableEntity
implements Driver
Voss
extends DriverBase
Listing 1 provides the source code for the Voss
class. The sequential process described at the top of this page is implemented by
generate()
, which is not public facing. Instead,
generate()
is
called by DriverBase.next()
.
DriverBase
.next() also
takes care to store the new sample in the field
DriverBase
.value, where
generate()
can employ
DriverBase.getValue()
to pick this
(now previous) sample up for the next sample iteration.
DriverBase
also offers
setValue()
and randomizeValue()
methods to establish the initial sequence value.
© Charles Ames | Page created: 2022-08-29 | Last updated: 2022-08-30 |