Пример #1
0
        public void Sample()
        {
            Contracts.Check(!_locked, "Cannot continue to sample after Lock() has been called");

            _numSampled++;

            // If the number of samples seen so far is less than the total reservoir size, cache the new sample.
            if (_numSampled <= _cache.Length)
            {
                _getter(ref _cache[_numSampled - 1]);

                // If the cache is full, sample from it with replacement into the reservoir.
                if (_numSampled == _cache.Length)
                {
                    for (int i = 0; i < _cache.Length; i++)
                    {
                        _reservoir[i] = _rnd.Next(_cache.Length);
                        _counts[_reservoir[i]]++;
                    }
                }
            }
            else
            {
                // Choose how many times to insert the current instance into the reservoir.
                int k = Stats.SampleFromBinomial(_rnd, _cache.Length, 1.0 / _numSampled);

                if (k > 0)
                {
                    int ind = _rnd.Next(_reservoir.Length);
                    // If the item referenced at this index appears more than once in the reservoir, we cannot overwrite it,
                    // we need to find an available place in the cache.
                    if (_counts[_reservoir[ind]] > 1)
                    {
                        Contracts.Assert(_counts.Contains(0));
                        var tmp = _counts.Select((count, i) => new KeyValuePair <int, int>(count, i)).First(kvp => kvp.Key == 0);
                        _counts[_reservoir[ind]]--;
                        _reservoir[ind]    = tmp.Value;
                        _counts[tmp.Value] = 1;
                    }
                    else if (_counts[_reservoir[ind]] == 0)
                    {
                        _counts[_reservoir[ind]]++;
                    }
                    _getter(ref _cache[_reservoir[ind]]);

                    for (int j = 1; j < k;)
                    {
                        var next = _rnd.Next(_reservoir.Length);
                        if (_reservoir[next] == _reservoir[ind])
                        {
                            continue;
                        }
                        _counts[_reservoir[next]]--;
                        _reservoir[next] = _reservoir[ind];
                        _counts[_reservoir[next]]++;
                        j++;
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Defines a sample stream for a biniomian distribution
        /// </summary>
        /// <param name="random">The random source</param>
        /// <param name="n">The number of trials</param>
        /// <param name="p">The probability of success of a given trial</param>
        public static IEnumerable <int> SampleBinomial(this IPolyrand random, int n, double p)
        {
            var sysrand = SysRand.Derive(random);

            while (true)
            {
                yield return(MlStats.SampleFromBinomial(sysrand, n, p));
            }
        }
Пример #3
0
        /// <summary>
        /// Defines a sample stream for a biniomian distribution
        /// </summary>
        /// <param name="random">The random source</param>
        /// <param name="n">The number of trials</param>
        /// <param name="p">The probability of success of a given trial</param>
        public static IEnumerable <T> SampleBinomial <T>(this IPolyrand random, T n, double p)
            where T : struct
        {
            var sysrand = SysRand.Derive(random);

            while (true)
            {
                yield return(convert <T>(MlStats.SampleFromBinomial(sysrand, convert <T, int>(n), p)));
            }
        }