/// <summary> /// Determines whether the Polynomials are equal. /// </summary> /// <param name="other">The other Polynomial.</param> /// <returns>Whether the Polynomials are equal.</returns> public bool Equals(Polynomial other) { if (this.Degree != other.Degree) return false; for (int i = 0; i < this.Coefficients.Length; i++) { if (!this.Coefficients[i].Equals(other.Coefficients[i])) return false; } return true; }
/// <summary> /// Divide the specified polynomials. /// </summary> /// <param name="left">The left polynomial.</param> /// <param name="right">The right polynomial.</param> /// <param name="remainder">The remainder.</param> /// <returns>The result.</returns> public static Polynomial DivRem(Polynomial left, Polynomial right, out Polynomial remainder) { if (left.Degree >= right.Degree) { Polynomial q = new Polynomial(0); while (left.Degree >= right.Degree) { Polynomial d = right * Polynomial.OfDegree(left.Degree - right.Degree, 1); q[left.Degree - right.Degree] = left[left.Degree] / d[d.Degree]; d = d * q[left.Degree - right.Degree]; left = left - d; if (left.Degree == 0 && right.Degree == 0) { remainder = left; return new Polynomial(0); } } remainder = left; return q; } else { remainder = left; return new Polynomial(0); } }
/// <summary> /// A linear spline interpolation. /// </summary> /// <param name="points">The known data points.</param> /// <returns>An interpolation function.</returns> public static Func<double, double> Linear(Point[] points) { if (points.Length < 2) return null; Polynomial[] splines = new Polynomial[points.Length - 1]; for (int i = 1; i < points.Length; i++) { double x0 = points[i - 1].X, y0 = points[i - 1].Y, x1 = points[i].X, y1 = points[i].Y; splines[i - 1] = new Polynomial(y0, (y1 - y0) / (x1 - x0)); } return x => { Polynomial last = splines[0]; int i; for (i = 1; i < splines.Length; i++) { if (points[i].X > x) break; last = splines[i]; } return last.Evaluate(x - points[i - 1].X); }; }
/// <summary> /// Divide the specified polynomials. /// </summary> /// <param name="left">The left polynomial.</param> /// <param name="right">The right polynomial.</param> /// <returns>The result.</returns> public static Polynomial operator /(Polynomial left, Polynomial right) { if (left.Degree >= right.Degree) { Polynomial q = new Polynomial(0); while (left.Degree >= right.Degree) { Polynomial d = right * OfDegree(left.Degree - right.Degree, 1); q[left.Degree - right.Degree] = left[left.Degree] / d[d.Degree]; d = d * q[left.Degree - right.Degree]; left = left - d; if (left.Degree == 0 && right.Degree == 0) return new Polynomial(0); } return q; } else { return new Polynomial(0); } }
/// <summary> /// A cubic spline interpolation. /// </summary> /// <param name="points">The known data points.</param> /// <returns>An interpolation function.</returns> public static Func<double, double> Cubic(Point[] points) { if (points.Length < 2) return null; int n = points.Length - 1; double[] b = new double[n], d = new double[n], h = new double[n], alpha = new double[n], c = new double[n + 1], l = new double[n + 1], mu = new double[n + 1], z = new double[n + 1]; for (int i = 0; i < n; i++) { h[i] = points[i + 1].X - points[i].X; } for (int i = 1; i < n; i++) { alpha[i] = (3 / h[i]) * (points[i + 1].Y - points[i].Y) - (3 / h[i - 1]) * (points[i].Y - points[i - 1].Y); } l[0] = mu[0] = z[0] = 0; for (int i = 1; i < n; i++) { l[i] = 2 * (points[i + 1].X - points[i - 1].X) - h[i - 1] * mu[i - 1]; mu[i] = h[i] / l[i]; z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; } l[n] = 1; z[n] = c[n] = 0; for (int j = n - 1; j >= 0; j--) { c[j] = z[j] - mu[j] * c[j + 1]; b[j] = (points[j + 1].Y - points[j].Y) / h[j] - (h[j] * (c[j + 1] + 2 * c[j])) / 3; d[j] = (c[j + 1] - c[j]) / (3 * h[j]); } Polynomial[] splines = new Polynomial[n]; for (int i = 0; i < n; i++) { splines[i] = new Polynomial(points[i].Y, b[i], c[i], d[i]); } return x => { Polynomial last = splines[0]; int i; for (i = 1; i < splines.Length; i++) { if (points[i].X > x) break; last = splines[i]; } return last.Evaluate(x - points[i - 1].X); }; }