Como funcionam as funções trigonométricas?

102

Portanto, na matemática do ensino médio e provavelmente na faculdade, aprendemos como usar as funções trigonométricas, o que elas fazem e que tipo de problemas resolvem. Mas eles sempre foram apresentados a mim como uma caixa preta. Se você precisa do seno ou cosseno de alguma coisa, aperte o botão sen ou cos da calculadora e pronto. O que é ótimo.

O que me pergunto é como as funções trigonométricas são normalmente implementadas.

Jurassic_C
fonte
Você está confuso sobre o que são funções trigonométricas ou como elas são implementadas?
Kyle Cronin
15
Eu sei o que eles são. Eu sei o que eles fazem. Eu sei como determinar o que preciso para que propósito. Posso contar tudo sobre a relação entre ângulos e distâncias. O que eu procurava era mais na linha da resposta de John D. Cook. E todos os outros que mencionaram algoritmos reais
Jurassic_C
Essa é uma boa pergunta. Por exemplo, seno, cosseno e tangente são funções transcendentais e difíceis de resolver ... Por outro lado, elas podem ser definidas usando uma expansão de série de Taylor simples que lhe dará a resposta correta até qualquer grau finito de precisão requeridos.
Alex

Respostas:

144

Primeiro, você precisa fazer algum tipo de redução de alcance. As funções trigonométricas são periódicas, portanto, você precisa reduzir os argumentos a um intervalo padrão. Para começar, você pode reduzir os ângulos para ficar entre 0 e 360 ​​graus. Mas, ao usar algumas identidades, você percebe que poderia sobreviver com menos. Se você calcular senos e cossenos para ângulos entre 0 e 45 graus, você pode iniciar seu caminho para calcular todas as funções trigonométricas para todos os ângulos.

Depois de reduzir seu argumento, a maioria dos chips usa um algoritmo CORDIC para calcular os senos e cossenos. Você pode ouvir as pessoas dizerem que os computadores usam a série Taylor. Parece razoável, mas não é verdade. Os algoritmos CORDIC são muito mais adequados para uma implementação de hardware eficiente . ( Bibliotecas de software podem usar a série Taylor, digamos, em hardware que não oferece suporte a funções trigonométricas.) Pode haver algum processamento adicional, usando o algoritmo CORDIC para obter respostas razoavelmente boas, mas fazendo algo diferente para melhorar a precisão.

Existem alguns refinamentos para o acima. Por exemplo, para ângulos muito pequenos theta (em radianos), sin (theta) = theta para toda a precisão que você tem, então é mais eficiente simplesmente retornar theta do que usar algum outro algoritmo. Portanto, na prática, há uma grande quantidade de lógica de caso especial para extrair todo o desempenho e precisão possíveis. Chips com mercados menores podem não ter tanto esforço de otimização.

John D. Cook
fonte
4
Ótima resposta - embora o CORDIC realmente não precise de redução de intervalo per se (na verdade, é essencialmente um algoritmo de redução de intervalo por si só); ele funciona bem para ângulos entre -pi / 2 e + pi / 2, então você só precisa fazer uma rotação vetorial de 180 graus para ângulos fora desse intervalo.
Jason S
3
As implementações que usam uma aproximação polinomial podem frequentemente usar séries de Taylor, mas normalmente devem usar coeficientes que foram determinados com o algoritmo Remez. lolengine.net/blog/2011/12/21/better-function-approximations
Pascal Cuoq
1
Observe que a tabela de valores usada pelo CORDIC deve ser pré-calculada. Portanto, Taylor ainda pode ser usado em "tempo de compilação".
Ruibarbo
2
Parece que essa resposta contradiz a resposta aceita de alta classificação para esta pergunta semelhante: stackoverflow.com/questions/2284860/… . Esta resposta diz que a função sin () é implementada principalmente no nível de hardware, enquanto a outra diz em C.
Perry
48

editar: Jack Ganssle tem uma discussão decente em seu livro sobre sistemas embarcados, "The Firmware Handbook" .

Para sua informação: se você tiver restrições de precisão e desempenho, a série de Taylor não deve ser usada para aproximar funções para fins numéricos. (Guarde-os para seus cursos de Cálculo.) Eles fazem uso da analiticidade de uma função em um único ponto , por exemplo, o fato de que todas as suas derivadas existem naquele ponto. Eles não convergem necessariamente no intervalo de interesse. Freqüentemente, eles fazem um péssimo trabalho de distribuição da precisão da aproximação da função para serem "perfeitos" bem perto do ponto de avaliação; o erro geralmente aumenta conforme você se afasta dele. E se você tiver uma função com qualquer derivada não contínua (por exemplo, ondas quadradas, ondas triangulares e suas integrais), uma série de Taylor lhe dará a resposta errada.

A melhor solução "fácil", ao usar um polinômio de grau máximo N para aproximar uma dada função f (x) em um intervalo x0 <x <x1, é da aproximação de Chebyshev ; veja Receitas Numéricas para uma boa discussão. Observe que Tj (x) e Tk (x) no artigo Wolfram ao qual vinculei usaram o cos e o cosseno inverso, esses são polinômios e, na prática, você usa uma fórmula de recorrência para obter os coeficientes. Novamente, consulte Receitas numéricas.

editar: Wikipedia tem um artigo semi-decente sobre a teoria da aproximação . Uma das fontes que eles citam (Hart, "Computer Approximations") está esgotada (e as cópias usadas tendem a ser caras), mas dá muitos detalhes sobre coisas como essa. (Jack Ganssle menciona isso na edição 39 de seu boletim informativo The Embedded Muse .)

edição 2: Aqui estão algumas métricas de erro tangíveis (veja abaixo) para Taylor vs. Chebyshev para sin (x). Alguns pontos importantes a serem observados:

  1. que o erro máximo de uma aproximação da série de Taylor em um determinado intervalo é muito maior do que o erro máximo de uma aproximação de Chebyshev do mesmo grau. (Para quase o mesmo erro, você pode se safar com um termo a menos com Chebyshev, o que significa desempenho mais rápido)
  2. A redução de alcance é uma grande vitória. Isso ocorre porque a contribuição de polinômios de ordem superior diminui quando o intervalo de aproximação é menor.
  3. Se você não conseguir reduzir o intervalo, seus coeficientes precisam ser armazenados com mais precisão.

Não me interpretem mal: a série de Taylor funcionará corretamente para seno / cosseno (com precisão razoável para o intervalo -pi / 2 a + pi / 2; tecnicamente, com termos suficientes, você pode alcançar qualquer precisão desejada para todas as entradas reais, mas tente calcular cos (100) usando a série de Taylor e você não pode fazer isso a menos que use aritmética de precisão arbitrária). Se eu estivesse preso em uma ilha deserta com uma calculadora não científica e precisasse calcular seno e cosseno, provavelmente usaria a série de Taylor, já que os coeficientes são fáceis de lembrar. Mas as aplicações do mundo real para ter que escrever suas próprias funções sin () ou cos () são raras o suficiente para que seja melhor usar uma implementação eficiente para atingir a precisão desejada - o que a série de Taylor não é .

Intervalo = -pi / 2 a + pi / 2, grau 5 (3 termos)

  • Taylor: erro máximo em torno 4.5e-3, f (x) = xx 3 /6 + x 5 /120
  • Chebyshev: erro máximo em torno de 7e-5, f (x) = 0,99996949x-0,1656700x 3 + 0,0075134x 5

Faixa = -pi / 2 a + pi / 2, grau 7 (4 termos)

  • Taylor: erro máximo em torno 1.5e-4, f (x) = xx 3 /6 + x 5 /120 x 7 /5040
  • Chebyshev: erro máximo em torno de 6e-7, f (x) = 0,99999660x-0,16664824x 3 + 0,00830629x 5 -0,00018363x 7

Intervalo = -pi / 4 a + pi / 4, grau 3 (2 termos)

  • Taylor: erro máximo em torno 2.5e-3, f (x) = xx 3 /6
  • Chebyshev: erro máximo em torno de 1,5e-4, f (x) = 0,999x-0,1603x 3

Faixa = -pi / 4 a + pi / 4, grau 5 (3 termos)

  • Taylor: erro máximo em torno 3.5e-5, f (x) = xx 3 /6 + x 5
  • Chebyshev: erro máximo em torno de 6e-7, f (x) = 0,999995x-0,1666016x 3 + 0,0081215x 5

Faixa = -pi / 4 a + pi / 4, grau 7 (4 termos)

  • Taylor: erro máximo em torno 3e-7, F (x) = xx 3 /6 + x 5 /120 x 7 /5040
  • Chebyshev: erro máximo em torno de 1,2e-9, f (x) = 0,9999999986x-0,1666666367x 3 + 0,008331584x 5 -0,000194621x 7
Jason S
fonte
2
Este comentário está errado. Existe uma hora e um lugar para cada aproximação. Se você não conhece análise suficiente para determinar a região de convergência para QUALQUER aproximação de série, você NÃO deve usá-la. Isso vale para as séries Taylor, Chebyshev, Padé, etc. As séries de Taylor costumam ser boas o suficiente.
kquinn
4
: encolher de ombros: Não sei sobre você, mas nunca me interessei em avaliar uma função em um pequeno bairro em torno de apenas um ponto. Mesmo um ajuste rápido de mínimos quadrados em um intervalo é muito fácil de fazer. Qualquer pessoa que esteja usando a série Taylor está perdendo o ponto.
Jason S
1
@kquinn: a região de convergência para as aproximações de Chebyshev não é um conceito útil, pois o intervalo sobre o qual são calculadas é uma entrada explícita para o processo.
Jason S
2
Upvoting porque o respondente sabia que Hart existe. : smile: Hart é a referência clássica aqui, embora tenha sido difícil de encontrar quando comprei uma cópia (impressa) há 25 anos. Vale a pena cada centavo. A redução de alcance sempre que possível, juntamente com uma aproximação apropriada, seja Pade, Chebychev, até mesmo a série de Taylor conforme apropriado, é uma boa abordagem. Aproximants Pade ou Chebychev são geralmente a melhor escolha em relação a uma série de Taylor.
3
??? Como é que isso é diferente? A série de Taylor até o 17º grau para calcular sin (x) de -2pi a + 2pi pode provavelmente ser batida por Chebyshev com um polinômio de 7º ou 9º grau. Eu não teria nenhum problema em fazer a declaração: "Se você tiver limitações de tempo ao cortar árvores, não deve usar uma serra manual. Use uma serra elétrica." Talvez eu deva reformular de "não deveria" para algo como "Eu não recomendaria usar a série Taylor". Claro, você poderia usar a série Taylor em alguns casos, mas sua precisão e desempenho serão problemáticos. Por desempenho, quero dizer tempo de execução da CPU.
Jason S
14

Eu acredito que eles são calculados usando Taylor Series ou CORDIC . Alguns aplicativos que fazem uso intenso de funções trigonométricas (jogos, gráficos) constroem tabelas trigonométricas ao iniciar, para que possam apenas consultar os valores em vez de recalculá-los indefinidamente.

Jon Galloway
fonte
6

Confira o artigo da Wikipedia sobre funções trigonométricas. Um bom lugar para aprender sobre como realmente implementá-los no código são as receitas numéricas .

Não sou muito matemático, mas meu entendimento de de onde sin, cos e tan "vêm" é que eles são, de certa forma, observados quando você está trabalhando com triângulos retangulares. Se você tirar medidas dos comprimentos dos lados de um monte de triângulos retângulos diferentes e plotar os pontos em um gráfico, você pode obter sin, cos e tan com isso. Como Harper Shelby aponta, as funções são simplesmente definidas como propriedades de triângulos retangulares.

Uma compreensão mais sofisticada é alcançada entendendo como essas proporções se relacionam com a geometria do círculo, o que leva aos radianos e toda essa bondade. Está tudo na entrada da Wikipedia.

Parappa
fonte
1

Mais comumente para computadores, a representação de séries de potências é usada para calcular senos e cossenos e estes são usados ​​para outras funções trigonométricas. Expandir essas séries para cerca de 8 termos calcula os valores necessários para uma precisão próxima ao épsilon da máquina (menor número de ponto flutuante diferente de zero que pode ser mantido).

O método CORDIC é mais rápido porque é implementado no hardware, mas é usado principalmente para sistemas embarcados e não para computadores padrão.

Joshua Howard
fonte
0

Eu gostaria de estender a resposta fornecida por @Jason S. Usando um método de subdivisão de domínio semelhante ao descrito por @Jason S e usando aproximações de série de Maclaurin, uma média (2-3) X speedup sobre tan (), sin () As funções, cos (), atan (), asin () e acos () construídas no compilador gcc com otimização -O3 foram alcançadas. As melhores funções de aproximação da série Maclaurin descritas abaixo alcançaram precisão de precisão dupla.

Para as funções tan (), sin () e cos (), e para simplificar, um domínio sobreposto de 0 a 2pi + pi / 80 foi dividido em 81 intervalos iguais com "pontos de ancoragem" em pi / 80, 3pi / 80, ..., 161pi / 80. Em seguida, tan (), sin () e cos () desses 81 pontos de ancoragem foram avaliados e armazenados. Com a ajuda de identidades trigonométricas, uma única função da série Maclaurin foi desenvolvida para cada função trigonométrica. Qualquer ângulo entre ± infinito pode ser submetido às funções de aproximação trigonométrica porque as funções primeiro traduzem o ângulo de entrada para o domínio de 0 a 2pi. Este overhead de tradução está incluído no overhead de aproximação.

Métodos semelhantes foram desenvolvidos para as funções atan (), asin () e acos (), onde um domínio sobreposto de -1,0 a 1,1 foi dividido em 21 intervalos iguais com pontos de ancoragem em -19/20, -17/20, .. ., 19/20, 21/20. Então, apenas atan () desses 21 pontos de ancoragem foi armazenado. Novamente, com a ajuda de identidades trigonométricas inversas, uma única função da série Maclaurin foi desenvolvida para a função atan (). Os resultados da função atan () foram então usados ​​para aproximar asin () e acos ().

Como todas as funções de aproximação de trigonometria inversa são baseadas na função de aproximação atan (), qualquer valor de entrada de argumento de precisão dupla é permitido. No entanto, a entrada do argumento para as funções de aproximação asin () e acos () é truncada para o domínio ± 1 porque qualquer valor fora dele não faz sentido.

Para testar as funções de aproximação, um bilhão de avaliações de funções aleatórias foram forçadas a serem avaliadas (ou seja, o compilador de otimização -O3 não teve permissão para ignorar a avaliação de algo porque algum resultado computado não seria usado.) Para remover o viés de avaliar um bilhão números aleatórios e processamento dos resultados, o custo de uma execução sem avaliar qualquer trigonometria ou função trigonométrica inversa foi executado primeiro. Essa tendência foi então subtraída de cada teste para obter uma aproximação mais representativa do tempo real de avaliação da função.

Tabela 2. Tempo gasto em segundos para executar a função ou funções indicadas um bilhão de vezes. As estimativas são obtidas subtraindo o custo de tempo de avaliação de um bilhão de números aleatórios mostrados na primeira linha da Tabela 1 das linhas restantes na Tabela 1.

Tempo gasto no bronzeado (): 18,0515 18,2545

Tempo gasto em TAN3 (): 5,93853 6,02349

Tempo gasto em TAN4 (): 6,72216 6,99134

Tempo gasto em sin () e cos (): 19,4052 19,4311

Tempo gasto em SINCOS3 (): 7.85564 7.92844

Tempo gasto em SINCOS4 (): 9.36672 9.57946

Tempo gasto em atan (): 15,7160 15,6599

Tempo gasto em ATAN1 (): 6,47800 6,55230

Tempo gasto em ATAN2 (): 7,26730 7,24885

Tempo gasto em ATAN3 (): 8.15299 8.21284

Tempo gasto em asin () e acos (): 36,8833 36,9496

Tempo gasto em ASINCOS1 (): 10,1655 9,78479

Tempo gasto em ASINCOS2 (): 10.6236 10.6000

Tempo gasto em ASINCOS3 (): 12,8430 12,0707

(No interesse de economizar espaço, a Tabela 1 não é mostrada.) A Tabela 2 mostra os resultados de duas execuções separadas de um bilhão de avaliações de cada função de aproximação. A primeira coluna é a primeira execução e a segunda coluna é a segunda execução. Os números '1', '2', '3' ou '4' nos nomes das funções indicam o número de termos usados ​​na função da série Maclaurin para avaliar a trigonometria particular ou a aproximação trigonométrica inversa. SINCOS # () significa que sin e cos foram avaliados ao mesmo tempo. Da mesma forma, ASINCOS # () significa que asin e acos foram avaliados ao mesmo tempo. Há pouca sobrecarga extra na avaliação de ambas as quantidades ao mesmo tempo.

Os resultados mostram que aumentar o número de termos aumenta ligeiramente o tempo de execução, como seria de se esperar. Mesmo o menor número de termos deu cerca de 12-14 dígitos de precisão em todos os lugares, exceto para a aproximação tan () perto de onde seu valor se aproxima de ± infinito. Seria de se esperar que até mesmo a função tan () tivesse problemas aqui.

Resultados semelhantes foram obtidos em um laptop MacBook Pro de última geração em Unix e em um computador desktop de última geração em Linux.

Roger Wehage
fonte
-5

Se você está pedindo uma explicação mais física de sin, cos e tan, considere como eles se relacionam com os triângulos retângulos. O valor numérico real de cos (lambda) pode ser encontrado formando um triângulo retângulo com um dos ângulos sendo lambda e dividindo o comprimento do lado dos triângulos adjacente a lambda pelo comprimento da hipotenusa. Da mesma forma, para o pecado, use o lado oposto dividido pela hipotenusa. Para tangente, use o lado oposto dividido pelo lado adjacente. O memônico clássico para lembrar isso é SOHCAHTOA (pronuncia-se socatoa).

jeffD
fonte