Exemple #1
0
        /// <summary>
        /// Returns a random subset of an array with a supplied number of
        /// elements (subsetCount). The elements in the subset are in the
        /// same order as in the original array. O(count).
        /// NOTE: this method needs to generate one random number for each
        /// element of the original array. If subsetCount is significantly
        /// smaller than count, it is more efficient to use
        /// <see cref="CreateSmallRandomSubsetIndexArray"/> or
        /// <see cref="CreateSmallRandomSubsetIndexArrayLong"/> or
        /// <see cref="CreateSmallRandomOrderedSubsetIndexArray"/> or
        /// <see cref="CreateSmallRandomOrderedSubsetIndexArrayLong"/>.
        /// </summary>
        public static T[] CreateRandomSubsetOfSize <T>(
            this T[] array, long subsetCount, IRandomUniform rnd = null)
        {
            if (rnd == null)
            {
                rnd = new RandomSystem();
            }
            long count = array.LongLength;

            if (!(subsetCount >= 0 && subsetCount <= count))
            {
                throw new ArgumentOutOfRangeException(nameof(subsetCount));
            }
            var  subset = new T[subsetCount];
            long si     = 0;

            for (int ai = 0; ai < count && si < subsetCount; ai++)
            {
                var p = (double)(subsetCount - si) / (double)(count - ai);
                if (rnd.UniformDouble() <= p)
                {
                    subset[si++] = array[ai];
                }
            }
            return(subset);
        }
Exemple #2
0
        /// <summary>
        /// Returns a random subset of the enumeration with a supplied number of
        /// elements (subsetCount). The elements in the subset are in the
        /// same order as in the input. O(count).
        /// NOTE: The number of elements of the Enumerable need to be calculated, in case of true enumerations
        ///       the implementation of .Count() results in a second evaluation of the enumerable.
        /// </summary>
        public static T[] CreateRandomSubsetOfSize <T>(
            this IEnumerable <T> input, long subsetCount, IRandomUniform rnd = null)
        {
            if (rnd == null)
            {
                rnd = new RandomSystem();
            }
            long count = input.Count();

            if (!(subsetCount >= 0 && subsetCount <= count))
            {
                throw new ArgumentOutOfRangeException(nameof(subsetCount));
            }
            var  subset = new T[subsetCount];
            long si = 0, ai = 0;

            foreach (var a in input)
            {
                if (ai < count && si < subsetCount)
                {
                    var p = (double)(subsetCount - si) / (double)(count - ai++);
                    if (rnd.UniformDouble() <= p)
                    {
                        subset[si++] = a;
                    }
                }
                else
                {
                    break;
                }
            }
            return(subset);
        }
        /// <summary>
        /// Enumerates elements in random order.
        /// </summary>
        public static IEnumerable <T> RandomOrder <T>(this IEnumerable <T> self, IRandomUniform rnd = null)
        {
            var tmp = self.ToArray();

            if (rnd == null)
            {
                rnd = new RandomSystem();
            }
            var perm = rnd.CreatePermutationArray(tmp.Length);

            return(perm.Select(index => tmp[index]));
        }
        /// <summary>
        /// Yields each element with propability p.
        /// </summary>
        public static IEnumerable <R> TakeRandomly <T, R>(this IEnumerable <T> self, Func <T, R> selector, double p,
                                                          IRandomUniform random = null)
        {
            if (self == null)
            {
                throw new ArgumentNullException();
            }
            if (p < 0 || p > 1)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (random == null)
            {
                random = new RandomSystem();
            }
            foreach (var s in self)
            {
                if (random.UniformDouble() <= p)
                {
                    yield return(selector(s));
                }
            }
        }