免责声明:我不是统计专家,我没有根据截断正态分布的数学定义(例如维基百科中的定义)检查以下建议的解决方案。第一个代码块是截断正态分布类,它封装了 Math.Net 的普通的班级。制作截断正态分布的主要技术是在构造函数中。请注意在样本方法:
using MathNet.Numerics.Distributions;
public class TruncatedNormalDistribution {
public TruncatedNormalDistribution(double xMin, double xMax) {
XMin = xMin;
XMax = xMax;
double mean = XMin + (XMax - XMin) / 2; // Halfway between minimum and maximum.
// If the standard deviation is a third of the difference between the mean and
// the required minimum or maximum of a normal distribution, 99.7% of samples should
// be in the required range.
double standardDeviation = (mean - XMin) / 3;
Distribution = new Normal(mean, standardDeviation);
}
private Normal Distribution { get; }
private double XMin { get; }
private double XMax { get; }
public double CumulativeDistribution(double x) {
return Distribution.CumulativeDistribution(x);
}
public double Density(double x) {
return Distribution.Density(x);
}
public double Sample() {
return Math.Clamp(Distribution.Sample(), XMin, XMax);
}
}
这是一个使用示例。要直观地表示结果,请在电子表格(如 Excel)中打开两个输出 CSV 文件,并将其数据映射到折线图:
// Put the path of the folder where the CSVs will be saved here
const string chartFolderPath =
@"C:\Insert\chart\folder\path\here";
const double xMin = 0;
const double xMax = 100;
var distribution = new TruncatedNormalDistribution(xMin, xMax);
// Densities
var dictionary = new Dictionary<double, double>();
for (double x = xMin; x <= xMax; x += 1) {
dictionary.Add(x, distribution.Density(x));
}
string csvPath = Path.Combine(
chartFolderPath,
$"Truncated Normal Densities, Range {xMin} to {xMax}.csv");
using var writer = new StreamWriter(csvPath);
foreach ((double key, double value) in dictionary) {
writer.WriteLine($"{key},{value}");
}
// Cumulative Distributions
dictionary.Clear();
for (double x = xMin; x <= xMax; x += 1) {
dictionary.Add(x, distribution.CumulativeDistribution(x));
}
csvPath = Path.Combine(
chartFolderPath,
$"Truncated Normal Cumulative Distributions, Range {xMin} to {xMax}.csv");
using var writer2 = new StreamWriter(csvPath);
foreach ((double key, double value) in dictionary) {
writer2.WriteLine($"{key},{value}");
}