StepSequence.java
/*
* License : The MIT License
* Copyright(c) 2022 olyutorskii
*/
package io.github.olyutorskii.aletojio.rng.dull;
import io.github.olyutorskii.aletojio.rng.RndInt32;
/**
* Step progression sequence generator.
*
* <p>{@code X(n) = start + step * n}
*
* <p>If a suitable step is selected,
* it can be compromised as a quasi-random number generator.
*
* <p>Using large prime numbers other than 2 for step would give a long period.
*
* <p>{@link Integer#MAX_VALUE} is followed by {@link Integer#MIN_VALUE}.
*
* @see <a href="https://en.wikipedia.org/wiki/Low-discrepancy_sequence">
* Low-discrepancy sequence (Wikipedia)
* </a>
*/
public class StepSequence implements RndInt32 {
/**
* Prime number near equal golden ratio of Integer.MAX.
*
* <p>Using this number for step yields sparse results
* that are hard to approximate with rational numbers.
*
* <p>Ref : Integer.MAX * (3-SQRT(5)) = 1640531525
*
* @see <a href="https://en.wikipedia.org/wiki/Golden_ratio">Golden ratio (Wikipedia)</a>
* @see <a href="https://en.wikipedia.org/wiki/Low-discrepancy_sequence">
* Low-discrepancy sequence (Wikipedia)
* </a>
*/
public static final int PRIME_STEP = 1642716433;
private final int step;
private int next;
/**
* Constructor.
*
* <p>output sequence will be {start, start+step, start+step*2, start+step*3, ...}
*
* <p>Overflow is ignored.
*
* @param start start value
* @param step step value
*/
public StepSequence(int start, int step) {
super();
this.next = start;
this.step = step;
return;
}
/**
* Create simple counter.
*
* <p>{0, 1, 2, ...}
*
* @return counter
*/
public static StepSequence createCounter() {
StepSequence result = new StepSequence(0, 1);
return result;
}
/**
* Create Quasi-random generator.
*
* <p>Quasi-random generator outputs extremely uniform random numbers.
*
* @return random generator
* @see <a href="https://en.wikipedia.org/wiki/Low-discrepancy_sequence">
* Low-discrepancy sequence (Wikipedia)
* </a>
*/
public static StepSequence createQuasiRandom() {
StepSequence result = new StepSequence(PRIME_STEP, PRIME_STEP);
return result;
}
/**
* {@inheritDoc}
*
* @return {@inheritDoc}
*/
@Override
public int nextInt32() {
int result = this.next;
this.next += this.step;
return result;
}
}