X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Finterpolation.py;h=5d65d154e1ce567a7a408c305abcf91596176f4c;hb=ff5b1d1514a419bbf8140658778d1e69e89b2664;hp=70c35c1a3ac9e812865185c71b1f4d2cc88be1ed;hpb=c2eb40221f6eb4bea022fcb885f25268c1dbd1e3;p=sage.d.git diff --git a/mjo/interpolation.py b/mjo/interpolation.py index 70c35c1..5d65d15 100644 --- a/mjo/interpolation.py +++ b/mjo/interpolation.py @@ -1,6 +1,26 @@ from sage.all import * from misc import product + +def lagrange_denominator(k, xs): + """ + Return the denominator of the kth Lagrange coefficient. + + INPUT: + + - ``k`` -- The index of the coefficient. + + - ``xs`` -- The list of points at which the function values are + known. + + OUTPUT: + + The product of all xs[j] with j != k. + + """ + return product([xs[k] - xs[j] for j in range(0, len(xs)) if j != k]) + + def lagrange_coefficient(k, x, xs): """ Returns the coefficient function l_{k}(variable) of y_{k} in the @@ -12,9 +32,9 @@ def lagrange_coefficient(k, x, xs): INPUT: - - ``k`` -- the index of the coefficient. + - ``k`` -- The index of the coefficient. - - ``x`` -- the symbolic variable to use for the first argument + - ``x`` -- The symbolic variable to use for the first argument of l_{k}. - ``xs`` -- The list of points at which the function values are @@ -31,8 +51,8 @@ def lagrange_coefficient(k, x, xs): 1/8*(pi - 6*x)*(pi - 2*x)*(pi + 6*x)*x/pi^4 """ - numerator = product([x - xs[j] for j in range(0, len(xs)) if j != k]) - denominator = product([xs[k] - xs[j] for j in range(0, len(xs)) if j != k]) + numerator = lagrange_psi(x, xs)/(x - xs[k]) + denominator = lagrange_denominator(k, xs) return (numerator / denominator) @@ -89,10 +109,10 @@ def divided_difference_coefficients(xs): [1/2/pi^2, -1/pi^2, 1/2/pi^2] """ - coeffs = [ product([ (QQ(1) / (xj - xi)) for xi in xs if xi != xj ]) - for xj in xs ] + coeffs = [ QQ(1)/lagrange_denominator(k, xs) for k in range(0, len(xs)) ] return coeffs + def divided_difference(xs, ys): """ Return the Newton divided difference of the points (xs[k], @@ -175,7 +195,7 @@ def newton_polynomial(x, xs, ys): for k in range(0, degree+1): term = divided_difference(xs[:k+1], ys[:k+1]) - term *= product([ x - xk for xk in xs[:k]]) + term *= lagrange_psi(x, xs[:k]) N += term return N @@ -269,3 +289,26 @@ def hermite_interpolant(x, xs, ys, y_primes): for k in range(0, len(xs)) ]) return (s1 + s2) + + +def lagrange_psi(x, xs): + """ + The function, + + Psi(x) = (x - xs[0])*(x - xs[1])* ... *(x - xs[-1]) + + used in Lagrange and Hermite interpolation. + + INPUT: + + - ``x`` -- The independent variable of the resulting expression. + + - ``xs`` -- A list of points. + + OUTPUT: + + A symbolic expression in one variable, `x`. + + """ + + return product([ (x - xj) for xj in xs ])