/// <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; } }