You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
public TFloat NextDistinct(TFloat other) {
var minInterval = CalculateMinInterval(other);
var value = this.Next();
if (Math.Abs(value - other) < minInterval) {
// In the event that the generated value is within +/- minimum interval of the
// original, round it up or down to either other + minInterval or other - minInterval
if (other <= this.High - minInterval) {
if (other >= this.Low + minInterval) {
return value > other ?
other + minInterval :
other - minInterval;
} else {
return other + minInterval;
}
} else {
return other - minInterval;
}
} else {
return value;
}
}
This guarantees that the newly generated value is outside of the minimum interval required to be considered distinct based upon the generator's precision, but it has two flaws:
If the precision is weak enough and the range is small enough, the generator will dutifully generate values outside of the range of this.Low and this.High instead of throw an UnableToGenerateException. An example could be a precision of 0.1 on a range from 0.0 to 0.1.
The values between 1 minimum intervals away from the other value are more likely to be returned, as any generated value between 0 and 1 minimum intervals away from the other value are instead pushed ignored in favor of the minimum interval. If the precision is weak enough and the range is small enough (say 0.01 precision for a range of 0.00 to 1.00 for percentages), this bias is noticeable, though mostly harmless.
This aren't causing any major problems downstream, but there certainly two things that could be improved. Item (1) is a simple boundary check in the constructor, but (2) is trickier because the minimum interval differs if you're using significant figures for precision.
When I brought this issue up with @sflanker, he had an idea expressed this way:
public TFloat NextDistinct(TFloat other) {
var current = this.Next(this.Low, this.High - GetMinInterval(this.High) * 2);
if (other > current - GetMinInterval(current)) {
other = other + (GetMinInterval(other) * 2);
}
return other;
}
That seems promising. 🤔
The text was updated successfully, but these errors were encountered:
Our initial implementations of
IDistinctGenerator.NextDistinct()
for theSingleGenerator
andDoubleGenerator
use the following approach to get a distinct value:This guarantees that the newly generated value is outside of the minimum interval required to be considered distinct based upon the generator's precision, but it has two flaws:
this.Low
andthis.High
instead of throw anUnableToGenerateException
. An example could be a precision of0.1
on a range from0.0
to0.1
.other
value are more likely to be returned, as any generated value between 0 and 1 minimum intervals away from theother
value are instead pushed ignored in favor of the minimum interval. If the precision is weak enough and the range is small enough (say0.01
precision for a range of0.00
to1.00
for percentages), this bias is noticeable, though mostly harmless.This aren't causing any major problems downstream, but there certainly two things that could be improved. Item (1) is a simple boundary check in the constructor, but (2) is trickier because the minimum interval differs if you're using significant figures for precision.
When I brought this issue up with @sflanker, he had an idea expressed this way:
That seems promising. 🤔
The text was updated successfully, but these errors were encountered: