/// <summary>
        ///   Computes the unnormalized cumulative distribution function and other attributes for the
        ///   distribution (like mean, variance, and so on).
        /// </summary>
        /// <remarks>
        ///   Also remember to change <see cref="SetUp(int, IEnumerable{double}, out double[])"/>
        ///   when changing this method.
        /// </remarks>
        private void UpdateHelpers()
        {
            var weightsSum = _weights.Sum();             // It will store the sum of all UNNORMALIZED weights.
            var cdf        = new double[_weights.Count]; // It will store NORMALIZED cdf.
            var tmpMean    = 0.0;
            var maxW       = 0.0;                        // It will store max weight (all weights are positive).
            var maxI       = 0;                          // It will store max weight index.

            // Let's normalize all weights, if necessary.
            if (!TMath.AreEqual(weightsSum, 1.0))
            {
                for (var i = 0; i < _weights.Count; ++i)
                {
                    _weights[i] /= weightsSum;
                }
                Debug.Assert(TMath.AreEqual(_weights.Sum(), 1.0));
            }

            weightsSum = 0.0; // Reset weight sum to use it for cdf.

            // One big loop to compute all helpers needed by this distribution.
            for (var i = 0; i < _weights.Count; ++i)
            {
                var w = _weights[i];
                weightsSum += w;
                cdf[i]      = weightsSum;
                tmpMean    += w * (i + 1.0); // Plus one because it is zero-based.
                if (w > maxW)
                {
                    maxW = w;
                    maxI = i;
                }
            }

            // Finalize some results...
            _cdf = cdf;
            Mean = tmpMean - 1.0; // Minus one to make it zero-based.
            Mode = new double[] { maxI };

            var halfWeightsSum = weightsSum / 2.0;
            var tmpMedian      = double.NaN;
            var tmpVar         = 0.0;

            // We still need another loop to compute variance; as for the mean, the plus/minus one is needed.
            for (var i = 0; i < _weights.Count; ++i)
            {
                if (double.IsNaN(tmpMedian) && _cdf[i] >= halfWeightsSum)
                {
                    tmpMedian = i;
                }
                tmpVar += _weights[i] * TMath.Square(i + 1 - Mean);
            }

            // Finalize last results...
            Median   = tmpMedian;
            Variance = tmpVar - 1.0;
        }