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); }
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); } }
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); }
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); }
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); }
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); }
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); } }
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); } }
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); }
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); } }
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); }
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); } }
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); } }
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); } }
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); }
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)); } }
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); } }
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); }
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); }
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); } }
public static TSource Single <TSource>(this IEnumerable <TSource> source) { TSource?single = source.TryGetSingle(out bool found); if (!found) { ThrowHelper.ThrowNoElementsException(); } return(single !); }
public static TSource First <TSource>(this IEnumerable <TSource> source) { TSource first = source.TryGetFirst(out bool found); if (!found) { ThrowHelper.ThrowNoElementsException(); } return(first); }
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); }
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); }
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); }
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); }
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); }
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]);
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); }
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); }