Есть ли более быстрая функция синуса?

25

Я работаю над генерацией 3D-шума Перлина. Библиотека C # Math кажется мне излишней, поскольку большинство ее функций используют двойное разрешение. Я использую Math.Sin () в нескольких местах для генерации шума. Кто-нибудь знает о более быстрой функции синуса?

user2709
источник

Ответы:

32

Вы можете использовать параболу, чтобы приблизить значение функции синуса. Это имеет то преимущество, что корни имеют значения точно -pi / 2 и pi / 2, что обычно не имеет место в случае других быстрых приближений, основанных на TaylorSeries или MaclaurinSeries .

public float Sin(float x)
{
    const float B = 4 / PI;
    const float C = -4 / (PI*PI);

    return -(B * x + C * x * ((x < 0) ? -x : x));
} 

Вот сравнение с фактической функцией синуса:

альтернативный текст

zfedoran
источник
3
Это действительно отличное решение. Вот отличная статья от devmaster.net, которая описывает, почему это работает, и дает некоторые подробности реализации: devmaster.net/forums/showthread.php?t=5784
reverbb
Я не знаю о C #, но функция abs () в большинстве сред C, вероятно, будет быстрее, чем ветвь (оператор?:) При оптимизации.
3
Я удалил вызов Math.Abs ​​(), потому что предположил, что этот код может выполняться на Xbox 360 или Windows Phone 7. JIT-компилятор на Xbox 360 ничего не вставляет. Вызов Math.Abs ​​() на самом деле дороже.
Зфедоран
@reverbb Ссылка 404. Вот кэшированная копия.
Даниэль Пендергаст
1
@zfedoran Почему вы отрицаете возвращаемое значение? Кажется, это отрицательная синусоида.
Даниэль Пендергаст
12

Каков диапазон входных значений для вашей функции sin () ? Для того, для чего вы его используете, похоже, что они могут быть ограничены, что означает, что вы можете предварительно вычислить значения . Например, если вы округляете входные значения до ближайшего градуса, то у вас есть только 360 возможных значений - просто предварительно вычислите их и сохраните в таблице.

Если вам нужно немного больше значений, скажем, с одним десятичным знаком, вы можете интерполировать из таблицы - я не знаком с перлин-шумом , но слово «шум», кажется, указывает на то, что он не требует высокой точности. :) (Вы также можете просто сделать таблицу большего размера, 3600 записей не много места).

Циклоп
источник
3
Если скорость - ваша проблема номер один, и вы не против жертвовать точностью, это лучший ответ.
AttackingHobo
1
Я не знаю о «лучшем» - как показано в другом ответе, вы можете получить еще одно очень хорошее приближение за пять операций + абс (скорость которого зависит от вашей арки / компилятора, но часто без ветвления). Если таблица поиска не находится в кеше, она будет намного медленнее.