//****************************************************************************************************** // Euclidean.cs - Gbtc // // Copyright © 2013, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 12/30/2013 - Stephen C. Wills // Generated original version of source code. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.Linq; namespace GSF.NumericalAnalysis { /// /// Contains an implementation of greatest common denominator /// and least common multiple using the Euclidean algorithm. /// public static class Euclidean { /// /// Implementation of the modulo operator using Euclidean division. /// /// The number to be divided. /// The number to divide by. /// public static double Mod(double numerator, double denominator) { double quotient = Math.Floor(numerator / denominator); return numerator - quotient * denominator; } /// /// Wraps a value to a range of values defined /// by the given minimum value and range. /// /// The value to be wrapped. /// The minimum value of the range. /// The size of the range. /// The given value wrapped to the given range. /// /// This method wraps the given value based on the assumption that /// for every pair of values x and y where x-y=range, the values are /// equivalent. This is probably most widely understood in terms of /// angles, where 0, 360, 720, etc. are all equivalent angles. If /// you wanted to wrap an angle such that it is between 120 and 480, /// for instance, you could call Euclidean.Wrap(angle, 120, 360). /// public static double Wrap(double value, double minimum, double range) { double transform = value - minimum; double remainder = Mod(transform, range); return remainder + minimum; } /// /// Gets the greatest common denominator of all the integers in the source collection. /// /// The collection of integers. /// The greatest common denominator. public static int GreatestCommonDenominator(this IEnumerable source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(GreatestCommonDenominator); } /// /// Gets the greatest common denominator of all the integers in the source collection. /// /// The collection of integers. /// The greatest common denominator. public static int GreatestCommonDenominator(params int[] source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(GreatestCommonDenominator); } /// /// Gets the greatest common denominator of the given integers. /// /// The first of the given integers. /// The second of the given integers. /// The greatest common denominator. public static int GreatestCommonDenominator(int a, int b) { return (b != 0) ? GreatestCommonDenominator(b, a % b) : a; } /// /// Gets the greatest common denominator of all the integers in the source collection. /// /// The collection of integers. /// The greatest common denominator. public static long GreatestCommonDenominator(this IEnumerable source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(GreatestCommonDenominator); } /// /// Gets the greatest common denominator of all the integers in the source collection. /// /// The collection of integers. /// The greatest common denominator. public static long GreatestCommonDenominator(params long[] source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(GreatestCommonDenominator); } /// /// Gets the greatest common denominator of the given integers. /// /// The first of the given integers. /// The second of the given integers. /// The greatest common denominator. public static long GreatestCommonDenominator(long a, long b) { return (b != 0) ? GreatestCommonDenominator(b, a % b) : a; } /// /// Gets the least common multiple of all the integers in the source collection. /// /// The collection of integers. /// The least common multiple. public static int LeastCommonMultiple(this IEnumerable source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(LeastCommonMultiple); } /// /// Gets the least common multiple of all the integers in the source collection. /// /// The collection of integers. /// The least common multiple. public static int LeastCommonMultiple(params int[] source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(LeastCommonMultiple); } /// /// Gets the least common multiple of the given integers. /// /// The first of the given integers. /// The second of the given integers. /// The least common multiple. public static int LeastCommonMultiple(int a, int b) { return a * (b / GreatestCommonDenominator(a, b)); } /// /// Gets the least common multiple of all the integers in the source collection. /// /// The collection of integers. /// The least common multiple. public static long LeastCommonMultiple(this IEnumerable source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(LeastCommonMultiple); } /// /// Gets the least common multiple of all the integers in the source collection. /// /// The collection of integers. /// The least common multiple. public static long LeastCommonMultiple(params long[] source) { if ((object)source == null) throw new ArgumentNullException(nameof(source), "source is null"); return source.Aggregate(LeastCommonMultiple); } /// /// Gets the least common multiple of the given integers. /// /// The first of the given integers. /// The second of the given integers. /// The least common multiple. public static long LeastCommonMultiple(long a, long b) { return a * (b / GreatestCommonDenominator(a, b)); } } }