Package squidpony.squidmath
Class TweakRNG
java.lang.Object
squidpony.squidmath.AbstractRNG
squidpony.squidmath.TweakRNG
- All Implemented Interfaces:
Serializable
,IRNG
,RandomnessSource
public class TweakRNG extends AbstractRNG implements Serializable
Somewhat experimental RNG that can be configured to smoothly transition between producing mostly values in the
center of its range, to producing more values at or near the extremes, as well as favoring high or low results.
The probability distribution is... unusual, with lumps that rise or fall based on centrality.
Even though this is experimental, it's still usable. Mostly the useful parts of this relate to changing centrality, making results occur more or less frequently in the center of the output range. You can also change the "favor" to bias results towards higher or lower parts of the same output range, though if favor is non-zero it may have counterintuitive results for
Internally, this acts as a
Here's an animation of the distribution graph changing.
Created by Tommy Ettinger on 10/6/2019.
Even though this is experimental, it's still usable. Mostly the useful parts of this relate to changing centrality, making results occur more or less frequently in the center of the output range. You can also change the "favor" to bias results towards higher or lower parts of the same output range, though if favor is non-zero it may have counterintuitive results for
nextLong()
.
Internally, this acts as a
TangleRNG
, which is a fairly solid, very fast algorithm, and uses its results two
at a time to give to an atan2 calculation (specifically, NumberTools.atan2_(float, float)
or
NumberTools.atan2_(double, double)
. These particular approximations of atan2 range from 0.0 to 1.0 instead of
-pi to pi. This means atan2 inputs with positive x and small y are likely to return values near 1.0 or near 0.0, but
not between 0.25 and 0.75. The opposite is true for inputs with negative x and small y; that is likely to be near 0.5
and can't be between 0.0 and 0.25 or between 0.75 and 1.0. TweakRNG uses this property to implement centrality,
changing the inputs to its internal atan2 usage so x is positive when centrality is positive, or negative when
centrality is negative. Likewise, favor is implemented by changing y, though reversed; positive favor makes the atan2
calculation adjusted with negative y, making it more likely to be between 0.5 and 1.0, while negative favor pushes it
back to between 0.0 and 0.5.
Here's an animation of the distribution graph changing.
Created by Tommy Ettinger on 10/6/2019.
- See Also:
- Serialized Form
-
Constructor Summary
-
Method Summary
Modifier and Type Method Description TweakRNG
copy()
Creates a copy of this IRNG; it will generate the same random numbers, given the same calls in order, as this IRNG at the point copy() is called.long
getCentrality()
long
getFavor()
long
getStateA()
long
getStateB()
int
next(int bits)
Get up to 32 bits (inclusive) of random output; the int this produces will not require more thanbits
bits to represent.boolean
nextBoolean()
Get a random bit of state, interpreted as true or false with approximately equal likelihood.double
nextDouble()
Gets a random double between 0.0 inclusive and 1.0 exclusive.float
nextFloat()
Gets a random float between 0.0f inclusive and 1.0f exclusive.int
nextInt()
Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).long
nextLong()
Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).void
setCentrality(long centrality)
Adjusts the central bias of this TweakRNG, often to positive numbers (which bias toward the center of the range), but also often to negative numbers (which bias toward extreme values, though still within the range).void
setFavor(long favor)
Adjusts the value bias of this TweakRNG, often to positive numbers (which bias toward higher results), but also often to negative numbers (which bias toward lower results).void
setStateA(long stateA)
void
setStateB(long stateB)
Serializable
toSerializable()
Gets a view of this IRNG in a way that implementsSerializable
, which may simply be this IRNG if it implements Serializable as well as IRNG.Methods inherited from class squidpony.squidmath.AbstractRNG
between, between, between, getRandomElement, getRandomElement, getRandomElement, nextDouble, nextFloat, nextInt, nextLong, nextSignedInt, nextSignedLong, randomOrdering, randomOrdering, randomPortion, shuffle, shuffle, shuffle, shuffle, shuffleInPlace, shuffleInPlace, swap
-
Constructor Details
-
Method Details
-
next
Description copied from class:AbstractRNG
Get up to 32 bits (inclusive) of random output; the int this produces will not require more thanbits
bits to represent.- Specified by:
next
in interfaceIRNG
- Specified by:
next
in interfaceRandomnessSource
- Specified by:
next
in classAbstractRNG
- Parameters:
bits
- an int between 1 and 32, both inclusive- Returns:
- a random number that fits in the specified number of bits
-
nextInt
Description copied from class:AbstractRNG
Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).- Specified by:
nextInt
in interfaceIRNG
- Specified by:
nextInt
in classAbstractRNG
- Returns:
- a 32-bit random int.
-
nextLong
Description copied from class:AbstractRNG
Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).- Specified by:
nextLong
in interfaceIRNG
- Specified by:
nextLong
in interfaceRandomnessSource
- Specified by:
nextLong
in classAbstractRNG
- Returns:
- a 64-bit random long.
-
nextBoolean
Description copied from class:AbstractRNG
Get a random bit of state, interpreted as true or false with approximately equal likelihood.
Note: This is abstract because some implementations may be best served by usingAbstractRNG.next(int)
to get 1 bit, returningnext(1) == 1
, but others will get much better results with a sign check by calling their choice ofAbstractRNG.nextInt()
orAbstractRNG.nextLong()
and returningnextInt() < 0
ornextLong < 0L
. For example, an implementation that uses a linear congruential generator without truncating some lower bits will have very-low-period results for the bottom bit (alternating true and false), but perfectly fine results from a sign check. There are tested issues on the bottom (at least 2) bits ofXoRoRNG
, but again not on a sign check.- Specified by:
nextBoolean
in interfaceIRNG
- Specified by:
nextBoolean
in classAbstractRNG
- Returns:
- a random boolean.
-
nextDouble
Description copied from class:AbstractRNG
Gets a random double between 0.0 inclusive and 1.0 exclusive. This returns a maximum of 0.9999999999999999 because that is the largest double value that is less than 1.0 .
This is abstract because some generators may natively work with double or float values, but others may need to convert a long to a double as with(nextLong() & 0x1fffffffffffffL) * 0x1p-53
, which is recommended if longs are fast to produce.- Specified by:
nextDouble
in interfaceIRNG
- Specified by:
nextDouble
in classAbstractRNG
- Returns:
- a double between 0.0 (inclusive) and 0.9999999999999999 (inclusive)
-
nextFloat
Description copied from class:AbstractRNG
Gets a random float between 0.0f inclusive and 1.0f exclusive. This returns a maximum of 0.99999994 because that is the largest float value that is less than 1.0f .
This is abstract because some generators may natively work with double or float values, but others may need to convert an int or long to a float as with(nextInt() & 0xffffff) * 0x1p-24f
,(nextLong() & 0xffffffL) * 0x1p-24f
, ornext(24) * 0x1p-24f
, any of which can work when the method they call is high-quality and fast. You probably would want to use nextInt() or next() if your implementation is natively 32-bit and is slower at producing longs, for example.- Specified by:
nextFloat
in interfaceIRNG
- Specified by:
nextFloat
in classAbstractRNG
- Returns:
- a float between 0f (inclusive) and 0.99999994f (inclusive)
-
copy
Description copied from class:AbstractRNG
Creates a copy of this IRNG; it will generate the same random numbers, given the same calls in order, as this IRNG at the point copy() is called. The copy will not share references with this IRNG. If this IRNG does not permit copying itself, it is suggested to either throw anUnsupportedOperationException
or return a new IRNG of the same type but with a random seed, with the latter meant as a partial defense against cheating.
This is abstract because every implementation is likely to have different specifics for this.- Specified by:
copy
in interfaceIRNG
- Specified by:
copy
in interfaceRandomnessSource
- Specified by:
copy
in classAbstractRNG
- Returns:
- a copy of this IRNG
-
toSerializable
Description copied from class:AbstractRNG
Gets a view of this IRNG in a way that implementsSerializable
, which may simply be this IRNG if it implements Serializable as well as IRNG.
For implementors: It is suggested to return anRNG
initialized by callingRNG(long)
withAbstractRNG.nextLong()
if you are unable to save the current state of this IRNG and the caller still needs something saved. This won't preserve the current state or the choice of IRNG implementation, however, so it is simply a last resort in case you don't want to throw an exception.- Specified by:
toSerializable
in interfaceIRNG
- Specified by:
toSerializable
in classAbstractRNG
- Returns:
- a
Serializable
view of this IRNG or a similar one; may bethis
-
getStateA
-
setStateA
-
getStateB
-
setStateB
-
getCentrality
-
setCentrality
Adjusts the central bias of this TweakRNG, often to positive numbers (which bias toward the center of the range), but also often to negative numbers (which bias toward extreme values, though still within the range).- Parameters:
centrality
- should be between -65535 and 65535; positive values bias toward the center of the range
-
getFavor
-
setFavor
Adjusts the value bias of this TweakRNG, often to positive numbers (which bias toward higher results), but also often to negative numbers (which bias toward lower results). All results will still be in their normal range, but will change how often high or low values occur. Unusual results will occur if favor is non-zero and you get a long withnextLong()
; in that case, the values are treated as higher when unsigned, so positive favor makes both high positive values and all negative values more common. Doubles and floats will behave normally.- Parameters:
favor
- should be between -65535 and 65535; positive values bias toward higher (unsigned for longs) results
-