Ejemplo n.º 1
0
        public static bool UnitTest()
        {
            FourierPoint a, b;
            Random       random = new Random(1001);

            byte[]     ra = new byte[32];
            BigInteger p  = (BigInteger.One << 128) - (BigInteger.One << 54) + BigInteger.One;

            for (int i = 20 * 1000; --i >= 0;)
            {
                random.NextBytes(ra);
                ra[ra.Length - 1] = 0;
                a = new FourierPoint(BitConverter.ToUInt64(ra, 0), BitConverter.ToUInt64(ra, 8));
                b = new FourierPoint(BitConverter.ToUInt64(ra, 16), BitConverter.ToUInt64(ra, 24));
                BigInteger ba = new BigInteger(ra.Take(16).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());
                BigInteger bb = new BigInteger(ra.Skip(16).Take(16).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());
                FourierPoint.mulmod(ref a, ref b);
                ba = (ba * bb) % p;
                byte[] rbb1 = ba.ToByteArray();
                Array.Resize(ref rbb1, 16);
                byte[] rbb2 = new byte[16];
                BitConverter.GetBytes(a.Low).CopyTo(rbb2, 0);
                BitConverter.GetBytes(a.High).CopyTo(rbb2, 8);
                for (int k = 16; --k >= 0;)
                {
                    if (rbb1[k] != rbb2[k])
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 2
0
        private static void ifft(this FourierPoint[] list)
        {
            int n      = list.Length;
            var handle = GCHandle.Alloc(list, GCHandleType.Pinned);

            try
            {
                IntPtr listAddress = handle.AddrOfPinnedObject();
                for (int k = 1; k < n; k <<= 1)
                {
                    FourierPoint.butterflyCore(listAddress, 0, k);
                    FourierPoint wpower = FourierPoint.One;
                    for (int j = k << 1, x = 0; j < n; x++, j += k << 1)
                    {
                        int pos = 0;
                        while ((x & (1 << pos)) != 0)
                        {
                            pos++;
                        }
                        FourierPoint.mulmod(ref wpower, ref FourierPoint.RootsInverters[pos]);
                        FourierPoint.inverseFFTCore(listAddress, j, k, ref wpower);
                    }
                }
            }
            finally
            {
                handle.Free();
            }
        }
Ejemplo n.º 3
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);
        }