Вопрос

Итак, в средней школе математики и, возможно, в колледже нас учат, как использовать тригонометрические функции, что они делают и какие задачи решают.Но мне они всегда представлялись как черный ящик.Если вам нужен синус или косинус чего-либо, нажмите кнопку sin или cos на калькуляторе, и все готово.Это нормально.

Мне интересно, как обычно реализуются тригонометрические функции.

Это было полезно?

Решение

Во-первых, вы должны сделать какое-то уменьшение диапазона. Триггерные функции являются периодическими, поэтому вам нужно уменьшить аргументы до стандартного интервала. Для начала вы можете уменьшить углы до 0–360 градусов. Но, используя несколько идентичностей, вы понимаете, что можете обойтись с меньшими затратами. Если вы вычисляете синусы и косинусы для углов от 0 до 45 градусов, вы можете начать с расчета всех функций триггера для всех углов.

После того, как вы уменьшили свои аргументы, большинство чипов используют алгоритм CORDIC для вычисления синусов и косинусы. Вы можете услышать, как люди говорят, что компьютеры используют серию Taylor. Это звучит разумно, но это не так. Алгоритмы CORDIC намного лучше подходят для эффективной аппаратной реализации. (Библиотеки Software могут использовать ряды Тейлора, скажем, на оборудовании, которое не поддерживает функции триггера.) Может быть некоторая дополнительная обработка, использующая алгоритм CORDIC, чтобы получить довольно хорошие ответы, но затем сделать что-то еще для улучшения точность.

Есть некоторые уточнения к вышесказанному. Например, для очень маленьких углов theta (в радианах) sin (theta) = theta со всей точностью, которую вы имеете, поэтому более эффективно просто возвращать theta, чем использовать какой-либо другой алгоритм. Таким образом, на практике существует множество особых логик, чтобы выжать всю возможную производительность и точность. Чипы с небольшими рынками могут не потребовать столько усилий по оптимизации.

Другие советы

редактировать:Джек Ганссл в своей книге о встроенных системах дает достойное обсуждение: «Справочник по прошивке».

К вашему сведению:Если у вас есть ограничения по точности и производительности, следует использовать ряд Тейлора. нет использоваться для аппроксимации функций в числовых целях.(Сохраните их для своих курсов по математическому анализу.) Они используют аналитичность функции в одной точке, напримертот факт, что все его производные существуют в этой точке.Они не обязательно сходятся в интересующем интервале.Часто они плохо распределяют точность аппроксимации функции, чтобы она была «идеальной» прямо возле точки оценки;ошибка обычно увеличивается по мере удаления от нее.И если у вас есть функция с любой прерывистой производной (например,прямоугольные волны, треугольные волны и их интегралы), ряд Тейлора даст вам неправильный ответ.

Лучшее «простое» решение при использовании полинома максимальной степени N для аппроксимации заданной функции f(x) в интервале x0 < x < x1 — это Чебышевское приближение;см. «Численные рецепты» для хорошего обсуждения.Обратите внимание, что Tj(x) и Tk(x) в статье Wolfram, на которую я ссылаюсь, использовали cos и обратный косинус. Это полиномы, и на практике для получения коэффициентов вы используете рекуррентную формулу.Опять же, см. Числовые рецепты.

редактировать:В Википедии есть вполне приличная статья на эту тему. теория приближений.Один из источников, на которые они ссылаются (Харт, «Компьютерные аппроксимации»), больше не издается (и использованные копии, как правило, стоят дорого), но содержит много подробностей о подобных вещах.(Джек Ганссл упоминает об этом в выпуске 39 своего информационного бюллетеня. Встроенная муза.)

редактировать 2:Вот некоторые ощутимые показатели ошибок (см. ниже) для Тейлора и Тейлора.Чебышева для sin(x).Некоторые важные моменты, на которые следует обратить внимание:

  1. что максимальная ошибка аппроксимации рядом Тейлора в заданном диапазоне намного больше, чем максимальная ошибка аппроксимации Чебышева той же степени.(Примерно по той же ошибке у Чебышева можно отделаться на один член меньше, а значит, быстрее производительность)
  2. Сокращение дальности — огромная победа.Это связано с тем, что вклад полиномов более высокого порядка уменьшается с уменьшением интервала аппроксимации.
  3. Если вам не удастся избежать сокращения диапазона, ваши коэффициенты необходимо хранить с большей точностью.

Не поймите меня неправильно:Ряд Тейлора будет правильно работать для синуса/косинуса (с разумной точностью в диапазоне от -pi/2 до +pi/2;технически, используя достаточное количество членов, вы можете достичь любой желаемой точности для всех реальных входных данных, но попробуйте вычислить cos(100), используя ряд Тейлора, и вы не сможете этого сделать, если не используете арифметику произвольной точности).Если бы я застрял на необитаемом острове с ненаучным калькулятором и мне нужно было вычислить синус и косинус, я бы, вероятно, использовал ряд Тейлора, поскольку коэффициенты легко запомнить.Но реальные приложения, требующие написания собственных функций sin() или cos(), достаточно редки, поэтому лучше всего использовать эффективную реализацию для достижения желаемой точности - что представляет собой ряд Тейлора. нет.

Диапазон = от -pi/2 до +pi/2, степень 5 (3 члена)

  • Тейлор:максимальная ошибка около 4,5e-3, f(x) = x-x3/6+х5/120
  • Чебышев:максимальная ошибка около 7e-5, f(x) = 0,9996949x-0,1656700x3+0,0075134x5

Диапазон = от -pi/2 до +pi/2, степень 7 (4 члена)

  • Тейлор:максимальная ошибка около 1,5e-4, f(x) = x-x3/6+х5/120-х7/5040
  • Чебышев:максимальная ошибка около 6e-7, f(x) = 0,99999660x-0,16664824x3+0,00830629x5-0,00018363x7

Диапазон = от -pi/4 до +pi/4, степень 3 (2 члена)

  • Тейлор:максимальная ошибка около 2,5e-3, f(x) = x-x3/6
  • Чебышев:максимальная ошибка около 1,5e-4, f(x) = 0,999x-0,1603x3

Диапазон = от -pi/4 до +pi/4, степень 5 (3 члена)

  • Тейлор:максимальная ошибка около 3,5e-5, f(x) = x-x3/6+х5
  • Чебышев:максимальная ошибка около 6e-7, f(x) = 0,999995x-0,1666016x3+0,0081215x5

Диапазон = от -pi/4 до +pi/4, степень 7 (4 члена)

  • Тейлор:максимальная ошибка около 3e-7, f(x) = x-x3/6+х5/120-х7/5040
  • Чебышев:максимальная ошибка около 1,2e-9, f(x) = 0,999999986x-0,166666367x3+0,008331584x5-0,000194621x7

Я считаю, что они рассчитываются с использованием серии Тейлора или CORDIC . Некоторые приложения, которые интенсивно используют функции триггеров (игры, графика), создают таблицы триггеров при запуске, чтобы они могли просто искать значения, а не пересчитывать их снова и снова.

Ознакомьтесь с статьей Википедии о функциях триггера. Хорошее место для того, чтобы узнать о фактической реализации их в коде, это Численные рецепты .

Я не большой математик, но я понимаю, откуда взялись грех, потому что и загар &; в том, что они, в некотором смысле, наблюдаются, когда вы работаете с прямоугольными треугольниками. Если вы измеряете длины сторон группы различных прямоугольных треугольников и наносите точки на график, вы можете получить из этого значения sin, cos и tan. Как указывает Харпер Шелби, функции просто определяются как свойства прямоугольных треугольников.

Более глубокое понимание достигается путем понимания того, как эти соотношения связаны с геометрией круга, что приводит к радианам и всей этой доброте. Все это есть в записи в Википедии.

Чаще всего для компьютеров представление степенных рядов используется для вычисления синусов и косинусов, и они используются для других функций триггера. Расширение этих рядов примерно до 8 членов вычисляет значения, необходимые с точностью, близкой к машинному эпсилону (наименьшее ненулевое число с плавающей запятой, которое можно удерживать).

Метод CORDIC быстрее, поскольку он реализован на оборудовании, но в основном он используется для встроенных систем, а не для стандартных компьютеров.

Я хотел бы расширить ответ, предоставленный @Jason S. Используя метод деления домена, аналогичный описанному в @Jason S, и используя приближения рядов Маклаурина, среднее (2-3) X ускорение по сравнению с tan (), Были достигнуты функции sin (), cos (), atan (), asin () и acos (), встроенные в компилятор gcc с оптимизацией -O3. Описанные ниже лучшие аппроксимирующие функции серии Маклаурина достигли двойной точности.

Для функций tan (), sin () и cos () и для простоты перекрывающийся домен от 0 до 2pi + pi / 80 был разделен на 81 равный интервал с помощью " опорных точек & Quot; при пи / 80, 3pi / 80, ..., 161pi / 80. Затем tan (), sin () и cos () из этих 81 опорных точек были оценены и сохранены. С помощью идентификаторов триггеров для каждой функции триггера была разработана отдельная функция ряда Маклаурина. Любой угол между & # 177; бесконечность может быть передан в функции аппроксимации триггера, поскольку функции сначала переводят входной угол в область от 0 до 2pi. Эти накладные расходы на перевод включаются в накладные расходы на аппроксимацию.

Аналогичные методы были разработаны для функций atan (), asin () и acos (), где перекрывающийся домен от -1,0 до 1,1 был разделен на 21 равный интервал с точками привязки в -19/20, -17/20 , ..., 19/20, 21/20. Тогда только atan () из этих 21 опорных точек был сохранен. Опять же, с помощью обратных тригогенных тождеств была разработана единственная функция ряда Маклаурина для функции atan (). Результаты функции atan () были затем использованы для аппроксимации asin () и acos ().

Поскольку все аппроксимирующие функции обратного триггера основаны на аппроксимирующей функции atan (), любое входное значение аргумента двойной точности допускается. Однако входной аргумент для аппроксимирующих функций asin () и acos () усекается до домена & # 177; 1, потому что любое значение за его пределами бессмысленно.

Чтобы протестировать аппроксимирующие функции, пришлось оценить миллиард случайных оценок функций (т. е. оптимизирующему компилятору -O3 не разрешалось обходить оценку чего-либо, потому что некоторый вычисленный результат не будет использоваться). Чтобы удалить смещение оценивая миллиард случайных чисел и обрабатывая результаты, сначала выполнялась стоимость прогона без оценки какой-либо триггера или обратной функции триггера. Это смещение затем вычиталось из каждого теста, чтобы получить более представительную аппроксимацию фактического времени оценки функции.

Таблица 2. Время, потраченное в секундах на выполнение указанной функции или функции один миллиард раз. Оценки получены путем вычитания затрат времени на оценку одного миллиарда случайных чисел, показанных в первой строке таблицы 1, из оставшихся строк таблицы 1.

Время, проведенное в tan (): 18.0515 18.2545

Время, проведенное в TAN3 (): 5.93853 6.02349

Время, проведенное в TAN4 (): 6.72216 6.99134

Время, проведенное в sin () и cos (): 19.4052 19.4311

Время, проведенное в SINCOS3 (): 7,85564 7,92844

Время, проведенное в SINCOS4 (): 9.36672 9.57946

Время, проведенное в atan (): 15,7160 15,6599

Время, проведенное в ATAN1 (): 6,47800, 6,55230

Время, проведенное в ATAN2 (): 7.26730 7.24885

Время, проведенное в ATAN3 (): 8.15299 8.21284

Время, проведенное в asin () и acos (): 36,8833 36,9496

Время, проведенное в ASINCOS1 (): 10.1655 9.78479

Время, проведенное в ASINCOS2 (): 10,6236 10,6000

Время, проведенное в ASINCOS3 (): 12,8430 12,0707

(В целях экономии места таблица 1 не показана.) В таблице 2 показаны результаты двух отдельных прогонов по миллиарду оценок каждой аппроксимирующей функции. Первый столбец - это первый прогон, а второй столбец - второй прогон. Числа «1», «2», «3» или «4» в названиях функций указывают количество терминов, используемых в функции рядов Макларина для оценки конкретного триггера или аппроксимации обратного трига. SINCOS # () означает, что и sin, и cos были вычислены одновременно. Аналогично, ASINCOS # () означает обаasin и acos были оценены одновременно. Существует небольшая дополнительная нагрузка при оценке обоих количеств одновременно.

Результаты показывают, что увеличение количества терминов немного увеличивает время выполнения, как и следовало ожидать. Даже наименьшее количество членов дает точность 12-14 цифр везде, за исключением приближения tan (), близкого к тому, где его значение приближается к & # 177; бесконечность. Можно было бы ожидать, что даже у функции tan () возникнут проблемы.

Аналогичные результаты были получены на мощном ноутбуке MacBook Pro в Unix и на настольном компьютере высокого класса в Linux.

Если вы просите более физическое объяснение грехов, cos и tan, подумайте, как они соотносятся с прямоугольными треугольниками. Фактическое числовое значение cos (лямбда) может быть найдено путем формирования прямоугольного треугольника с одним из углов, являющегося лямбда, и делением длины стороны треугольников, примыкающей к лямбде, на длину гипотенузы. Точно так же для греха используйте противоположную сторону, разделенную на гипотенузу. Для касательной используйте противоположную сторону, разделенную на соседнюю сторону. Классический мемоник, чтобы помнить это, SOHCAHTOA (произносится как socatoa).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top