/**
         * Karazuba multiplication
         */
        private BigDecimalPolynomial multRecursive(BigDecimalPolynomial poly2)
        {
            decimal[] a = coeffs;
            decimal[] b = poly2.coeffs;

            int n = poly2.coeffs.Length;

            if (n <= 1)
            {
                decimal[] c = (decimal[])coeffs.Clone();
                for (int i = 0; i < coeffs.Length; i++)
                {
                    c[i] = decimal.Multiply(c[i], poly2.coeffs[0]);
                }
                return(new BigDecimalPolynomial(c));
            }
            else
            {
                int n1 = n / 2;

                BigDecimalPolynomial a1 = new BigDecimalPolynomial(copyOf(a, n1));
                BigDecimalPolynomial a2 = new BigDecimalPolynomial(copyOfRange(a, n1, n));
                BigDecimalPolynomial b1 = new BigDecimalPolynomial(copyOf(b, n1));
                BigDecimalPolynomial b2 = new BigDecimalPolynomial(copyOfRange(b, n1, n));

                BigDecimalPolynomial A = (BigDecimalPolynomial)a1.Clone();
                A.Add(a2);
                BigDecimalPolynomial B = (BigDecimalPolynomial)b1.Clone();
                B.Add(b2);

                BigDecimalPolynomial c1 = a1.multRecursive(b1);
                BigDecimalPolynomial c2 = a2.multRecursive(b2);
                BigDecimalPolynomial c3 = A.multRecursive(B);
                c3.Sub(c1);
                c3.Sub(c2);

                BigDecimalPolynomial c = new BigDecimalPolynomial(2 * n - 1);
                for (int i = 0; i < c1.coeffs.Length; i++)
                {
                    c.coeffs[i] = c1.coeffs[i];
                }
                for (int i = 0; i < c3.coeffs.Length; i++)
                {
                    c.coeffs[n1 + i] = decimal.Add(c.coeffs[n1 + i], (c3.coeffs[i]));
                }
                for (int i = 0; i < c2.coeffs.Length; i++)
                {
                    c.coeffs[2 * n1 + i] = decimal.Add(c.coeffs[2 * n1 + i], (c2.coeffs[i]));
                }
                return(c);
            }
        }
 /**
  * Subtracts another polynomial which can have a different number of coefficients.
  *
  * @param b
  */
 void Sub(BigDecimalPolynomial b)
 {
     if (b.coeffs.Length > coeffs.Length)
     {
         int N = coeffs.Length;
         coeffs = copyOf(coeffs, b.coeffs.Length);
         for (int i = N; i < coeffs.Length; i++)
         {
             coeffs[i] = ZERO;
         }
     }
     for (int i = 0; i < b.coeffs.Length; i++)
     {
         coeffs[i] = decimal.Subtract(coeffs[i], b.coeffs[i]);
     }
 }
Beispiel #3
0
        /**
         * Divides each coefficient by a <code>BigDecimal</code> and rounds the result to <code>decimalPlaces</code> places.
         *
         * @param divisor       the number to divide by
         * @param decimalPlaces the number of fractional digits to round the result to
         * @return a new <code>BigDecimalPolynomial</code>
         */
        public BigDecimalPolynomial Divide(decimal divisor, int decimalPlaces)
        {
            BigInteger max         = MaxCoeffAbs();
            int        coeffLength = (int)(max.BitLength * LOG_10_2) + 1;
            // factor = 1/divisor
            decimal factor = decimal.Round(decimal.Divide(Constants.BIGDEC_ONE, divisor), coeffLength + decimalPlaces + 1, MidpointRounding.AwayFromZero);             //decimal.ROUND_HALF_EVEN);

            // multiply each coefficient by factor
            BigDecimalPolynomial p = new BigDecimalPolynomial(coeffs.Length);

            for (int i = 0; i < coeffs.Length; i++)
            // multiply, then truncate after decimalPlaces so subsequent operations aren't slowed down
            {
                p.coeffs[i] = decimal.Round(decimal.Multiply(new decimal(coeffs[i].IntValue), factor), decimalPlaces, MidpointRounding.AwayFromZero);                // BigDecimal.ROUND_HALF_EVEN);
            }

            return(p);
        }
        /**
         * Multiplies the polynomial by another, taking the indices mod N. Does not
         * change this polynomial but returns the result as a new polynomial.
         *
         * @param poly2 the polynomial to multiply by
         * @return a new polynomial
         */
        public BigDecimalPolynomial Multiply(BigDecimalPolynomial poly2)
        {
            int N = coeffs.Length;

            if (poly2.coeffs.Length != N)
            {
                throw new InvalidOperationException("Number of coefficients must be the same");
            }

            BigDecimalPolynomial c = multRecursive(poly2);

            if (c.coeffs.Length > N)
            {
                for (int k = N; k < c.coeffs.Length; k++)
                {
                    c.coeffs[k - N] = decimal.Add(c.coeffs[k - N], c.coeffs[k]);
                }
                c.coeffs = copyOf(c.coeffs, N);
            }
            return(c);
        }