Эффективность вычисления arcsin из таблицы поиска синуса

Я реализовал таблицу поиска для вычисления значений синуса / косинуса в своей системе. Теперь мне нужны обратные тригонометрические функции (arcsin / arccos).

Мое приложение работает на встроенном устройстве, на котором я не могу добавить вторую таблицу поиска для arcsin, поскольку у меня ограничена программная память. Итак, решение, которое я имел в виду, заключалось в том, чтобы просмотреть таблицу синусоидального поиска, чтобы получить соответствующий индекс.

Мне интересно, будет ли это решение более эффективным, чем использование стандартной реализации из стандартной математической библиотеки.
Кто-нибудь уже экспериментировал с этим?

Текущая реализация LUT представляет собой массив значений синуса от 0 до PI / 2. Значение, хранящееся в таблице, умножается на 4096, чтобы сохранить целочисленные значения с точностью, достаточной для моего приложения. Таблица поиска с разрешением 1/4096 дает нам массив из 6434 значений. Затем у меня есть две функции: синус и косинус, которые в качестве аргумента принимают угол в радианах, умноженный на 4096. Эти функции преобразуют заданный угол в соответствующий угол в первом квадранте и считывают соответствующее значение в таблице.

Мое приложение работает на dsPIC33F со скоростью 40 MIPS, и я использую пакет компиляции C30.


person greydet    schedule 07.05.2011    source источник
comment
Опишите структуру вашей текущей таблицы синусов / косинусов.   -  person finnw    schedule 07.05.2011
comment
Соглашаясь с finnw. В зависимости от структуры вашей таблицы теперь вы можете выполнить двоичный поиск по таблице, который может быть достаточно быстрым. Но так вы также потеряете более или менее точность.   -  person schnaader    schedule 07.05.2011
comment
Я отредактировал свой вопрос, указав информацию о реализации моей таблицы поиска   -  person greydet    schedule 07.05.2011


Ответы (4)


Довольно сложно сказать что-либо с уверенностью, поскольку вы не рассказали нам об оборудовании, компиляторе или своем коде. Однако априори я ожидал, что стандартная библиотека вашего компилятора будет более эффективной, чем ваш код.

person David Heffernan    schedule 07.05.2011
comment
Я добавил информацию о моей реализации таблицы поиска и устройстве, на котором она работает. - person greydet; 07.05.2011

К сожалению, вам приходится использовать компилятор C30, который не поддерживает C ++, в противном случае я бы указал вам на Оптимизация Математические приложения с арифметикой с фиксированной точкой и связанная с ними библиотека.

Однако общие принципы алгоритма CORDIC применяются, и объем памяти будет намного меньше, чем ваш текущая реализация. В статье объясняется создание arctan (), а arccos () и arcsin () могут быть вычислены на основе этого, как описано здесь.

введите описание изображения здесь

введите описание изображения здесь

Конечно, это также предполагает, что вам понадобится также извлечение квадратного корня и деление. Это может быть дорого, хотя PIC24 / dsPIC имеет аппаратное целочисленное деление. В статье об ускорении математики также рассматривается извлечение квадратного корня. Вполне вероятно, что ваш подход к таблице поиска будет быстрее для прямого поиска, но, возможно, не для обратного поиска, но подходы, описанные в этой статье, являются более общими и более точными (библиотека использует 64-битные целые числа как 36,28-битные с фиксированной точкой, вы можете обойтись с меньшей точностью и диапазоном в вашем приложении) и, безусловно, быстрее, чем реализация стандартной библиотеки с программной плавающей запятой.

person Clifford    schedule 07.05.2011

Вы можете использовать «наполовину» подход, комбинируя крупнозернистую таблицу поиска для экономии памяти и числовое приближение для промежуточных значений (например, Серия Маклорена, что будет более точным, чем линейная интерполяция.)

Некоторые примеры здесь.

В этом вопросе также есть ссылки по теме.

person finnw    schedule 08.05.2011

При двоичном поиске 6434 потребуется ~ 12 поисков, чтобы найти значение, с последующей интерполяцией, если требуется более высокая точность. Из-за природы кривой sin вы получите гораздо большую точность на одном конце, чем на другом. Если вы можете сэкономить память, создание собственной инверсной таблицы, равномерно распределенной по входам, вероятно, будет лучшим выбором для скорости и точности.

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

person AShelly    schedule 07.05.2011
comment
К сожалению, я пропустил строчку, в которой вы сказали, что не можете позволить себе второй стол. Я все равно посмотрю, какую экономию можно получить, удалив stdlib d - person AShelly; 07.05.2011