Пример #1
0
        public static decimal Min(this IEnumerable <decimal> source)
        {
            if (source.TryGetSpan(out ReadOnlySpan <decimal> span))
            {
                return(Min(span));
            }

            decimal value;

            using (IEnumerator <decimal> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = e.Current;
                while (e.MoveNext())
                {
                    decimal x = e.Current;
                    if (x < value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #2
0
        public static double Average <TSource>(this IEnumerable <TSource> source, Func <TSource, double> selector)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (selector == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.selector);
            }

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                double sum   = selector(e.Current);
                long   count = 1;
                while (e.MoveNext())
                {
                    // There is an opportunity to short-circuit here, in that if e.Current is
                    // ever NaN then the result will always be NaN. Assuming that this case is
                    // rare enough that not checking is the better approach generally.
                    sum += selector(e.Current);
                    ++count;
                }

                return(sum / count);
            }
        }
Пример #3
0
        public static double Min(this IEnumerable <double> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            double value;

            using (IEnumerator <double> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = e.Current;
                while (e.MoveNext())
                {
                    double x = e.Current;
                    if (x < value)
                    {
                        value = x;
                    }
                    else if (double.IsNaN(x))
                    {
                        return(x);
                    }
                }
            }

            return(value);
        }
Пример #4
0
        public static long Max(this IEnumerable <long> source)
        {
            if (source.TryGetSpan(out ReadOnlySpan <long> span))
            {
                return(Max(span));
            }

            long value;

            using (IEnumerator <long> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = e.Current;
                while (e.MoveNext())
                {
                    long x = e.Current;
                    if (x > value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #5
0
        public static long Min(this IEnumerable <long> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (source.GetType() == typeof(long[]))
            {
                return(Min((long[])source));
            }

            long value;

            using (IEnumerator <long> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = e.Current;
                while (e.MoveNext())
                {
                    long x = e.Current;
                    if (x < value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #6
0
        public static decimal Min <TSource>(this IEnumerable <TSource> source, Func <TSource, decimal> selector)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (selector == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.selector);
            }

            decimal value;

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = selector(e.Current);
                while (e.MoveNext())
                {
                    decimal x = selector(e.Current);
                    if (x < value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #7
0
        public static TSource Aggregate <TSource>(this IEnumerable <TSource> source, Func <TSource, TSource, TSource> func)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (func == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.func);
            }

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                TSource result = e.Current;
                while (e.MoveNext())
                {
                    result = func(result, e.Current);
                }

                return(result);
            }
        }
Пример #8
0
        public static double Average(this IEnumerable <long> source)
        {
            if (source.TryGetSpan(out ReadOnlySpan <long> span))
            {
                return(Average(span));
            }

            using (IEnumerator <long> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                long sum   = e.Current;
                long count = 1;
                checked
                {
                    while (e.MoveNext())
                    {
                        sum += e.Current;
                        ++count;
                    }
                }

                return((double)sum / count);
            }
        }
Пример #9
0
        public static int Max(this IEnumerable <int> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (source.GetType() == typeof(int[]))
            {
                return(Max((int[])source));
            }

            int value;

            using (IEnumerator <int> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = e.Current;
                while (e.MoveNext())
                {
                    int x = e.Current;
                    if (x > value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #10
0
        public static decimal Average <TSource>(this IEnumerable <TSource> source, Func <TSource, decimal> selector)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (selector == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.selector);
            }

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                decimal sum   = selector(e.Current);
                long    count = 1;
                while (e.MoveNext())
                {
                    sum += selector(e.Current);
                    ++count;
                }

                return(sum / count);
            }
        }
Пример #11
0
        private static double Average(ReadOnlySpan <int> span)
        {
            if (span.IsEmpty)
            {
                ThrowHelper.ThrowNoElementsException();
            }

            long sum = 0;
            int  i   = 0;

            if (Vector.IsHardwareAccelerated && span.Length >= Vector <int> .Count)
            {
                Vector <long> sums = default;
                do
                {
                    Vector.Widen(new Vector <int>(span.Slice(i)), out Vector <long> low, out Vector <long> high);
                    sums += low;
                    sums += high;
                    i    += Vector <int> .Count;
                }while (i <= span.Length - Vector <int> .Count);
                sum += Vector.Sum(sums);
            }

            for (; (uint)i < (uint)span.Length; i++)
            {
                sum += span[i];
            }

            return((double)sum / span.Length);
        }
Пример #12
0
        public static decimal Average(this IEnumerable <decimal> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            using (IEnumerator <decimal> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                decimal sum   = e.Current;
                long    count = 1;
                while (e.MoveNext())
                {
                    sum += e.Current;
                    ++count;
                }

                return(sum / count);
            }
        }
Пример #13
0
        public static decimal Average(this IEnumerable <decimal> source)
        {
            if (source.TryGetSpan(out ReadOnlySpan <decimal> span))
            {
                if (span.IsEmpty)
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                return(Sum(span) / span.Length);
            }

            using (IEnumerator <decimal> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                decimal sum   = e.Current;
                long    count = 1;
                while (e.MoveNext())
                {
                    sum += e.Current;
                    ++count;
                }

                return(sum / count);
            }
        }
Пример #14
0
        public static double Average(this IEnumerable <double> source)
        {
            if (source.TryGetSpan(out ReadOnlySpan <double> span))
            {
                if (span.IsEmpty)
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                return(Sum(span) / span.Length);
            }

            using (IEnumerator <double> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                double sum   = e.Current;
                long   count = 1;
                while (e.MoveNext())
                {
                    // There is an opportunity to short-circuit here, in that if e.Current is
                    // ever NaN then the result will always be NaN. Assuming that this case is
                    // rare enough that not checking is the better approach generally.
                    sum += e.Current;
                    ++count;
                }

                return(sum / count);
            }
        }
Пример #15
0
        public static decimal Min(this IEnumerable <decimal> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            decimal value;

            using (IEnumerator <decimal> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = e.Current;
                while (e.MoveNext())
                {
                    decimal x = e.Current;
                    if (x < value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #16
0
        private static TResult Average <TSource, TAccumulator, TResult>(this IEnumerable <TSource> source)
            where TSource : struct, INumber <TSource>
            where TAccumulator : struct, INumber <TAccumulator>
            where TResult : struct, INumber <TResult>
        {
            if (source.TryGetSpan(out ReadOnlySpan <TSource> span))
            {
                if (span.IsEmpty)
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                return(TResult.CreateChecked(Sum <TSource, TAccumulator>(span)) / TResult.CreateChecked(span.Length));
            }

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                TAccumulator sum   = TAccumulator.CreateChecked(e.Current);
                long         count = 1;
                while (e.MoveNext())
                {
                    checked { sum += TAccumulator.CreateChecked(e.Current); }
                    count++;
                }

                return(TResult.CreateChecked(sum) / TResult.CreateChecked(count));
            }
        }
Пример #17
0
        public static double Average(this IEnumerable <int> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            using (IEnumerator <int> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                long sum   = e.Current;
                long count = 1;
                checked
                {
                    while (e.MoveNext())
                    {
                        sum += e.Current;
                        ++count;
                    }
                }

                return((double)sum / count);
            }
        }
Пример #18
0
        public static TResult?Min <TSource, TResult>(this IEnumerable <TSource> source, Func <TSource, TResult> selector)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (selector == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.selector);
            }

            TResult?value = default;

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (value == null)
                {
                    do
                    {
                        if (!e.MoveNext())
                        {
                            return(value);
                        }

                        value = selector(e.Current);
                    }while (value == null);

                    Comparer <TResult> comparer = Comparer <TResult> .Default;
                    while (e.MoveNext())
                    {
                        TResult x = selector(e.Current);
                        if (x != null && comparer.Compare(x, value) < 0)
                        {
                            value = x;
                        }
                    }
                }
                else
                {
                    if (!e.MoveNext())
                    {
                        ThrowHelper.ThrowNoElementsException();
                    }

                    value = selector(e.Current);
                    while (e.MoveNext())
                    {
                        TResult x = selector(e.Current);
                        if (Comparer <TResult> .Default.Compare(x, value) < 0)
                        {
                            value = x;
                        }
                    }
                }
            }

            return(value);
        }
Пример #19
0
        public static TSource Min <TSource>(this IEnumerable <TSource> source)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            Comparer <TSource> comparer = Comparer <TSource> .Default;
            TSource            value    = default(TSource);

            if (value == null)
            {
                using (IEnumerator <TSource> e = source.GetEnumerator())
                {
                    do
                    {
                        if (!e.MoveNext())
                        {
                            return(value);
                        }

                        value = e.Current;
                    }while (value == null);

                    while (e.MoveNext())
                    {
                        TSource x = e.Current;
                        if (x != null && comparer.Compare(x, value) < 0)
                        {
                            value = x;
                        }
                    }
                }
            }
            else
            {
                using (IEnumerator <TSource> e = source.GetEnumerator())
                {
                    if (!e.MoveNext())
                    {
                        ThrowHelper.ThrowNoElementsException();
                    }

                    value = e.Current;
                    while (e.MoveNext())
                    {
                        TSource x = e.Current;
                        if (comparer.Compare(x, value) < 0)
                        {
                            value = x;
                        }
                    }
                }
            }

            return(value);
        }
Пример #20
0
        public static double Average(this IEnumerable <int> source)
        {
            if (source.TryGetSpan(out ReadOnlySpan <int> span))
            {
                // Int32 is special-cased separately from the rest of the types as it can be vectorized:
                // with at most Int32.MaxValue values, and with each being at most Int32.MaxValue, we can't
                // overflow a long accumulator, and order of operations doesn't matter.

                if (span.IsEmpty)
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                long sum = 0;
                int  i   = 0;

                if (Vector.IsHardwareAccelerated && span.Length >= Vector <int> .Count)
                {
                    Vector <long> sums = default;
                    do
                    {
                        Vector.Widen(new Vector <int>(span.Slice(i)), out Vector <long> low, out Vector <long> high);
                        sums += low;
                        sums += high;
                        i    += Vector <int> .Count;
                    }while (i <= span.Length - Vector <int> .Count);
                    sum += Vector.Sum(sums);
                }

                for (; (uint)i < (uint)span.Length; i++)
                {
                    sum += span[i];
                }

                return((double)sum / span.Length);
            }

            using (IEnumerator <int> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                long sum   = e.Current;
                long count = 1;

                while (e.MoveNext())
                {
                    checked { sum += e.Current; }
                    count++;
                }

                return((double)sum / count);
            }
        }
Пример #21
0
        public static TSource Single <TSource>(this IEnumerable <TSource> source)
        {
            TSource?single = source.TryGetSingle(out bool found);

            if (!found)
            {
                ThrowHelper.ThrowNoElementsException();
            }

            return(single !);
        }
Пример #22
0
        public static TSource First <TSource>(this IEnumerable <TSource> source)
        {
            TSource first = source.TryGetFirst(out bool found);

            if (!found)
            {
                ThrowHelper.ThrowNoElementsException();
            }

            return(first);
        }
Пример #23
0
        public static float Min <TSource>(this IEnumerable <TSource> source, Func <TSource, float> selector)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (selector == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.selector);
            }

            float value;

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = selector(e.Current);
                if (float.IsNaN(value))
                {
                    return(value);
                }

                while (e.MoveNext())
                {
                    float x = selector(e.Current);
                    if (x < value)
                    {
                        value = x;
                    }

                    // Normally NaN < anything is false, as is anything < NaN
                    // However, this leads to some irksome outcomes in Min and Max.
                    // If we use those semantics then Min(NaN, 5.0) is NaN, but
                    // Min(5.0, NaN) is 5.0!  To fix this, we impose a total
                    // ordering where NaN is smaller than every value, including
                    // negative infinity.
                    // Not testing for NaN therefore isn't an option, but since we
                    // can't find a smaller value, we can short-circuit.
                    else if (float.IsNaN(x))
                    {
                        return(x);
                    }
                }
            }

            return(value);
        }
Пример #24
0
        private static long Min(long[] array)
        {
            if (array.Length == 0)
            {
                ThrowHelper.ThrowNoElementsException();
            }

            // Vectorize the search if possible.
            int  index;
            long value;

            if (Vector.IsHardwareAccelerated && array.Length >= Vector <long> .Count * 2)
            {
                // The array is at least two vectors long. Create a vector from the first N elements,
                // and then repeatedly compare that against the next vector from the array.  At the end,
                // the resulting vector will contain the minimum values found, and we then need only
                // to find the min of those.
                var mins = new Vector <long>(array);
                index = Vector <long> .Count;
                do
                {
                    mins   = Vector.Min(mins, new Vector <long>(array, index));
                    index += Vector <long> .Count;
                }while (index + Vector <long> .Count <= array.Length);

                value = mins[0];
                for (int i = 1; i < Vector <long> .Count; i++)
                {
                    if (mins[i] < value)
                    {
                        value = mins[i];
                    }
                }
            }
            else
            {
                value = array[0];
                index = 1;
            }

            // Iterate through the remaining elements, comparing against the min.
            for (int i = index; (uint)i < (uint)array.Length; i++)
            {
                if (array[i] < value)
                {
                    value = array[i];
                }
            }

            return(value);
        }
Пример #25
0
        private static long Max(ReadOnlySpan <long> span)
        {
            if (span.IsEmpty)
            {
                ThrowHelper.ThrowNoElementsException();
            }

            // Vectorize the search if possible.
            int  index;
            long value;

            if (Vector.IsHardwareAccelerated && span.Length >= Vector <long> .Count * 2)
            {
                // The span is at least two vectors long. Create a vector from the first N elements,
                // and then repeatedly compare that against the next vector from the span.  At the end,
                // the resulting vector will contain the maximum values found, and we then need only
                // to find the max of those.
                var maxes = new Vector <long>(span);
                index = Vector <long> .Count;
                do
                {
                    maxes  = Vector.Max(maxes, new Vector <long>(span.Slice(index)));
                    index += Vector <long> .Count;
                }while (index + Vector <long> .Count <= span.Length);

                value = maxes[0];
                for (int i = 1; i < Vector <long> .Count; i++)
                {
                    if (maxes[i] > value)
                    {
                        value = maxes[i];
                    }
                }
            }
            else
            {
                value = span[0];
                index = 1;
            }

            // Iterate through the remaining elements, comparing against the max.
            for (int i = index; (uint)i < (uint)span.Length; i++)
            {
                if (span[i] > value)
                {
                    value = span[i];
                }
            }

            return(value);
        }
Пример #26
0
        public static double Max <TSource>(this IEnumerable <TSource> source, Func <TSource, double> selector)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (selector == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.selector);
            }

            double value;

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = selector(e.Current);

                // As described in a comment on Min(this IEnumerable<double>) NaN is ordered
                // less than all other values. We need to do explicit checks to ensure this, but
                // once we've found a value that is not NaN we need no longer worry about it,
                // so first loop until such a value is found (or not, as the case may be).
                while (double.IsNaN(value))
                {
                    if (!e.MoveNext())
                    {
                        return(value);
                    }

                    value = selector(e.Current);
                }

                while (e.MoveNext())
                {
                    double x = selector(e.Current);
                    if (x > value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #27
0
        private static double Average(ReadOnlySpan <long> span)
        {
            if (span.IsEmpty)
            {
                ThrowHelper.ThrowNoElementsException();
            }

            long sum = span[0];

            for (int i = 1; i < span.Length; i++)
            {
                checked { sum += span[i]; }
            }

            return((double)sum / span.Length);
        }
Пример #28
0
        private static double Max(ReadOnlySpan <double> span)
        {
            if (span.IsEmpty)
            {
                ThrowHelper.ThrowNoElementsException();
            }

            int i;

            for (i = 0; i < span.Length && double.IsNaN(span[i]); i++)
            {
                ;
            }

            if (i == span.Length)
            {
                return(span[^ 1]);
Пример #29
0
        public static float Max <TSource>(this IEnumerable <TSource> source, Func <TSource, float> selector)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }

            if (selector == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.selector);
            }

            float value;

            using (IEnumerator <TSource> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = selector(e.Current);
                while (float.IsNaN(value))
                {
                    if (!e.MoveNext())
                    {
                        return(value);
                    }

                    value = selector(e.Current);
                }

                while (e.MoveNext())
                {
                    float x = selector(e.Current);
                    if (x > value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }
Пример #30
0
        public static double Max(this IEnumerable <double> source)
        {
            if (source.TryGetSpan(out ReadOnlySpan <double> span))
            {
                return(Max(span));
            }

            double value;

            using (IEnumerator <double> e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    ThrowHelper.ThrowNoElementsException();
                }

                value = e.Current;

                // As described in a comment on Min(this IEnumerable<double>) NaN is ordered
                // less than all other values. We need to do explicit checks to ensure this, but
                // once we've found a value that is not NaN we need no longer worry about it,
                // so first loop until such a value is found (or not, as the case may be).
                while (double.IsNaN(value))
                {
                    if (!e.MoveNext())
                    {
                        return(value);
                    }

                    value = e.Current;
                }

                while (e.MoveNext())
                {
                    double x = e.Current;
                    if (x > value)
                    {
                        value = x;
                    }
                }
            }

            return(value);
        }