From 89ea7cefd713fbd44e6838603185a70ace6edf54 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 4 Nov 2012 16:32:50 -0500 Subject: [PATCH] Clean up a little bit of the interpolation code. --- mjo/interpolation.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/mjo/interpolation.py b/mjo/interpolation.py index 8c3936e..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,8 +109,7 @@ 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 @@ -176,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 @@ -289,6 +308,7 @@ def lagrange_psi(x, xs): OUTPUT: A symbolic expression in one variable, `x`. + """ return product([ (x - xj) for xj in xs ]) -- 2.43.2