Como usar a função polilogaritmo em c ++?

9

Existe alguma diretiva de pré-processador que possa ser usada para usar a função polylog? Ou está incluído no cmath? Se sim, você o chama por Li ou por polylog?


EDIT: O que realmente estou tentando fazer é fornecer um valor analítico para a integral indefinida da função

x3ex1

que envolve funções de polilogaritmo. Mas se alguém tiver uma sugestão para outra maneira de integrar essa função analiticamente, eu seria bem-vindo a todas as idéias.


flamingohats
fonte
Para fins de pesquisa: a função considerada no OP está relacionada às funções Debye . Esta nota pode ser útil.
JM
Outra relação próxima é a integral de Fermi-Dirac incompleta .
15173 Hardmath

Respostas:

7

Existe uma biblioteca C da GPL, ANANT - Algorithms in Analytic Number Theory, de Linas Vepstas, que inclui a implementação multiprecisão do polilogaritmo, com base no GMP .

Do seu arquivo LEIA-ME:

Este projeto contém implementações ad-hoc de diversas funções analíticas de interesse na teoria dos números, incluindo a função gama, a função Riemann zeta, o polilogaritmo e a função de ponto de interrogação de Minkowski. A implementação usa a biblioteca Gnu Multi-Precision (GMP) para executar todas as operações de baixo nível. O código aqui é licenciado sob os termos da licença Gnu GPLv3.

Aparentemente, a GSL (GNU Scientific Library) possui apenas a função de dilogaritmo . No entanto, seguindo uma dica do @JM, encontra-se a função Debye, que fornece a integral ulterior (até um múltiplo escalar) implementada em dupla precisão (consulte GSL 7.10 Debye Functions, pedidos de 1 a 6):

Dn(x)=nxn0xtndtet1


Software de integração simbólica, como Mathematica ou Maxima, fornece:

0xt3dtet1=6Li4(ex)6xLi3(ex)+3x2Li2(ex)+x3log(1ex)x44π415

O lado esquerdo é obviamente um valor puramente real se , mas os polilogaritmos mostrados serão de valor complexo (porque e, portanto, a igualdade depende do cancelamento total de partes imaginárias). Podemos evitar a necessidade de aritmética complexa neste caso, substituindo a expressão:x>0ex>1

0xt3dtet1=6Li4(ex)6xLi3(ex)3x2Li2(ex)x3Li1(ex)+π415

Isso é uma melhoria porque, com argumentos de polilogaritmo em , os resultados são valores puramente reais. Observe o resultado apropriado quando é zero, e isso é obtido pelo cancelamento entre o termo inicial e a constante. Assim, o erro relativo pode ser um problema para pequenos valores positivos de .[0,1]x=0x

Observe que nossa constante misteriosa é o limite superior limitador dessas integrais (aumento monótono):π4/15

0t3dtet1=Γ(4)ζ(4)=6π490

Agora podemos revisitar a pergunta do título: Como usar a função polilogaritmo em c ++? Vale ressaltar que não há implementação padrão de funções de polilogaritmo para C ou mesmo C ++ . Se o objetivo é evitar qualquer biblioteca adicional para sua implementação, é muito bom que você role suas próprias rotinas, talvez seguindo as linhas sugeridas pelo artigo de David C. Wood ao qual a resposta de GertVdE está vinculada.

Além das rotinas de multiprecisão sugeridas na primeira parte da minha resposta, existe uma biblioteca matemática de precisão dupla (livre) madura em Cephes, de Stephen L. Moshier, que implementa as versões real ( polylog) e complexa ( cpolylog) das funções especiais do polilogaritmo. Embora sua precisão dependa em parte das funções matemáticas padrão subjacentes de C, a documentação da fonte Cephes relata testes e erros teóricos de pico para pedidos de 1 a 4, aproximadamente nos limites da precisão dupla.

Como alternativa, você pode usar outro software para verificar diretamente (sem referenciar polilogaritmos) as rotinas de quadratura que você escreveu para sua integral. Como esboço nesta pergunta Math.SE , a série de potências centrada na origem da integral tem convergência limitada, mas isso pode ser atenuado usando uma expansão de fração contínua.

Para gratificação imediata, recomendo as rotinas QUADPACK de quadratura numérica (gratuita) incluídas no Maxima , especificamente quad_qag. Por exemplo, encontre a integral acima de [0,5] com este comando Maxima:

(%i1) quad_qag(x^3/(%e^x - 1), x, 0, 5, 2);
(%o1) [4.899892158330582,5.4399730923588665*10^-14,21,0]

Dos argumentos de entrada, apenas o último tem uma explicação. O quinto argumento quad_qagespecifica qual regra aplicar em quadratura adaptativa. Os valores possíveis são de 1 a 6 e oferecem sofisticação / precisão crescentes. A linha de saída fornece primeiro a quadratura numérica, seguida por uma estimativa de seu erro absoluto, o número de subintervalos / etapas usados ​​e um código de retorno (aqui zero significa que não há erro ou condições especiais encontradas).

hardmath
fonte
1
"mesmo C ++", um link melhor para funções especiais seria en.cppreference.com/w/cpp/numeric/special_math , embora a função ainda não esteja lá. É surpreendente que nem mesmo esteja na biblioteca Boost.Math boost.org/doc/libs/1_68_0/libs/math/doc/html/special.html .
alfC
1
@alfC: Obrigado pelo melhor link. Usarei isso acima para ilustrar a contínua falta de suporte padrão para essa função / família de funções.
hardmath 27/09/18
4

Antes de tudo, você deve escolher com base na sua aplicação se precisar de aritmética de alta precisão (ou seja, ficará satisfeito apenas com os resultados de precisão dupla IEEE para as funções do polilog ou precisa de maior precisão)? Se você precisar de alta precisão, poderá procurar na família de ferramentas da biblioteca GMP.

Caso contrário, você pode usar aproximações. Algumas pesquisas de literatura me indicaram este artigo . No final do artigo, há uma "tabela de seleção": com base nos argumentos dos polilogos de que você precisa, você pode selecionar uma fórmula de aproximação. Mas tenha cuidado para verificar a estabilidade e a precisão.

Se você não precisar de muitas avaliações (não em um loop aninhado), eu usaria a quadratura numérica usando o método exponencial duplo.

GertVdE
fonte
A precisão necessária seria de 10 ^ -6. Você conhece alguma outra maneira que não envolva o uso de bibliotecas extras?
Flamingohats
@ Flamingohats: então eu iria para as expressões no papel que eu vinculei na minha resposta. Qual é o seu alcance para ? x
GERVDE
@ flamingohats: Você está dizendo que precisa aproximar-se de para ou algo dessa natureza? Não entendo por que "serão necessárias apenas duas avaliações", a menos que você queira dizer que este é um requisito / ideal adicional para a quadratura ou outra aproximação. Estou pensando que podemos determinar uma aproximação polinomial ou racional que fornece a precisão necessária. x[0,10]0xt3et1dtx[0,10]
hardmath
desculpe, fiquei confuso. Aproximei a integral de 0,65 a 5,025 usando o método Trapezoidal e preciso de uma fórmula para encontrar o valor exato para que eu possa comparar a aproximação com um valor analítico. Eu sei que isso será aproximado porque é um número de ponto flutuante; portanto, uma precisão de 1e-6 será boa. Se eu puder aprender de alguma forma como inserir a função polylog no IDE, ela deve funcionar.
Flamingohats
1
@ flamingohats: ainda não está claro se você precisa de um valor único ( ) ou se você realmente precisa dele programado no seu código. Se for o primeiro, por que não usar o Sage, Euler Toolbox, ... para verificar vários valores cruciais para você (usando a implementação do polilog ou regras sofisticadas de quadratura)? Se for o segundo, implemente um método de quadratura "tradicional" (como você fez) e use novamente Sage, Euler, ... para testá-lo e validá-lo. 0.655.205t3et1dt=4.8498308528256668370925
GertVdE
3

A GSL também possui integrais Fermi-Dirac completas , para o número e . Essas funções são equivalentes aos polylogs Embora observe a restrição aos argumentos negativos do polylog para real .j j = - 1Fj(x)j Fj(x)=-Lij+1(-e-x)xj=12,12,32

Fj(x)=Lij+1(ex)
x
inocente
fonte