private DiscreteDistribution(PrivateCoordinates coordinates) { if (coordinates.XCoordinates == null) { throw new ArgumentNullException(nameof(coordinates.XCoordinates)); } if (coordinates.PDFCoordinates == null) { throw new ArgumentNullException(nameof(coordinates.PDFCoordinates)); } if (coordinates.XCoordinates.Length < 3) { throw new DistributionsArgumentException(DistributionsArgumentExceptionType.LengthOfArgumentsMustBeGreaterThenTwo); } if (coordinates.PDFCoordinates.Length < 3) { throw new DistributionsArgumentException(DistributionsArgumentExceptionType.LengthOfValuesMustBeGreaterThenTwo); } if (coordinates.XCoordinates.Length != coordinates.PDFCoordinates.Length) { throw new DistributionsArgumentException(DistributionsArgumentExceptionType.LengthOfArgumentsMustBeEqualToLengthOfValues); } if (!coordinates.FromContinuous && coordinates.CDFCoordinates == null) { coordinates = Resample(coordinates); } XCoordinatesInternal = coordinates.XCoordinates; YCoordinatesInternal = coordinates.PDFCoordinates; cdfCoordinates = coordinates.CDFCoordinates; length = XCoordinatesInternal.Length; min = XCoordinatesInternal[0]; max = XCoordinatesInternal[length - 1]; if (coordinates.CDFCoordinates == null) { bool gotInf = AnalyzeInfinities(YCoordinatesInternal, Step); if (!coordinates.FromContinuous || gotInf) { Normalize(YCoordinatesInternal, Step); } } }
private static PrivateCoordinates Resample(PrivateCoordinates coordinates) { var pdf = coordinates.PDFCoordinates; int length = coordinates.XCoordinates.Length; double min = coordinates.XCoordinates[0]; double max = coordinates.XCoordinates[length - 1]; double step = (max - min) / (length - 1); AnalyzeInfinities(pdf, step); Normalize(pdf, step); double[] cdf = GetCDF(pdf, step); double tolerance = CommonRandomMath.GetTolerance(length); var minI = 0; var maxI = length - 1; for (int i = 0; i < length - 1; i++) { var c = cdf[i]; if (c < tolerance) { if (pdf[i] == 0) { minI = i + 1; } else { minI = i; } } if (c > 1 - tolerance) { if (pdf[i] == 0) { maxI = i - 1; } else { maxI = i; } break; } } min = coordinates.XCoordinates[minI]; max = coordinates.XCoordinates[maxI]; int r = maxI - minI + 1; if (r != length) { double[] newX = CommonRandomMath.GenerateXAxis(min, max, length, out _); double[] newY = new double[r]; for (int i = 0; i < r; i++) { newY[i] = coordinates.PDFCoordinates[i + minI]; } newY = CommonRandomMath.Resample(newY, length); return(new PrivateCoordinates { XCoordinates = newX, PDFCoordinates = newY }); } else { return(coordinates); } }