Dado un conjunto de puntos en [ - 1 , 1 ] , me gustaría calcular ∫ 1 - 1 L i ( x ) exactamente. L i es el polinomio de Lagrange con respecto a los puntos x j con x i como nodo, es decir, L i ( x ) = ∏ j ≠ i x - x j
¿Alguna idea de cómo evitarlos?
Dado un conjunto de puntos en [ - 1 , 1 ] , me gustaría calcular ∫ 1 - 1 L i ( x ) exactamente. L i es el polinomio de Lagrange con respecto a los puntos x j con x i como nodo, es decir, L i ( x ) = ∏ j ≠ i x - x j
¿Alguna idea de cómo evitarlos?
Respuestas:
El cálculo de
Calcule los pesos de la cuadratura de Clenshaw-Curtis en la cuadrícula extrema de Chebyshev para :
Transforme los pesos en la cuadrícula arbitraria , a través de la matriz de transformación para obtener los pesos buscados ,
El algoritmo parece ser bastante estable, particularmente cuando se lo compara con el enfoque de Vandermonde según lo provisto en la respuesta de @Kirill : aunque sigue las mismas ideas: generar los pesos en cuadratura de manera conocida y luego transformarlos en la nueva cuadrícula. podría esperarse ya que la transformación en términos de la matriz de Vandermonde suele estar muy mal condicionada.
Ejemplo: generación de pesos en cuadratura Legendre-Lobatto
Ejemplo: generación de fórmulas de cuadratura de Newton-Cotes
Consideramos la generación de la fórmula de la cuadratura de Newton-Cotes en cuadrículas equidistantes. Una vez más, uno espera un mal acondicionamiento, ya que, en resumen, para la interpolación polinómica, las redes espaciadas equitativamente son malas.
Ejemplo: cuadratura de Guass-Patterson
Este ejemplo se debe a @ NicoSchlömer. No conocía estas reglas hasta ahora, así que tomé las abscisas de esta implementación y apliqué tanto el enfoque de Vandermonde como el enfoque transformado de Clenshaw-Curtis (donde, como anteriormente, el enfoque de Vandermonde está utilizando el algoritmo Björk-Pereyra).
A partir de esta imagen, el enfoque transformado de Clenshaw-Curtis parece mucho más eficiente que el enfoque de Vandermonde (al menos en aritmética de precisión finita). Aún así, Clenshaw-Curtis se desglosa a partir del índice 7, por lo que se deben utilizar otros métodos.
module VandermondeInverse
using SpecialMatrices
function main(n=8)
X = Rational{BigInt}[k//(n-1) for k=0:n-1]
# X = convert(Vector{Rational{BigInt}}, linspace(-1, 1, n))
x = convert(Vector{Float64}, X)
A = convert(Matrix{Rational{BigInt}}, Vandermonde(X))
b = [i%2==0 ? 2//(i+1) : 0 for i=0:n-1]
println("Norm: ", norm(A, Inf))
println("Norm of inverse: ", norm(inv(A), Inf))
println("Condition number: ", cond(convert(Matrix{Float64}, A)))
ans = A'\b
println("True answer: ", ans)
B = convert(Matrix{Float64}, A)
c = convert(Vector{Float64}, b)
println("Linear solve: ", norm((B'\c - ans)./ans, Inf))
d = vec(c')
for k=1:n, l=n:-1:k+1
d[l] -= x[k]*d[l-1]
end
for k=n-1:-1:1, l=k:n
if l > k
d[l] /= x[l]-x[l-k]
end
if l < n
d[l] -= d[l+1]/(x[l+1] - x[l-k+1])
end
end
println("Neville elimination: ", norm((d-ans)./ans, Inf))
nothing
end
end
V = VandermondeInverse
Salida:
julia> V.main(14)
Norm: 14.0
Norm of inverse: 1.4285962612120493e10
Condition number: 5.2214922998851654e10
True answer: Rational{Int64}[3202439130233//2916000,-688553801328731//52390800,19139253128382829//261954000,-196146528919726853//785862000,6800579086408939//11642400,-43149880138884259//43659000,32567483200938127//26195400,-7339312362348889//6237000,48767438804485271//58212000,-69618881108680969//157172400,44275410625421677//261954000,-2308743351566483//52390800,11057243346333379//1571724000,-209920276397//404250]
Linear solve: 1.5714609387747318e-8
Neville elimination: 1.3238218572356314e-15
Si X
no es positivo como en esta prueba, parece que los errores relativos son del mismo orden que con una resolución lineal regular.
V.main(32)
produce una respuesta sensata en aproximadamente un segundo en mi computadora portátil (mientras uso solo un poco de memoria). Los números ni siquiera son tan grandes, el numerador más grande tiene 54 dígitos, por lo que sospecho que algo más te va mal. ¿Puedes publicar una esencia, porque tengo curiosidad por ver cómo falla?
Float64
para d
: consultar con @show typeof(d)
. Avísame si encuentras más problemas con él.
Calcule primero los productos de los nominadores y los denominadores y luego divídalos una vez. Los dos productos deben ser del mismo orden de magnitud, por lo que no debe haber errores significativos de redondeo. También obtiene el beneficio adicional de una mayor velocidad, debido a la reducción del número de cálculos de coma flotante.