truncatedNormalToNormal function
Returns a Future<Map<String, num>>
containing
the mean and standard deviation
of the parent distribution of
a truncated normal distribution
with:
xMin
: Left limit of the truncated normal distribution,xMax
: Right limit of the truncated normal distribution.xMin < xMax
,meanOfTruncatedNormal
: mean of the truncated normal,stdDevOfTruncatedNormal
: standard deviation of the truncated normal.
Important: The function uses a simulated annealing algorithm, and convergence is not strictly guaranteed.
Note: The distribution must have a maximum between
xMin
and xMax
, that is the parent distribution must have
xMin < mean < xMax
.
Usage:
import 'package:sample_statistics/sample_statistics.dart';
void main(List<String> args) async {
final xMin = 2.0;
final xMax = 7.0;
final meanTruncatedNormal = 4.0;
final stdDevTruncatedNormal = 2.0;
final Map<String, double> result = await truncatedNormalToNormal(
xMin,
xMax,
meanTr,
stdDevTr,
);
print('mean: ${result[0]}, stdDev: ${result[1]});
}
Implementation
Future<Map<String, num>> truncatedNormalToNormal(
num xMin,
num xMax,
num meanTruncatedNormal,
num stdDevTruncatedNormal, {
num stdDevMin = 0.1,
num stdDevMax = 5,
}) async {
final mean = FixedInterval(
xMin + stdDevMin,
xMax - stdDevMin,
name: 'mean',
);
final stdDev = FixedInterval(
stdDevTruncatedNormal / 2,
stdDevTruncatedNormal * 2,
name: 'stdDev',
);
final space = SearchSpace.fixed(
[mean, stdDev],
);
num logBase(num x, {num base = 10}) {
return log(x) / log(base);
}
// This function will be minimized.
num energy(List<num> x) {
final result = (pow(
meanTruncatedNormal - _meanTruncatedNormal(xMin, xMax, x[0], x[1]),
2) +
pow(
stdDevTruncatedNormal -
_stdDevTruncatedNormal(xMin, xMax, x[0], x[1]),
2) +
epsilon);
// if (result.isNaN || result.isInfinite) {
// print('$x => energy: $result ');
// }
return logBase(result);
}
final field = EnergyField(energy, space);
final sim = LoggingSimulator(
field,
gammaStart: 0.7,
gammaEnd: 0.1,
outerIterations: 150,
innerIterationsStart: 3,
innerIterationsEnd: 6,
sampleSize: 350,
)
..deltaPositionStart = [stdDevTruncatedNormal, meanTruncatedNormal]
// ..deltaPositionEnd = [1e-8, 1e-8]
..temperatureSequence = exponentialSequence
..startPosition = [meanTruncatedNormal, stdDevTruncatedNormal];
final result = await sim.anneal(
isRecursive: true,
ratio: 0.7,
);
// await File('example/data/log.dat').writeAsString(sim.export());
return {'mean': result[0], 'stdDev': result[1]};
}