@c /orthopoly.texi/1.10/Fri Mar  2 00:44:47 2007//
@menu
* Introdução a polinómios ortogonais::
* Definições para polinómios ortogonais::
@end menu

@node Introdução a polinómios ortogonais, Definições para polinómios ortogonais, orthopoly, orthopoly
@section Introdução a polinómios ortogonais

@code{orthopoly} é um pacote para avaliação simbólica e numérica de
muitos tipos de polinómios ortogonais, incluindo polinómios de Chebyshev,
Laguerre, Hermite, Jacobi, Legendre, e ultraesférico
(Gegenbauer). Adicionalmentey, @code{orthopoly} inclui suporte funções esféricas segundo o critério de
Bessel, esféricas segundo o critério de Hankel, e funções harm@^onica esféricas.

Em sua maior parte, @code{orthopoly} segue as convenções de Abramowitz e Stegun
@i{Handbook of Mathematical Functions}, Chapter 22 (10th printing, December 1972);
adicionalmente, usamos Gradshteyn e Ryzhik, 
@i{Table of Integrals, Series, and Products} (1980 corrected and 
enlarged edition), e Eugen Merzbacher @i{Quantum Mechanics} (2nd edition, 1970).

@c INSTALLATION INSTRUCTIONS NO LONGER RELEVANT
@c BUT MAYBE SOME OF THESE FILES SHOULD BE MENTIONED IN ANOTHER CONTEXT
@c This will create a directory @code{orthopoly_x} (again x is the release 
@c identifier) that contains the source file @code{orthopoly.lisp}, user 
@c documentation in html and texi formats, a sample maxima initialization file 
@c @code{orthopoly-init.lisp}, a README file, a testing routine 
@c @code{test_orthopoly.mac}, and two demonstration files.

@c Start Maxima and compile orthopoly. To do this, use the command
@c 
@c (c1) compile_file("orthopoly.lisp");

Barton Willis da University de Nebraska e Kearney (UNK) escreveu
o pacote @code{orthopoly} e sua documetação. O pacote 
é liberado segundo a licença pública geral GNU (GPL).

@subsection Iniciando com orthopoly

@code{load ("orthopoly")} torna o pacote @code{orthopoly} disponível para uso.

Para encontrar o polinómio de Legendre de terceira ordem,

@c ===beg===
@c legendre_p (3, x);
@c ===end===
@example
(%i1) legendre_p (3, x);
                      3             2
             5 (1 - x)    15 (1 - x)
(%o1)      - ---------- + ----------- - 6 (1 - x) + 1
                 2             2
@end example

Para expressar esse polinómio como uma soma de potências de @var{x}, aplique @var{ratsimp} ou @var{rat}
para o resultado anterior.

@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c [ratsimp (%), rat (%)];
@c ===end===
@example
(%i2) [ratsimp (%), rat (%)];
                        3           3
                     5 x  - 3 x  5 x  - 3 x
(%o2)/R/            [----------, ----------]
                         2           2
@end example

Alternativamente, faça o segundo argumento  para @code{legendre_p} (sua variável ``principal'') 
uma expressão racional canónica (CRE)  usando @code{rat(x)} em lugar de somente @code{x}.

@c ===beg===
@c legendre_p (3, rat (x));
@c ===end===
@example
(%i1) legendre_p (3, rat (x));
                              3
                           5 x  - 3 x
(%o1)/R/                   ----------
                               2
@end example

Para avaliação em ponto flutuante, @code{orthopoly} usa uma análise de erro durante a execução
para estimar uma associação superior para o erro. Por exemplo,

@c ===beg===
@c jacobi_p (150, 2, 3, 0.2);
@c ===end===
@example
(%i1) jacobi_p (150, 2, 3, 0.2);
(%o1) interval(- 0.062017037936715, 1.533267919277521E-11)
@end example

intervalos possuem a forma @code{interval (@var{c}, @var{r})}, onde @var{c} é o
centro e @var{r} é o raio do intervalo. Uma vez que Maxima
não suporta aritmética sobre intervalos, em algumas situações, tais
como em gráficos, vai querer suprimir o erro e sair somente com o
centro do intervalo. Para fazer isso, escolha a variável de
opção @code{orthopoly_returns_intervals} para @code{false}.

@c ===beg===
@c orthopoly_returns_intervals : false;
@c jacobi_p (150, 2, 3, 0.2);
@c ===end===
@example
(%i1) orthopoly_returns_intervals : false;
(%o1)                         false
(%i2) jacobi_p (150, 2, 3, 0.2);
(%o2)                  - 0.062017037936715
@end example

Veja a secção @pxref{Avaliação em Ponto Flutuante} para maiores informações.

Muitas funções em @code{orthopoly} possuem uma propriedade @code{gradef}; dessa forma

@c ===beg===
@c diff (hermite (n, x), x);
@c diff (gen_laguerre (n, a, x), x);
@c ===end===
@example
(%i1) diff (hermite (n, x), x);
(%o1)                     2 n H     (x)
                               n - 1
(%i2) diff (gen_laguerre (n, a, x), x);
              (a)               (a)
           n L   (x) - (n + a) L     (x) unit_step(n)
              n                 n - 1
(%o2)      ------------------------------------------
                               x
@end example

A função de um único passo no segundo exemplo previne um erro que poderia
de outra forma surgir através da avaliação de @var{n} para 0.

@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c ev (%, n = 0);
@c ===end===
@example
(%i3) ev (%, n = 0);
(%o3)                           0
@end example

A propriedade @code{gradef} somente aplica para a variável ``principal''; dderivadas com
relação a outros argumentos usualmente resultam em uma mensagem de erro; por exemplo

@c ===beg===
@c diff (hermite (n, x), x);
@c diff (hermite (n, x), n);
@c ===end===
@example
(%i1) diff (hermite (n, x), x);
(%o1)                     2 n H     (x)
                               n - 1
(%i2) diff (hermite (n, x), n);

Maxima doesn't know the derivative of hermite with respect the first argument
 -- an error.  Quitting.  To debug this try debugmode(true);
@end example

Geralmente, funções em @code{orthopoly} mapeiam sobre listas e matrizes. Para
o mapeamento para avaliação total, as variáveis de opção 
@code{doallmxops} e @code{listarith} devem ambas serem @code{true} (o valor padrão).
Para ilustrar o mapeamento sobre matrizes, considere

@c ===beg===
@c hermite (2, x);
@c m : matrix ([0, x], [y, 0]);
@c hermite (2, m);
@c ===end===
@example
(%i1) hermite (2, x);
                                     2
(%o1)                    - 2 (1 - 2 x )
(%i2) m : matrix ([0, x], [y, 0]);
                            [ 0  x ]
(%o2)                       [      ]
                            [ y  0 ]
(%i3) hermite (2, m);
               [                             2  ]
               [      - 2        - 2 (1 - 2 x ) ]
(%o3)          [                                ]
               [             2                  ]
               [ - 2 (1 - 2 y )       - 2       ]
@end example

No segundo exemplo, o elemento @code{i, j} do valor
é @code{hermite (2, m[i,j])}; isso não é o mesmo que calcular
@code{-2 + 4 m . m}, como visto no próximo exemplo.

@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c -2 * matrix ([1, 0], [0, 1]) + 4 * m . m;
@c ===end===
@example
(%i4) -2 * matrix ([1, 0], [0, 1]) + 4 * m . m;
                    [ 4 x y - 2      0     ]
(%o4)               [                      ]
                    [     0      4 x y - 2 ]
@end example

Se avaliar uma função em um ponto fora do seu domínio, geralmente
@code{orthopoly} retorna uma função não avaliada. Por exemplo,

@c ===beg===
@c legendre_p (2/3, x);
@c ===end===
@example
(%i1) legendre_p (2/3, x);
(%o1)                        P   (x)
                              2/3
@end example

@code{orthopoly} suporta tradução em TeX; @code{orthopoly} também faz saídas
bidimensionais em um terminal.

@c ===beg===
@c spherical_harmonic (l, m, theta, phi);
@c tex (%);
@c jacobi_p (n, a, a - b, x/2);
@c tex (%);
@c ===end===
@example
(%i1) spherical_harmonic (l, m, theta, phi);
                          m
(%o1)                    Y (theta, phi)
                          l
(%i2) tex (%);
$$Y_@{l@}^@{m@}\left(\vartheta,\varphi\right)$$
(%o2)                         false
(%i3) jacobi_p (n, a, a - b, x/2);
                          (a, a - b) x
(%o3)                    P          (-)
                          n          2
(%i4) tex (%);
$$P_@{n@}^@{\left(a,a-b\right)@}\left(@{@{x@}\over@{2@}@}\right)$$
(%o4)                         false
@end example

@subsection Limitations

Quando uma expressão envolve muitos polinómios ortogonais com ordens
simbólicas, é possível que a expressão actualmente
tenda para zero, e ainda ocorre também que Maxima estar incapacitado
de simplificar essa expressão para zero. Se fizer uma divisão por
tal quantidade que tende a zero, poderá ficar em apuros. Por exemplo,
a seguinte expressão tende para zero para inteiros @var{n} maiores que
1, e ainda ocorre também que Maxima está incapacitado de simplificar
essa expressão para zero.

@c ===beg===
@c (2*n - 1) * legendre_p (n - 1, x) * x - n * legendre_p (n, x) + (1 - n) * legendre_p (n - 2, x);
@c ===end===
@example
(%i1) (2*n - 1) * legendre_p (n - 1, x) * x - n * legendre_p (n, x) + (1 - n) * legendre_p (n - 2, x);
(%o1)  (2 n - 1) P     (x) x - n P (x) + (1 - n) P     (x)
                  n - 1           n               n - 2
@end example

Para um @var{n} específico, podemos reduzir a expressão a zero.

@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c ev (% ,n = 10, ratsimp);
@c ===end===
@example
(%i2) ev (% ,n = 10, ratsimp);
(%o2)                           0
@end example

Geralmente, a forma polinomial de um polinómio ortogonal esteja adequada de forma hostil
para avaliaçao em ponto flutuante. Aqui está um exemplo.

@c ACTUALLY NEEDS load("orthopoly"); BEFORE ANYTHING ELSE
@c ===beg===
@c p : jacobi_p (100, 2, 3, x)$
@c subst (0.2, x, p);
@c jacobi_p (100, 2, 3, 0.2);
@c float(jacobi_p (100, 2, 3, 2/10));
@c ===end===
@example 
(%i1) p : jacobi_p (100, 2, 3, x)$

(%i2) subst (0.2, x, p);
(%o2)                3.4442767023833592E+35
(%i3) jacobi_p (100, 2, 3, 0.2);
(%o3)  interval(0.18413609135169, 6.8990300925815987E-12)
(%i4) float(jacobi_p (100, 2, 3, 2/10));
(%o4)                   0.18413609135169
@end example

O verdadeiro valor está em torno de 0.184; ess calculo suporta erro de 
cancelamento por extremo subtrativo.Expandindo o polinómio e então
avaliando, fornecendo um melhor resultado.
@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c p : expand (p)$
@c subst (0.2, x, p);
@c ===end===
@example
(%i5) p : expand(p)$
(%i6) subst (0.2, x, p);
(%o6) 0.18413609766122982
@end example

Essa não é uma regra geral; expandindo o polinómio não resulta sempre 
em expressões que são melhores adaptadas a avaliação numérica.
Com grande folga, o melhor caminho para fazer avaliação numérica é fazer um ou mais
argumentos da função serem números em ponto flutuante. Em função disso, 
algoritmos especializados em ponto flutuante são usados para avaliação.

A função @code{float} do Maxima é até certo ponto indiscriminada; se aplicar 
@code{float} a uma expressão envolvendo um polinómio ortogonal com um
grau simbólico ou um parâmetro de ordem, esses parâmetos (inteiros) podem ser 
convertido em números em ponto flutuante; após o que, a expressão não irá avaliar 
completamente. Considere

@c ===beg===
@c assoc_legendre_p (n, 1, x);
@c float (%);
@c ev (%, n=2, x=0.9);
@c ===end===
@example
(%i1) assoc_legendre_p (n, 1, x);
                               1
(%o1)                         P (x)
                               n
(%i2) float (%);
                              1.0
(%o2)                        P   (x)
                              n
(%i3) ev (%, n=2, x=0.9);
                             1.0
(%o3)                       P   (0.9)
                             2
@end example

A expressão em (%o3) não irá avaliar para um número em ponto flutuante; @code{orthopoly} não
reconhece valores em ponto flutuante em lugares onde deve haver valores inteiros. Similarmente, 
avaliação numérica da função @code{pochhammer} para ordens que
excedam @code{pochhammer_max_index} pode ser perturbador; considere

@c ===beg===
@c x :  pochhammer (1, 10), pochhammer_max_index : 5;
@c ===end===
@example
(%i1) x :  pochhammer (1, 10), pochhammer_max_index : 5;
(%o1)                         (1)
                                 10
@end example

Aplicando @code{float} não avalia @var{x} para um número em ponto flutuante

@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c float (x);
@c ===end===
@example
(%i2) float (x);
(%o2)                       (1.0)
                                 10.0
@end example

Para avaliar @var{x} para um número em ponto flutuante, irá precisar associar
@code{pochhammer_max_index} a 11 ou mais e aplicar @code{float} a @var{x}.

@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c float (x), pochhammer_max_index : 11;
@c ===end===
@example
(%i3) float (x), pochhammer_max_index : 11;
(%o3)                       3628800.0
@end example

O valor padrão de @code{pochhammer_max_index} é 100;
modifique esse valor após chama @code{orthopoly}.

Finalmente, tenha consciência que os livros citados nas referências adotam diferentes definições de 
polinómios ortogonais; geralmente adotamos as convenções 
citadas nas convenções de Abramowitz e Stegun.

Antes de suspeitar de um erro no pacote @code{orthopoly}, verifique alguns casos especiais 
para determinar se suas definições coincidem com aquelas usadas por @code{orthopoly}. 
Definitions muitas vezes diferem por uma normalização; ocasionalmente, autores
utilizam versões ``modificadas'' das funções que fazem a família
ortogonal sobre um intervalo diferente do intervalo @math{(-1, 1)}. Para definir, por exemplo,
um polinómio de Legendre que é ortogonal a @math{(0, 1)}, defina

@c ===beg===
@c shifted_legendre_p (n, x) := legendre_p (n, 2*x - 1)$
@c shifted_legendre_p (2, rat (x));
@c legendre_p (2, rat (x));
@c ===end===
@example
(%i1) shifted_legendre_p (n, x) := legendre_p (n, 2*x - 1)$

(%i2) shifted_legendre_p (2, rat (x));
                            2
(%o2)/R/                 6 x  - 6 x + 1
(%i3) legendre_p (2, rat (x));
                               2
                            3 x  - 1
(%o3)/R/                    --------
                               2
@end example

@anchor{Avaliação em Ponto Flutuante}
@subsection Avaliação em Ponto Flutuante

Muitas funções em @code{orthopoly} utilizam análise de erro durante a execução para 
estimar o erro em avaliações em ponto flutuante; as 
exceções são funções de Bessel esféricas e os polinómios associados de
Legendre do segundo tipo. Para avaliações numéricas, as funções 
de Bessel esféricas chamam funções da colecção de programas @code{SLATEC}. Nenhum método especializado é usado
para avaliação numérica dos polinómios associados  de Legendre do
segundo tipo.

A análise de erro durante a execução ignora erros que são de segunda ordem ou maior
na máquina (também conhecida como perda de algarismos). A análise de erro durante a execução também
ignora alguns poucos outros tipos de erro. É possível (embora não provável) 
que o erro actual exceda o estimado.

Intervalos possuem a forma @code{interval (@var{c}, @var{r})}, onde @var{c} é o centro 
do intervalo e @var{r} é seu raio. O 
centro de um intervalo pode sr um número complexo, e o raio é sempre um número real positivo.

Aqui está um exemplo.

@c ===beg===
@c fpprec : 50$
@c y0 : jacobi_p (100, 2, 3, 0.2);
@c y1 : bfloat (jacobi_p (100, 2, 3, 1/5));
@c ===end===

@example
(%i1) fpprec : 50$

(%i2) y0 : jacobi_p (100, 2, 3, 0.2);
(%o2) interval(0.1841360913516871, 6.8990300925815987E-12)
(%i3) y1 : bfloat (jacobi_p (100, 2, 3, 1/5));
(%o3) 1.8413609135168563091370224958913493690868904463668b-1
@end example

Vamos testar o quanto o erro actual é é menor que o erro estimado

@c CONTINUING PREVIOUS EXAMPLE HERE
@c ===beg===
@c is (abs (part (y0, 1) - y1) < part (y0, 2));
@c ===end===
@example
(%i4) is (abs (part (y0, 1) - y1) < part (y0, 2));
(%o4)                         true
@end example

Realmente, por esse exemplo o erro estimado é um maior que
o erro verdadeiro.

Maxima não suporta aritmética sobre intervalos.

@c ===beg===
@c legendre_p (7, 0.1) + legendre_p (8, 0.1);
@c ===end===
@example
(%i1) legendre_p (7, 0.1) + legendre_p (8, 0.1);
(%o1) interval(0.18032072148437508, 3.1477135311021797E-15)
        + interval(- 0.19949294375000004, 3.3769353084291579E-15)
@end example

Um utilizador pode definir operadores aritméticos que fazem matemática de intervalos. Para
definir adição de intervalos, podemos definir

@c ===beg===
@c infix ("@+")$
@c "@+"(x,y) := interval (part (x, 1) + part (y, 1), part (x, 2) + part (y, 2))$
@c legendre_p (7, 0.1) @+ legendre_p (8, 0.1);
@c ===end===
@example
(%i1) infix ("@@+")$

(%i2) "@@+"(x,y) := interval (part (x, 1) + part (y, 1), part (x, 2) + part (y, 2))$

(%i3) legendre_p (7, 0.1) @@+ legendre_p (8, 0.1);
(%o3) interval(- 0.019172222265624955, 6.5246488395313372E-15)
@end example

As rotinas eseciais em ponto flutuante são chamadas quando os argumentos
forem complexos.  Por exemplo,

@c ===beg===
@c legendre_p (10, 2 + 3.0*%i);
@c ===end===
@example
(%i1) legendre_p (10, 2 + 3.0*%i);
(%o1) interval(- 3.876378825E+7 %i - 6.0787748E+7, 
                                           1.2089173052721777E-6)
@end example

Let's compare this to the true value.

@c ===beg===
@c float (expand (legendre_p (10, 2 + 3*%i)));
@c ===end===
@example
(%i1) float (expand (legendre_p (10, 2 + 3*%i)));
(%o1)          - 3.876378825E+7 %i - 6.0787748E+7
@end example

Adicionalmente, quando os argumentos forem grandes números em ponto flutuante, as rotinas especiais
de ponto flutuante são chamadas; todavia, tos grandes números em ponto flutuante são convertidos para números em ponto flutuante de dupla precisão
e o resultado final é número em ponto flutuante de precisão dupla.

@c ===beg===
@c ultraspherical (150, 0.5b0, 0.9b0);
@c ===end===
@example
(%i1) ultraspherical (150, 0.5b0, 0.9b0);
(%o1) interval(- 0.043009481257265, 3.3750051301228864E-14)
@end example

@subsection Gráficos e @code{orthopoly}

Para desenhar gráficos de expressões que envolvem polinómios
ortogonais, deverá fazer duas coisas:
@enumerate
@item 
Escolher a variável de opção @code{orthopoly_returns_intervals} para @code{false},
@item
Colocar apóstrofo em qualquer chamada a funções do pacote @code{orthopoly}.
@end enumerate
Se chamadas a funções não receberem apóstrofo, Maxima irá avaliá-las para polinómios antes 
de montar o gráfico; consequêntemente, as rotinas especializadas em ponto flutuante não serão chamadas.
Aqui está um exemplo de como montar o gráfico de uma expressão que envolve
um polinómio de Legendre.

@c ===beg===
@c plot2d ('(legendre_p (5, x)), [x, 0, 1]), orthopoly_returns_intervals : false;
@c ===end===
@example
(%i1) plot2d ('(legendre_p (5, x)), [x, 0, 1]), orthopoly_returns_intervals : false;
(%o1)
@end example

@ifnotinfo
@figure{orthopoly1}
@end ifnotinfo

A expressão @i{completa} @code{legendre_p (5, x)} recebe apóstrofo; isso é 
diferente de apenas colocar apóstrofo no nome da função usando @code{'legendre_p (5, @var{x})}.

@subsection Funções Diversas

O pacote @code{orthopoly} define o
síbolo de Pochhammer e uma função de passo de unidade. @code{orthopoly} utiliza 
a função delta de Kronecker e a função de passo de unidade em
declarações @code{gradef}.

Para converter os símbolos Pochhammer em quocientes da funções gama,
use @code{makegamma}.

@c ===beg===
@c makegamma (pochhammer (x, n));
@c makegamma (pochhammer (1/2, 1/2));
@c ===end===
@example
(%i1) makegamma (pochhammer (x, n));
                          gamma(x + n)
(%o1)                     ------------
                            gamma(x)
(%i2) makegamma (pochhammer (1/2, 1/2));
                                1
(%o2)                       ---------
                            sqrt(%pi)
@end example

Derivadas de símbolos de Pochhammer são fornecidas em termos de @code{psi}
function.

@c ===beg===
@c diff (pochhammer (x, n), x);
@c diff (pochhammer (x, n), n);
@c ===end===
@example
(%i1) diff (pochhammer (x, n), x);
(%o1)             (x)  (psi (x + n) - psi (x))
                     n     0             0
(%i2) diff (pochhammer (x, n), n);
(%o2)                   (x)  psi (x + n)
                           n    0
@end example

É preciso ser cuidadoso com expressões como (%o1); a diferença das
funções @code{psi} possuem polinómios quando @code{@var{x} = -1, -2, .., -@var{n}}. Esses polinómios
cacelam-se com factores em @code{pochhammer (@var{x}, @var{n})} fazendo da derivada um polinómio
de grau @code{@var{n} - 1} quando @var{n} for um inteiro positivo.

O símbolo de Pochhammer é definido de ordens negativas até sua
representação como um quociente de funções gama. Considere

@c ===beg===
@c q : makegamma (pochhammer (x, n));
@c sublis ([x=11/3, n= -6], q);
@c ===end===
@example
(%i1) q : makegamma (pochhammer (x, n));
                          gamma(x + n)
(%o1)                     ------------
                            gamma(x)
(%i2) sublis ([x=11/3, n= -6], q);
                               729
(%o2)                        - ----
                               2240
@end example

Alternativamente, podemos tomar ese resultado directamente.

@c ===beg===
@c pochhammer (11/3, -6);
@c ===end===
@example
(%i1) pochhammer (11/3, -6);
                               729
(%o1)                        - ----
                               2240
@end example

A função passo de unidade é contínua à esquerda; dessa forma

@c ===beg===
@c [unit_step (-1/10), unit_step (0), unit_step (1/10)];
@c ===end===
@example
(%i1) [unit_step (-1/10), unit_step (0), unit_step (1/10)];
(%o1)                       [0, 0, 1]
@end example

Se precisar de uma função de degrau unitário que seja
ou contínua à esquerda ou contínua à
direita do zero, defina a sua própria função usando
@code{signum}; por exemplo,

@c ===beg===
@c xunit_step (x) := (1 + signum (x))/2$
@c [xunit_step (-1/10), xunit_step (0), xunit_step (1/10)];
@c ===end===
@example
(%i1) xunit_step (x) := (1 + signum (x))/2$

(%i2) [xunit_step (-1/10), xunit_step (0), xunit_step (1/10)];
                                1
(%o2)                       [0, -, 1]
                                2
@end example

Não redefina a própria @code{unit_step}; alguns código em @code{orthopoly}
requerem que a função de passo de unidade seja contínua à esquerda.

@subsection Algorítmos

Geralmente, @code{orthopoly} faz avaliações simbólicas pelo uso de uma representação 
hipergeométrica de polinómios ortogonais. As funções 
hipegeométricas são avaliadas usando as funções (não documetadas) @code{hypergeo11} 
e @code{hypergeo21}. As excessões são as funções de Bessel metade inteiras 
e a função de Legendre associada de segundo tipo. As funções de Bessel metade inteiras são
avaliadas usando uma representação explícita, e a função de Legendre 
associada de segundo tipo é avaliada usando recursividade.

Para avaliação em ponto flutuante, nós novamente convertemos muitas fuções em
uma forma hipergeométrica; nós avaliamos as funções hipergeométricas usando 
recursividade para frente. Novamente, as excessões são as funções de Bessel metade inteiras 
e a função de Legendre associada de segundo tipo. Numericamente, 
as funções de Bessel meio inteiras são avaliadas usando o código SLATEC.

@node Definições para polinómios ortogonais,  , Introdução a polinómios ortogonais, orthopoly
@section Definições para polinómios ortogonais

@deffn {Função} assoc_legendre_p (@var{n}, @var{m}, @var{x})
As funções de Legendre associadas de primeiro tipo. 

Referência: Abramowitz e Stegun, equações 22.5.37, página 779, 8.6.6
(segunda equação), página 334, e 8.2.5, página 333.
@end deffn

@deffn {Função} assoc_legendre_q (@var{n}, @var{m}, @var{x})
A função de Legendre associada de segundo tipo.

Referência: Abramowitz e Stegun, equação 8.5.3 e 8.1.8.
@end deffn

@deffn {Função} chebyshev_t (@var{n}, @var{x})
A função de Chebyshev de primeiro tipo.

Referência: Abramowitz e Stegun, equação 22.5.47,página 779.
@end deffn

@deffn {Função} chebyshev_u (@var{n}, @var{x})
A função de Chebyshev do segundo tipo.

Referência: Abramowitz e Stegun, equação 22.5.48,página 779.
@end deffn

@deffn {Função} gen_laguerre (@var{n}, @var{a}, @var{x})
O poli@^omio generalizado de Laguerre.

Referência: Abramowitz e Stegun, equação 22.5.54,página 780.
@end deffn

@deffn {Função} hermite (@var{n}, @var{x})
O polinómio de Hermite.

Referência: Abramowitz e Stegun, equação 22.5.55,página 780.
@end deffn

@deffn {Função} intervalp (@var{e})
Retorna @code{true} se a entrada for um intervalo e retorna @code{false} se não for. 
@end deffn

@deffn {Função} jacobi_p (@var{n}, @var{a}, @var{b}, @var{x})
o polinómio de Jacobi.

Os polinómios de Jacobi são actualmente definidos para todo
@var{a} e @var{b}; todavia, o peso do polinómio de
Jacobi @code{(1 - @var{x})^@var{a} (1 + @var{x})^@var{b}} não é integrável para @code{@var{a} <= -1} ou
@code{@var{b} <= -1}. 

Referência: Abramowitz e Stegun, equação 22.5.42,página 779.
@end deffn

@deffn {Função} laguerre (@var{n}, @var{x})
O polinómio de Laguerre.

Referência: Abramowitz e Stegun, equatções 22.5.16 e 22.5.54,página 780.
@end deffn

@deffn {Função} legendre_p (@var{n}, @var{x})
O polinómio de Legendre de primeiro tipo.

Referência: Abramowitz e Stegun, equações 22.5.50 e 22.5.51,página 779.
@end deffn

@deffn {Função} legendre_q (@var{n}, @var{x})
O polinómio de Legendre de primeiro tipo.

Referência: Abramowitz e Stegun, equações 8.5.3 e 8.1.8.
@end deffn

@deffn {Função} orthopoly_recur (@var{f}, @var{args})
Retorna uma relação recursiva para a família de funções ortogonais
@var{f} com argumentos @var{args}. A recursividade é com 
relação ao grau do polinómio.

@c ===beg===
@c orthopoly_recur (legendre_p, [n, x]);
@c ===end===
@example
(%i1) orthopoly_recur (legendre_p, [n, x]);
                (2 n - 1) P     (x) x + (1 - n) P     (x)
                           n - 1                 n - 2
(%o1)   P (x) = -----------------------------------------
         n                          n
@end example

O segundo argumento a @code{orthopoly_recur} deve ser uma lista com o 
número correcto de argumentos para a função @var{f}; se o número de argumentos não for o correcto, 
Maxima sinaliza com um erro.

@c ===beg===
@c orthopoly_recur (jacobi_p, [n, x]);
@c ===end===
@example
(%i1) orthopoly_recur (jacobi_p, [n, x]);

Function jacobi_p needs 4 arguments, instead it received 2
 -- an error.  Quitting.  To debug this try debugmode(true);
@end example

Adicionalmente, quando @var{f} não for o nome de uma das
famílias de polinómios ortogonais, um erro é sinalizado.

@c ===beg===
@c orthopoly_recur (foo, [n, x]);
@c ===end===
@example
(%i1) orthopoly_recur (foo, [n, x]);

A recursion relation for foo isn't known to Maxima
 -- an error.  Quitting.  To debug this try debugmode(true);
@end example
@end deffn

@defvr {Variable} orthopoly_returns_intervals
Valor por omissão: @code{true}

Quando @code{orthopoly_returns_intervals} for @code{true}, resultados em ponto flutuante são retornados na
forma @code{interval (@var{c}, @var{r})}, onde @var{c} é o centro de um intervalo
e @var{r} é seu raio. O centro pode ser um número complexo; nesse
caso, o intervalo é um disco no plano complexo.
@end defvr

@deffn {Função} orthopoly_weight (@var{f}, @var{args})

Retorna uma lista de três elementos; o primeiro elemento é 
a fórmula do peso para a família de polinómios ortogonais
@var{f} com argumentos fornecidos pela lista @var{args}; os 
segundos e terceiros elementos fornecem os pontos finais inferior e superior
do intervalo de ortogonalidade. Por exemplo,

@c ===beg===
@c w : orthopoly_weight (hermite, [n, x]);
@c integrate (w[1] * hermite (3, x) * hermite (2, x), x, w[2], w[3]);
@c ===end===
@example
(%i1) w : orthopoly_weight (hermite, [n, x]);
                            2
                         - x
(%o1)                 [%e    , - inf, inf]
(%i2) integrate (w[1] * hermite (3, x) * hermite (2, x), x, w[2], w[3]);
(%o2)                           0
@end example

A variável principal de @var{f} deve ser um símbolo; Se não for, Maxima
sinaliza com um erro. 

@end deffn

@deffn {Função} pochhammer (@var{n}, @var{x})
O símbolo de Pochhammer. Para inteiros não negativos @var{n} com
@code{@var{n} <= pochhammer_max_index}, a expressão @code{pochhammer (@var{x}, @var{n})} 
avalia para o produto @code{@var{x} (@var{x} + 1) (@var{x} + 2) ... (@var{x} + n - 1)}
when @code{@var{n} > 0} e
para 1 quando @code{@var{n} = 0}. Para valores negativos de @var{n},
@code{pochhammer (@var{x}, @var{n})} é definido como @code{(-1)^@var{n} / pochhammer (1 - @var{x}, -@var{n})}.
Dessa forma

@c ===beg===
@c pochhammer (x, 3);
@c pochhammer (x, -3);
@c ===end===
@example
(%i1) pochhammer (x, 3);
(%o1)                   x (x + 1) (x + 2)
(%i2) pochhammer (x, -3);
                                 1
(%o2)               - -----------------------
                      (1 - x) (2 - x) (3 - x)
@end example

Para converter um símbolo de Pochhammer em um quociente de funções gama,
(veja Abramowitz e Stegun, equação 6.1.22) use @code{makegamma}; por exemplo 

@c ===beg===
@c makegamma (pochhammer (x, n));
@c ===end===
@example
(%i1) makegamma (pochhammer (x, n));
                          gamma(x + n)
(%o1)                     ------------
                            gamma(x)
@end example

Quando @var{n} exceder @code{pochhammer_max_index} ou quando @var{n} 
for simbólico, @code{pochhammer} retorna uma forma substantiva.

@c ===beg===
@c pochhammer (x, n);
@c ===end===
@example
(%i1) pochhammer (x, n);
(%o1)                         (x)
                                 n
@end example
@end deffn

@defvr {Variável} pochhammer_max_index
Valor por omissão: 100

@code{pochhammer (@var{n}, @var{x})} expande para um produto se e somente se
@code{@var{n} <= pochhammer_max_index}.

Exemplos:

@c ===beg===
@c pochhammer (x, 3), pochhammer_max_index : 3;
@c pochhammer (x, 4), pochhammer_max_index : 3;
@c ===end===
@example
(%i1) pochhammer (x, 3), pochhammer_max_index : 3;
(%o1)                   x (x + 1) (x + 2)
(%i2) pochhammer (x, 4), pochhammer_max_index : 3;
(%o2)                         (x)
                                 4
@end example

Referência: Abramowitz e Stegun, equação 6.1.16,página 256.
@end defvr

@deffn {Função} spherical_bessel_j (@var{n}, @var{x})
A Função de Bessel esférica de primeiro tipo.

Referência: Abramowitz e Stegun, equações 10.1.8,página 437 e 10.1.15,página 439.
@end deffn

@deffn {Função} spherical_bessel_y (@var{n}, @var{x})
A Função de Bessel esférica de segundo tipo. 

Referência: Abramowitz e Stegun, equações 10.1.9,página 437 e 10.1.15,página 439.
@end deffn

@deffn {Função} spherical_hankel1 (@var{n}, @var{x})
A Função de Hankel esférica de
primeiro tipo.

Referência: Abramowitz e Stegun, equação 10.1.36,página 439.
@end deffn

@deffn {Função} spherical_hankel2 (@var{n}, @var{x})
A Função de Hankel esférica de segundo tipo.

Referência: Abramowitz e Stegun, equação 10.1.17,página 439.
@end deffn

@deffn {Função} spherical_harmonic (@var{n}, @var{m}, @var{x}, @var{y})
A função arm@^onica esférica.

Referência: Merzbacher 9.64.
@end deffn

@deffn {Função} unit_step (@var{x})
A função de passo de unidade contínua à esquerda; dessa forma
@code{unit_step (@var{x})} tende para @code{@var{x} <= 0} e é igual a
1 para @code{@var{x} > 0}.

Se quiser uma função de degrau unitário que tome o
valor 1/2 em zero, use @code{(1 + signum (@var{x}))/2}.
@end deffn

@deffn {Função} ultraspherical (@var{n}, @var{a}, @var{x})
A função polin@^omial ultraesférica (também conhecida como função polinomial de Gegenbauer).

Referência: Abramowitz e Stegun, equação 22.5.46,página 779.
@end deffn

