Пример #1
0
        public static bool UnitTest(int seed)
        {
            Random random = new Random(seed);
            int    bits   = 17;
            int    n      = 1 << bits;

            FourierPoint[] a0    = new FourierPoint[n];
            FourierPoint[] a1    = new FourierPoint[n];
            byte[]         bytes = new byte[16];
            for (int i = n; --i >= 0;)
            {
                random.NextBytes(bytes);
                a0[i] = a1[i] = new FourierPoint(BitConverter.ToUInt64(bytes, 0), BitConverter.ToUInt64(bytes, 8));
            }
            a0.FFT(false);
            a0.IFFT(false);
            //var scale = FourierPoint.PowMod(FourierPoint.HalfOne, new FourierPoint((ulong)bits, 0));
            for (int i = n; --i >= 0;)
            {
                //a0[i] *= scale;
                a0[i] >>= bits;
            }
            for (int i = n; --i >= 0;)
            {
                if (a0[i] != a1[i])
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #2
0
        public static void Multiply(ulong[] input1, ulong[] input2, ulong[] result, int n)
        {
            // AsmX64Operations.FastestMultiplication(input1, input2, result, n);
            // return;

            int fftBitsPerDigit, fftLog2Size;

            GetFFTParameters(n, out fftBitsPerDigit, out fftLog2Size);
            long fftN = 1L << fftLog2Size;

            //double directComputations = (double)n * n;
            //double karatsubaComputations = 4.7 * Math.Pow(n, LOG2_3);
            //double fftComputations = 7.2 * (3.0 * fftLog2Size + 4.0) * fftN;

            FourierPoint[] number1 = new FourierPoint[fftN];
            GroupDigits(input1, fftBitsPerDigit, number1);
            FourierPoint[] number2 = new FourierPoint[fftN];
            GroupDigits(input2, fftBitsPerDigit, number2);

            //FourierPoint scale = FourierPoint.PowMod(FourierPoint.HalfOne, new FourierPoint((ulong)fftLog2Size, 0UL));
            number1.FFT(false);
            number2.FFT(false);
            for (int i = number1.Length; --i >= 0;)
            {
                FourierPoint point = number1[i];
                FourierPoint.mulmod(ref point, ref number2[i]);
                //FourierPoint.mulmod(ref point, ref scale);
                point    >>= fftLog2Size;
                number1[i] = point;
            }
            number1.IFFT(false);

            var number1Handle = GCHandle.Alloc(number1, GCHandleType.Pinned);

            try
            {
                FourierPoint.PropagateCarries(number1Handle.AddrOfPinnedObject(), fftBitsPerDigit, number1.Length);
            }
            finally
            {
                number1Handle.Free();
            }

            UngroupDigits(number1, fftBitsPerDigit, result);
        }