Beispiel #1
0
        /// <summary>Multiplies the polynomial by another polynomial.</summary>
        public unsafe void Multiply(Polynomial value)
        {
            if (value == null)
            {
                throw new ArgumentNullException();
            }

            // (a0 + a1*x + a2*x^2) * (b0 + b1*x + b2^x^2 + b3*x^3) =
            //
            // a0 * (b0 + b1*x + b2^x^2 + b3*x^3) + a1*x * (b0 + b1*x + b2^x^2 + b3*x^3) + a2*x^2 * (b0 + b1*x + b2^x^2 + b3*x^3) =
            //
            // (a0*b0 + a0*b1*x + a0*b2*x^2 + a0*b3*x^3) + (a1*b0*x + a1*b1*x^2 + a1*b2*x^3 + a1*b3*x^4) +
            //   (a2*b0*x^2 + a2*b1*x^3 + a2*b2*x^4 + a2*b3*x^5) =
            //
            // a0*b0 + (a0*b1 + a1*b0)*x + (a0*b2 + a1*b1 * a2*b0)*x^2 + (a0*b3 + a1*b2 + a2*b1)*x^3 + (a1*b3 + a2*b2)*x^4 + a2*b3*x^5
            //
            // notice how in the result, the indices of the coefficients that are multiplied sum to the index of the result coefficient that they
            // contribute to. so for the 0th result coefficient, we have only a0*b0 (where 0+0 = 0). for the 1st result coefficient, we have
            // a0*b1 and a1*b0 (where 0+1 = 1+0 = 1). for the 2nd result coefficient, we have a0*b2, a1*b1, and a2*b0 (where 0+2 = 1+1 = 2+0 = 2)

            if (value.Degree == 0) // if it's actually a multiplication by a constant, we already have a method tuned for that
            {
                Multiply(value.coefficients[0]);
            }
            else
            {
                int newDegree = Degree + value.Degree;
                if (newDegree + 1 > coefficients.Length)
                {
                    coefficients = Utility.EnlargeArray(coefficients, Length, value.Degree);
                }

                // create a copy of the coefficients on the stack, and then clear the coefficients in preparation for writing the result
                double *copy = stackalloc double[Length];
                fixed(double *data = coefficients)
                {
                    int length = Length * sizeof(double);

                    Unsafe.Copy(data, copy, length);
                    Unsafe.Clear(data, length);
                }

                for (int i = 0; i <= Degree; i++)
                {
                    double av = copy[i];
                    for (int j = 0; j <= value.Degree; j++)
                    {
                        coefficients[i + j] += av * value.coefficients[j];
                    }
                }

                Degree = newDegree;
            }
        }