Example #1
0
        public IntegerPolynomial Multiply(IntegerPolynomial poly2, int modulus)
        {
            IntegerPolynomial c = Multiply(poly2);

            c.Mod(modulus);
            return(c);
        }
Example #2
0
        /**
         * Multithreaded version of {@link #resultant()}.
         *
         * @return <code>(rho, res)</code> satisfying <code>res = rho*this + t*(x^n-1)</code> for some integer <code>t</code>.
         */
        /* Taking out Async for now, harder problem than just translating.
         * public async Task<Resultant> ResultantMultiThread()
         * {
         *      int N = coeffs.Length;
         *
         *      // upper bound for resultant(f, g) = ||f, 2||^deg(g) * ||g, 2||^deg(f) = squaresum(f)^(N/2) * 2^(deg(f)/2) because g(x)=x^N-1
         *      // see http://jondalon.mathematik.uni-osnabrueck.de/staff/phpages/brunsw/CompAlg.pdf chapter 3
         *      BigInteger max = squareSum().pow((N + 1) / 2);
         *      max = max.multiply(BigInteger.ValueOf(2).pow((degree() + 1) / 2));
         *      BigInteger max2 = max.multiply(BigInteger.ValueOf(2));
         *
         *      // compute resultants modulo prime numbers
         *      BigInteger prime = BigInteger.ValueOf(10000);
         *      BigInteger pProd = Constants.BIGINT_ONE;
         *      LinkedBlockingQueue<Task<ModularResultant>> resultantTasks = new LinkedBlockingQueue<Task<ModularResultant>>();
         *      Iterator<BigInteger> primes = BIGINT_PRIMES.Iterator();
         *      ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
         *      while (pProd.CompareTo(max2) < 0)
         *      {
         *              if (primes.hasNext())
         *              {
         *                      prime = primes.next();
         *              }
         *              else
         *              {
         *                      prime = prime.NextProbablePrime();
         *              }
         *              Task<ModularResultant> task = executor.submit(new ModResultantTask(prime.IntValue));
         *              resultantTasks.add(task);
         *              pProd = pProd.Multiply(prime);
         *      }
         *
         *      // Combine modular resultants to obtain the resultant.
         *      // For efficiency, first combine all pairs of small resultants to bigger resultants,
         *      // then combine pairs of those, etc. until only one is left.
         *      ModularResultant overallResultant = null;
         *      while (!resultantTasks.isEmpty())
         *      {
         *              try
         *              {
         *                      Task<ModularResultant> modRes1 = resultantTasks.take();
         *                      Task<ModularResultant> modRes2 = resultantTasks.poll();
         *                      if (modRes2 == null)
         *                      {
         *                              // modRes1 is the only one left
         *                              overallResultant = await modRes1; //modRes1..get();
         *                              break;
         *                      }
         *                      Task<ModularResultant> newTask = executor.submit(new CombineTask(modRes1.get(), modRes2.get()));
         *                      resultantTasks.add(newTask);
         *              }
         *              catch (Exception e)
         *              {
         *                      throw new InvalidOperationException(e.ToString());
         *              }
         *      }
         *      executor.shutdown();
         *      BigInteger res = overallResultant.res;
         *      BigIntPolynomial rhoP = overallResultant.rho;
         *
         *      BigInteger pProd2 = pProd.divide(BigInteger.ValueOf(2));
         *      BigInteger pProd2n = pProd2.negate();
         *
         *      if (res.compareTo(pProd2) > 0)
         *      {
         *              res = res.subtract(pProd);
         *      }
         *      if (res.compareTo(pProd2n) < 0)
         *      {
         *              res = res.add(pProd);
         *      }
         *
         *      for (int i = 0; i < N; i++)
         *      {
         *              BigInteger c = rhoP.coeffs[i];
         *              if (c.compareTo(pProd2) > 0)
         *              {
         *                      rhoP.coeffs[i] = c.subtract(pProd);
         *              }
         *              if (c.compareTo(pProd2n) < 0)
         *              {
         *                      rhoP.coeffs[i] = c.add(pProd);
         *              }
         *      }
         *
         *      return new Resultant(rhoP, res);
         * }
         */
        /**
         * Resultant of this polynomial with <code>x^n-1 mod p</code>.
         *
         * @return <code>(rho, res)</code> satisfying <code>res = rho*this + t*(x^n-1) mod p</code> for some integer <code>t</code>.
         */
        public ModularResultant Resultant(int p)
        {
            // Add a coefficient as the following operations involve polynomials of degree deg(f)+1
            int[] fcoeffs = new int[coeffs.Length + 1];
            Array.Copy(coeffs, fcoeffs, coeffs.Length);
            IntegerPolynomial f = new IntegerPolynomial(fcoeffs);
            int N = fcoeffs.Length;

            IntegerPolynomial a = new IntegerPolynomial(N);

            a.coeffs[0]     = -1;
            a.coeffs[N - 1] = 1;
            IntegerPolynomial b  = new IntegerPolynomial(f.coeffs);
            IntegerPolynomial v1 = new IntegerPolynomial(N);
            IntegerPolynomial v2 = new IntegerPolynomial(N);

            v2.coeffs[0] = 1;
            int da = N - 1;
            int db = b.Degree();
            int ta = da;
            int c  = 0;
            int r  = 1;

            while (db > 0)
            {
                c = Util.Util.Invert(b.coeffs[db], p);
                c = (c * a.coeffs[da]) % p;
                a.MultShiftSub(b, c, da - db, p);
                v1.MultShiftSub(v2, c, da - db, p);

                da = a.Degree();
                if (da < db)
                {
                    r *= Util.Util.Pow(b.coeffs[db], ta - da, p);
                    r %= p;
                    if (ta % 2 == 1 && db % 2 == 1)
                    {
                        r = (-r) % p;
                    }
                    IntegerPolynomial temp = a;
                    a = b;
                    b = temp;
                    int tempdeg = da;
                    da   = db;
                    temp = v1;
                    v1   = v2;
                    v2   = temp;
                    ta   = db;
                    db   = tempdeg;
                }
            }
            r *= Util.Util.Pow(b.coeffs[0], da, p);
            r %= p;
            c  = Util.Util.Invert(b.coeffs[0], p);
            v2.Multiply(c);
            v2.Mod(p);
            v2.Multiply(r);
            v2.Mod(p);

            // drop the highest coefficient so #coeffs matches the original input
            int[] newCoeffs = new int[v2.coeffs.Length - 1];
            Array.Copy(v2.coeffs, newCoeffs, v2.coeffs.Length - 1);
            v2.coeffs = newCoeffs;
            return(new ModularResultant(new BigIntPolynomial(v2), BigInteger.ValueOf(r), BigInteger.ValueOf(p)));
        }