Костян 0 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба Собственно интересует метод реализации функций cos(x) и exp(x) . Как они вычисляются ? Таблично , посредством ряда фурье или ... ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба Можно подглядеть у newlib. Вот синус-косинус: sf_sine.c Вот экспонента: sf_exp.c Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kosyak© 0 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба Скорее всего ряд Тейлора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба Скорее всего ряд Тейлора. sf_sine.c /* Calculate the Taylor series. */ :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Serj78 0 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба Библиотека math.h, входящая в состав кейла, по- видимому также использует ряд Тейлора. Причем количество членов воидимо какое-то ужасное, судя по времени выполнения. На AVR из его библиотеки float sin(float x) выполнялся впятеро быстрее, там было 5 членов ряда. :) Буду переписывать библиотеку- по времени выполнения математика меня не устраивает - медленнее чем на 8-ми битнике (AVR) работает при вчетверо большей тактовой. А уж знаменито разрекламированная функция (hypot) вычисляющая длину двумерного вектора ( например, модуль комплексного числа ), это вообще песня. 0.76 мс!!! на 72-х мегагерцах... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 23 28 января, 2010 Опубликовано 28 января, 2010 (изменено) · Жалоба CORDIC Изменено 28 января, 2010 пользователем blackfin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 28 января, 2010 Опубликовано 28 января, 2010 · Жалоба CORDIC Newlib весь безнадежно тормозной. И далеко не "new" :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artur_off 0 29 января, 2010 Опубликовано 29 января, 2010 (изменено) · Жалоба Библиотека math.h, входящая в состав кейла, по- видимому также использует ряд Тейлора. Причем количество членов воидимо какое-то ужасное, судя по времени выполнения. На AVR из его библиотеки float sin(float x) выполнялся впятеро быстрее, там было 5 членов ряда. :) Буду переписывать библиотеку- по времени выполнения математика меня не устраивает - медленнее чем на 8-ми битнике (AVR) работает при вчетверо большей тактовой. А уж знаменито разрекламированная функция (hypot) вычисляющая длину двумерного вектора ( например, модуль комплексного числа ), это вообще песня. 0.76 мс!!! на 72-х мегагерцах... Тоже столкнулся с проблемой очень медленной работы функций. tab_sin_U[i]=round((sin(temp)*amount)+(1/6)*(sin(3*temp)*amount)); Расчет массива из 1024-х значений по этой формуле, в STR912 занимал примерно пол секунды. И это при частоте ядра 96МГц. Изменено 29 января, 2010 пользователем artur_off Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 30 января, 2010 Опубликовано 30 января, 2010 · Жалоба Тоже столкнулся с проблемой очень медленной работы функций. tab_sin_U[i]=round((sin(temp)*amount)+(1/6)*(sin(3*temp)*amount)); Расчет массива из 1024-х значений по этой формуле, в STR912 занимал примерно пол секунды. И это при частоте ядра 96МГц. Формула как-то странно выглядит. Например, (1/6) - это 0. Возможно, что с типами других операндов напутано. Если можно не использовать double, то нужно внимательно проследить, чтобы везде был float. К тому же amount можно вынести за скобки и сэкономить одно умножение. Что делает round() и как - непонятно. Вывод: рано спешить с выводами про "быстро-медленно", сначала надо код подправить. И вообще, что такое "очень медленная работа функций, и это с частотой ядра 96 МГц"? Эта фраза не имеет смысла, пока не сказано, сколько микросекунд - медленно, а сколько - быстро. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Drozd2 0 30 января, 2010 Опубликовано 30 января, 2010 · Жалоба Если есть желание реализовать свой алгоритм, тогда исключительно CORDIC. Такой ответ уже был. Алгоритм очень хорошо срабатывает на ПЛИС. Весь просчет за один такт. Нужно только не забывать, что для точности, например, 32 бит нужно закладывать в расчет не меньше 33 бит. Еще лучше держат бит 5 в запасе. Очень удобный алгоритм, если нужно сразу получить и синис, и косинус числа. Прирост в скорости вычисления колоссальный. Даже на микроконтроллере без сопроцессора. Да и вообще, для любителей численных методов интересная тема. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Serj78 0 31 января, 2010 Опубликовано 31 января, 2010 · Жалоба Если есть желание реализовать свой алгоритм, тогда исключительно CORDIC. Такой ответ уже был. Алгоритм очень хорошо срабатывает на ПЛИС. Весь просчет за один такт. Нужно только не забывать, что для точности, например, 32 бит нужно закладывать в расчет не меньше 33 бит. Еще лучше держат бит 5 в запасе. Очень удобный алгоритм, если нужно сразу получить и синис, и косинус числа. Прирост в скорости вычисления колоссальный. Даже на микроконтроллере без сопроцессора. Да и вообще, для любителей численных методов интересная тема. Готовых функций CORDIC не нашел, только алгоритм. Пока остановился на том, что и просто тупое копирование AVR-овской библиотеки от CVAvr (она, слава богу, открытая и на С писанная) дает примерно десятикратный прирост времени выполнения. Возможно, в родной кейловской библиотеке больше точность, буду проверять. У меня дискретность значений примерно 50 микрорадиан. Использовал функции в float синуса, косинуса и арктангенса ( на самом деле там один синус, остальные- через тригонометрические преобразования) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 31 января, 2010 Опубликовано 31 января, 2010 · Жалоба Возможно, в родной кейловской библиотеке больше точность, буду проверять. У меня дискретность значений примерно 50 микрорадиан. Если такой маленький прирост, то наверняка можно оптимизировать при помощи локальной линеаризации. Использовал функции в float синуса, косинуса и арктангенса ( на самом деле там один синус, остальные- через тригонометрические преобразования) Если честно, не понимаю, как арктангенс можно получить из синуса тригонометрическими преобразованиями. Скорее всего никак нельзя. Ну да ладно, это к делу не относится... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artur_off 0 31 января, 2010 Опубликовано 31 января, 2010 (изменено) · Жалоба Формула как-то странно выглядит. Например, (1/6) - это 0. Возможно, что с типами других операндов напутано. Если можно не использовать double, то нужно внимательно проследить, чтобы везде был float. К тому же amount можно вынести за скобки и сэкономить одно умножение. Что делает round() и как - непонятно. Вывод: рано спешить с выводами про "быстро-медленно", сначала надо код подправить. И вообще, что такое "очень медленная работа функций, и это с частотой ядра 96 МГц"? Эта фраза не имеет смысла, пока не сказано, сколько микросекунд - медленно, а сколько - быстро. Это кусок кода с матлаба, так как сишный удалил. а на С естественно было приведение к float. хотя здесь протупил, вместо 1/6 можно было написать 0.167. round() - математическое округление. по поводу amount согласен, но это не так уж и сильно влияет на производительность. По поводу времени выполнения было сказано, что занимает примерно пол секунды (0.5 с). Изменено 31 января, 2010 пользователем artur_off Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 31 января, 2010 Опубликовано 31 января, 2010 · Жалоба Это кусок кода с матлаба, так как сишный удалил. а на С естественно было приведение к float. хотя здесь протупил, вместо 1/6 можно было написать 0.167. round() - математическое округление. Если везде float, то нужно использовать sinf() вместо sin(), roundf() вместо round(). 0.167 лучше писать как 0.167f, а если округление до трёх цифр не подходит, то 1.0f/6. Не сочтите за занудство, это на всякий случай. Скорее всего, у Вас так и написано. Меня удивил round(), потому что в стандартной библиотеке Си его сразу не нашёл. Видимо, было добавлено в C99... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artur_off 0 31 января, 2010 Опубликовано 31 января, 2010 · Жалоба Если везде float, то нужно использовать sinf() вместо sin(), roundf() вместо round(). 0.167 лучше писать как 0.167f, а если округление до трёх цифр не подходит, то 1.0f/6. Не сочтите за занудство, это на всякий случай. Скорее всего, у Вас так и написано. Меня удивил round(), потому что в стандартной библиотеке Си его сразу не нашёл. Видимо, было добавлено в C99... Благодарю за советы))). А round() действительно добавлен в С99 и поэтому перед #include <math.h> надо объявить #define __USE_C99_MATH. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться