Como posso obter a solução da equação complicada?
Introduction
Update 6/2014
Originally, I found three solutions; now it’s s s six. Eu pensei que eu sabia que havia três porque racionalizar a equação resulta em um polinômio de grau 24 e NSolve
encontra 24 Raízes e, em seguida, eliminar raízes que não eram zeros da equação original. Acontece que a equação era problemática do ponto de vista dos numéricos e perdi três.Outras modificações:
-
parece mais natural usar
Rationalize
para converter os coeficientes para números exatos neste caso do queSetPrecision
. -
da mesma forma, substituí
First @ eq
porSubtract @@ eq
.
Racionalizar a equação
deve-se ter em mente que, de acordo com a documentação em NSolve
NSolve
lida principalmente com o linear e equações polinomiais.
a equação de OP é uma equação algébrica que pode ser transformada em uma equação polinomial, que NSolve
pode então resolver facilmente. Uma vez que NSolve
não faz isso por si só, temos que racionalizar “à mão.”A racionalização tende a introduzir soluções estranhas, por isso temos de verificar as respostas devolvidas por NSolve
. Os coeficientes um pouco desagradáveis de eq
tornam mais difícil, uma vez que na racionalização eq
, o erro de arredondamento leva a algumas das raízes quadradas não cancelando como deveriam. Podemos corrigir isso ajustando a precisão de eq
para Infinity
.
podemos encontrar a praça-raízes em uma expressão expr
com
DeleteDuplicates @ Cases, Infinity]
, em Seguida, para cada raiz quadrada, podemos multiplicar expr
pela expressão com a raiz quadrada substituído pelo seu negativo e simplificar.
abaixo é o resultado da aplicação do método à função obtida substituindo Equal
em eq
por Subtract
por Apply
(@@
). Podemos resolver a equação exactamente.Existem algumas diferenças significativas entre as duas soluções:
(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)
seleccionar as raízes da equação indicada
actualizar: foi aqui que perdi alguns zeros.
I used Pick
to select roots at which the original equation eq
has a small value, less than some small threshold, say 10^-1
. Podemos verificar mais tarde que cada um é uma raiz, mas eu não verifiquei para outras raizes. As raízes originais foram:
rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)
Estes correspondem às raízes, 7, 9 e 20rootsRat
:
Position < 10^-1 &)](* {{7}, {9}, {20}}*)
Se eu verificar a exata equação para a zeros com PossibleZeroQ
, mais eu fico raízes:
Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)
leva sempre as suas possíveis raízes, ou pelo menos mais do que eu estava disposto a esperar.]
Curiosamente, estes adicionais raízes estão ligadas às diferenças entre os resultados retornados por NSolve
e Solve
:
Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)
Vamos deixar a nossa nova raízes ser o seguinte e podemos verificá-los abaixo:
rootsEqNew = Pick];rootsEqNew // N(* {{ζ -> -24559.6 + 24559.6 I}, {ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> -0.0832786 - 722.827 I}, {ζ -> 6.98478 + 0.493405 I}, {ζ -> 722.642 - 0.100823 I}}*)
Verifica
Em primeiro lugar, em não olhar muito bom para as novas adições:
eqExact /. rootsEqNew // N(* { 0. + 9.7614*10^12 I, (* {1} *) -1.49012*10^-8 + 3.91155*10^-8 I, (* {7} *) -1.39698*10^-8 - 3.63216*10^-8 I, (* {9} *) -2. + 1536. I, (* {14} *) 1.49012*10^-8 + 1.11759*10^-8 I, (* {20} *) 0. + 1024. I} (* {21} *)*)
O problema está na avaliação da equação com máquina de precisão.
N(* N::meprec warning about $MaxExtraPrecision being reached *)(* {0``69.62973568978663 + 0``69.69302870899077 I, 0``90.5174054423328 + 0``90.55817837498498 I, 0``90.50250822096415 + 0``90.54414468499085 I, 0``80.1824915073549 + 0``79.76650578675965 I, 0``90.47483650216002 + 0``90.49782363232914 I, 0``80.17292602755023 + 0``79.76710897249409 I}*)
a advertência não parece ser significativa. O aumento de $MaxExtraPrecision
para 2000
ainda produz o aviso e zeros com precisão em torno de 2020
para 2040
. Se forem zeros, N
provavelmente irá sempre produzir o aviso, uma vez que não pode ter um
Precision
(para além de MachinePrecision
).