Integrando polinômios Lagrange com muitos nós, arredondamento

10

Dado um conjunto de pontos em , eu gostaria de calcular exatamente. é o polinômio de Lagrange em relação aos pontos com como nó, ou seja, Como esse é um polinômio de grau , eu poderia usar qualquer quadratura gaussiana antiga de grau suficiente. Isso funciona bem se não for muito grande, mas gera resultados com erros de arredondamento para grande . [ - 1 , 1 ] 1 - 1 L i ( x ){xj}j=1n[1,1]L i x j x i L i ( x ) = j i x - x j

11Li(x)dx
Lixjxinnn
Li(x)=jixxjxixj.
nnn

Alguma idéia de como evitar isso?

Nico Schlömer
fonte
3
Isso depende de onde xj 's são, mas você tem verificado que o seu Li ' s são bem-comportado? No pior dos casos, com xj sendo distribuída uniformemente, você começa o fenômeno Runge ( Li 's oscilatório e grande), caso em que não é realmente erros de arredondamento causando problemas.
Kirill
2
Além disso, nitpick: dividir por números pequenos é uma operação bem condicionada, é a subtração subseqüente de grandes números quase iguais que está mal condicionada e leva à instabilidade numérica.
Kirill
Parece que você está tentando calcular ondeVé a matriz de Vandermonde dexj's. Você pode dizer qual é o número da condição deV? (2,0,23,0,25,0,)V1VxjV
Kirill

Respostas:

5

O cálculo de

11Lk(x)dx
para os polinômios de LagrangeLk definidos em uma grade arbitráriaxk,k=0,,n pode ser realizado pelas duas etapas a seguir:

  1. Calcule os pesos de quadratura de Clenshaw-Curtis wkcc na grade extrema de Chebyshev yk para k=0,,n :

    yk=porque(kπn)Wkcc=ckn(1-j=1n/2bj4j2-1porque(2πjkn))
    ondebk: =1parak=n/2, caso contráriobk: =2eck: =1parak=0 0ouk=n, caso contráriock: =2. Veja o artigo de Waldvogel (2006) para mais detalhes.

  2. Transformar os pesos Wkcc à rede arbitrária xk,k=0 0,,n , através da matriz de transformação M para obter os pesos pretendidos Wk ,

    Wk=jMkjWjcc
    onde
    Mjk = euj(yk).

Em princípio, este é apenas quadratura Clenshaw-Curtis com os valores da função da grelha arbitrária xk , mas obtidos através de transformação com base (para um refernce geral em Clenshaw-Curtis, ver por exemplo o papel Trefethen).

O algoritmo parece bastante estável, principalmente quando comparado à abordagem de Vandermonde, conforme fornecida na resposta de @Kirill : embora siga as mesmas idéias - gere os pesos de quadratura em uma base conhecida e depois se transforme na nova grade - poderia ter sido esperado, já que a transformação em termos da matriz de Vandermonde é geralmente altamente mal condicionada.


Exemplo: Geração de pesos de quadratura de Legendre-Lobatto

Consideramos o exemplo da regra de quadratura de Legendere-Lobatto e comparamos a precisão com a abordagem monomial. Como referência, usamos os pesos em quadratura WkPerna obtidos pelo algoritmo Golub-Welsch para diferentes n e calculamos o erro acumulado

ϵn=k=1n(Wk-WkPerna)2
Aqui está o resultado: insira a descrição da imagem aqui Um observa que os pesos de quadratura de Clenshaw-Curtis são perfeitamente estáveis ​​em toda a faixa considerada de pontos de grade e reproduzem os pesos de Legendre até a precisão da máquina ( ϵ1015 ).


Exemplo: Geração de fórmulas de quadratura de Newton-Cotes

Consideramos a geração da fórmula de quadratura de Newton-Cotes em grades igualmente espaçadas. Novamente, espera-se um mau condicionamento, pois, em suma, para interpolação polinomial, as grades igualmente espaçadas são baaad.

Na figura a seguir, calculei a soma absoluta dos pesos Eu|WEu|/N . insira a descrição da imagem aqui

Até, digamos, 50 pontos de grade, o resultado da abordagem monomial e Clenshaw-Curtis concorda. Depois disso, Clenshaw-Curtis se torna melhor - pelo que vale a pena. Uma interpretação direta é que a grade igualmente espaçada arruina tudo para, digamos, n>10 . Por volta de n=50. , no entanto, a condição da matriz de Vandermonde revida e leva a um resultado ainda pior.


Exemplo: quadratura de Guass-Patterson

Este exemplo é devido ao @ NicoSchlömer. Eu não conhecia essas regras até agora, então peguei as abscissas dessa implementação e apliquei a abordagem de Vandermonde e a de Clenshaw-Curtis transformada (onde, como acima, a abordagem de Vandermonde está usando o algoritmo de Björk-Pereyra).

Conforme sugerido no comentário, calculei o erro de integrar uma função constante por

ϵ=1n|2-Eu=1nWEu|,
com o seguinte resultado:

insira a descrição da imagem aqui A partir dessa imagem, a abordagem transformada de Clenshaw-Curtis parece muito mais eficiente que a abordagem de Vandermonde (pelo menos na aritmética de precisão finita). Ainda assim, Clenshaw-Curtis divide a partir do índice 7, portanto outros métodos devem ser usados.

davidhigh
fonte
Wk
Esqueci de mencionar que isso ocorre com os pontos Gauss-Patterson, github.com/nschloe/quadpy/blob/master/quadpy/line_segment/… .
Nico Schlömer
@ NicoSchlömer: ok, isso é interessante, porque, exceto pela aritmética de precisão arbitrária (que a implementação julia parece oferecer), é difícil raciocinar como a abordagem de Vandermonde deveria ser mais precisa (como o Vandermonde está entre os principais exemplos de matriz mal condicionada). Vou fazer uma edição da questão e considerar a quadratura de Gauss-Patterson.
Davidhigh 19/12/19
Obrigado David por analisar tudo isso. É realmente interessante! Eu acho que seria uma adição interessante deste post incluir uma comparação com a quadratura de Gauss-Legendre comum no grau apropriado. Eu acho que funciona como a sua abordagem Clenshaw-Curtis. Além disso, colocar o código no github ou mais e vinculá-lo a partir daqui será útil para qualquer um que investigue isso no futuro. Se você vincular a resposta mais votada, tornarei a resposta "correta" por causa dos insights interessantes.
Nico Schlömer 19/12/19
@ NicoSchlömer: obrigado. O que você quer dizer com comparação com Gauss-Legendre? (porque os pesos de Gauss-Legendre são reproduzidos com precisão da máquina). A comparação entre Leg. e CC foi realizado por Trefethen, com o resultado de que a precisão do CC é frequentemente comparável. O que seria realmente interessante é estudar o desempenho de diferentes grades personalizadas e compará-lo com Legendre ou Clenshaw-Curtis. Além disso, vinculei a resposta mais votada.
Davidhigh
10

bV1b=(2,0,23,0,25,0,)

0x1<x2<<xnVb0x1O(n2)Lix12(x+1)

O(ϵmach)

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

Resultado:

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

Se Xnão for positivo como neste teste, parece que os erros relativos são da mesma ordem que com uma resolução linear regular.

bV1LEueuEu(xj)=δEujαjkeuk

euk(x)=j,kαj,kxj=(1,x,x2,,xn)(α0 0k,,αnk),
eu
eu=(α00α0 0nαn0 0αnn).
eukeu(1,x,,xn)
(1,x,x2,,xn)eu=(eu0 0(x),eu1(x),,eun(x)).
euk(xj)=δjk
(1x0 0x0 02x0 0n1xnxn2xnn)eu=Eu,
eu=V-1Vxj

-11xkdx=1+(-1)kk+1

-11euk(x)dx=jαjk1+(-1)kk+1=(2,0 0,23,0 0,25,0 0,)(α0 0k,,αnk).
n+1k=0 0n(2,0 0,23,0 0,)eueu=V-1
Kirill
fonte
Obrigado pela resposta elaborada! Para adicionar ainda mais clareza, você poderia dar mais detalhes sobre como trazer o problema para a forma de Vandermonde?
Nico Schlömer 18/03/19
@ NicoSchlömer Claro, veja editar. Obrigado pela pergunta, eu não tinha ideia que esse algoritmo existia.
18717 Kirill
n=16n=31
@ NicoSchlömer Hm, não consigo reproduzir isso: com o código acima, V.main(32)produz uma resposta sensata em cerca de um segundo no meu laptop (enquanto uso apenas um pouco de memória). Os números nem são tão grandes, o maior numerador tem 54 dígitos, então eu suspeito que algo está errado para você. Você pode postar uma essência, porque estou curioso para ver como ela falha?
Kirill
1
@ NicoSchlömer Se você quer dizer como começa a usar o BigFloat ao imprimir os erros relativos para a saída, não sei bem qual é a regra. Mas garanti que ele seja usado Float64para d: verifique com @show typeof(d). Deixe-me saber se você encontrar mais problemas com ele.
22417 Kirill
2

Calcule os produtos dos nominadores e denominadores primeiro e depois divida uma vez. Os dois produtos devem ser da mesma ordem de grandeza, para que não haja erros de arredondamento significativos. Além disso, você obtém o benefício adicional de maior velocidade, devido ao número reduzido de cálculos de ponto flutuante.

zap
fonte