public ScalarMultiplicationResult Multiply(IEnumerable <int> vector1, IEnumerable <int> vector2, IArithmeticOperations arithmeticOperations) { GC.Collect(); GC.WaitForPendingFinalizers(); int[] a = vector1.ToArray(); int[] b = vector2.ToArray(); if (a.Length != b.Length) { throw new Exception("Vectors should have same amount of elements"); } // TODO: // Show amount of memory occupied on UI // Add selector of number of multiplies (k) int result = 0; int numberOfElements = a.Length; ////Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; ////Thread.CurrentThread.Priority = ThreadPriority.Highest; Stopwatch sw = new Stopwatch(); sw.Start(); for (int k = 0; k < 10000; k++) { result = 0; for (int i = 0; i < numberOfElements; i++) { result = arithmeticOperations.Add(result, arithmeticOperations.Multiply(a[i], b[i])); } } sw.Stop(); return(new ScalarMultiplicationResult(result, sw.ElapsedTicks)); }
/// <summary> /// Performs arithmetic operations /// </summary> public ArithmeticOperationsController(IArithmeticOperations operations) { Operations = operations ?? throw new ArgumentNullException(nameof(operations)); }
public static int SumOfSquares <T>(IEnumerable <T> sequence, IArithmeticOperations <T> summator) { // Do work }
public ScalarMultiplicationResult Multiply(IEnumerable <int> vector1, IEnumerable <int> vector2, IArithmeticOperations arithmeticOperations) { GC.Collect(); GC.WaitForPendingFinalizers(); int[] weights = vector1.ToArray(); int[] inputValues = vector2.ToArray(); if (vector1.Count() != vector2.Count()) { throw new Exception("Vectors should have same amount of elements"); } ulong numberOfProducts = (ulong)Math.Pow(2, weights.Length); uint[] products = new uint[numberOfProducts]; int maxWeightsExponent = 0; int maxInputValuesExponent = 0; int[] weightsExponents = new int[weights.Length]; int[] inputValuesExponents = new int[weights.Length]; bool skipInputValues = false; if (arithmeticOperations is FixedFloatingPointNumbersArithmeticOperations) { skipInputValues = true; } for (int i = 0; i < weights.Length; i++) { int weigthExponent = arithmeticOperations.GetExponent(weights[i]); if (weigthExponent > maxWeightsExponent) { maxWeightsExponent = weigthExponent; } weightsExponents[i] = weigthExponent; if (skipInputValues) { continue; } int inputValueExponent = arithmeticOperations.GetExponent(inputValues[i]); if (inputValueExponent > maxInputValuesExponent) { maxInputValuesExponent = inputValueExponent; } inputValuesExponents[i] = inputValueExponent; } for (int i = 0; i < weights.Length; i++) { weights[i] = arithmeticOperations.MantissaRigthShift(weights[i], maxWeightsExponent - weightsExponents[i]); if (skipInputValues) { continue; } inputValues[i] = arithmeticOperations.MantissaRigthShift(inputValues[i], maxInputValuesExponent - inputValuesExponents[i]); } for (ulong i = 0; i < numberOfProducts; i++) { uint product = 0; for (int j = 0; j < weights.Length; j++) { if ((((ulong)1 << j) & i) > 0) { product += (uint)(weights[j] & FloatingPointNumbersArithmeticOperations.MANTISSA_MASK); } } products[i] = product; } uint resultExponent = (uint)((maxInputValuesExponent + maxWeightsExponent) << 24); uint result = 0; ulong[] inputData; int count = arithmeticOperations.NumberSize; int[] intputValuesMantisses; if (arithmeticOperations is FixedFloatingPointNumbersArithmeticOperations fixedFloatingPointNumbersArithmeticOperations) { intputValuesMantisses = inputValues.Select(d => (int)(fixedFloatingPointNumbersArithmeticOperations.FixedToFloatingPoint(d) & FloatingPointNumbersArithmeticOperations.MANTISSA_MASK)).ToArray(); } else { intputValuesMantisses = inputValues.Select(d => (int)(d & FloatingPointNumbersArithmeticOperations.MANTISSA_MASK)).ToArray(); } inputData = ConvertToSerialData(intputValuesMantisses, count); Stopwatch sw = new Stopwatch(); sw.Start(); for (int k = 0; k < 10000; k++) { result = 0; for (int i = 0; i < count; i++) { result = products[inputData[i]] + (result >> 1); } result |= resultExponent; } sw.Stop(); if (arithmeticOperations is FloatingPointNumbersArithmeticOperations || arithmeticOperations is FixedFloatingPointNumbersArithmeticOperations) { int mantissa = (int)((result & 0xFFFFFF) << 7); int exponent = (int)(result & 0x7F000000); FloatingPointNumbersArithmeticOperations.NormalizeManissa(ref mantissa, ref exponent); return(new ScalarMultiplicationResult(exponent | mantissa, sw.ElapsedTicks)); } else { return(new ScalarMultiplicationResult((int)result, sw.ElapsedTicks)); } }