|
Табличное предстваление нелинейной функции - проблема точности |
|
|
|
Jan 22 2014, 11:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Народ - примитивный вопрос - вроде как в универе учил, а забыл как делается. В общем есть такая функция: y = (pi-0.5*((2.6829)*u.^(1/3)+0.1984*u+0.2602*u.^(5/3)))*(180/pi) Для значений аргумента u от 0 до 1 она дает угол y от 180° до 90°. График данной функции представлен на рисунке.
Так как вычислят нужно в ПЛИС и быстро - хотим сделать таблицу значений. Но проблема в том, что точность результата должна быть в пределах 0,1°, а как видно из графика в начале функции маленькие значения аргумента вызывают значительное изменение результата. В реале это 1/(2^29) для начальных значений. Ессно лепить таблицу с таким количеством записей нерентабельно и ессно при больших значениях аргумента точность будет избыточной. С другой стороны можно было бы сделать обратную таблицу с 900 записями и 29 битами входного параметра. Но тогда нужно сравнивать аргумент с каждым значением, а это в худшем случае 900 итераций. А хотелось бы одну. Я думаю есть более простые алгоритмы вычисления. Подскажите.
|
|
|
|
|
 |
Ответов
(1 - 12)
|
Jan 30 2014, 19:14
|
Группа: Участник
Сообщений: 14
Регистрация: 17-01-14
Пользователь №: 80 083

|
Цитата(syoma @ Jan 29 2014, 11:59)  Кстати обратная функция от этой это: u=(y-sin(y))/pi - в общем-то изза ее проблемности и весь сыр бор. Может есть более простые методы нахождения y в этом случае? Может корень искать с помощью касательных, методом Ньютона? Очень быстро.
|
|
|
|
|
Feb 4 2014, 15:55
|
Местный
  
Группа: Свой
Сообщений: 443
Регистрация: 11-02-09
Пользователь №: 44 698

|
Цитата(syoma @ Jan 22 2014, 15:41)  y = (pi-0.5*((2.6829)*u.^(1/3)+0.1984*u+0.2602*u.^(5/3)))*(180/pi) Вот если бы как-то просто вычислить u.(1/3), то все выражение можно было бы свести к виду у = С1 - С2* t * ( (t.^2 + A).^2 + B ) где t = u.^1/3 Такую структуру можно было бы реализовать на плис Только надо как-то умудриться взять степень 1/3 может логарифм/ антилогарифм вроде бы как-то можно легко реализовать log2 двоичного кода может в квартусе есть уже готовый такой модуль - с плавающими, вещественными числами
|
|
|
|
|
Feb 4 2014, 22:26
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
ПЛИС плисе рознь... Умножители там есть? Может быть, достаточную точность даст интерполяция чем нибудь посложнее линейной, но в общем, не сложным, например каким нибудь простым сплайном, с таблицей с вменяемым числом значений. Хотя, судя по тому, что возведения в квадрат для Вас не проблема, то можно интерполироваться полиномами и 4-ой степени, и пятой, храня, например в таблицах сразу коэффициенты полиномов для каждого отрезка. А судя по картинке, есть матлаб, вот прямо в нем и проанализируйте разные варианты интерполяций.
|
|
|
|
|
Feb 5 2014, 20:38
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Цитата(sifadin @ Feb 4 2014, 18:55)  Вот если бы как-то просто вычислить u.(1/3), то... Только надо как-то умудриться взять степень 1/3... Вам писали выше про Ньютона. Берете х(0) = 1 (или любое другое приближение искомого корня), считаете х(к+1) = 2х(к)/3+ а/(3х(к)^2), все это сходится к кубическому корню из а. Например, при а = 64 и х(0) = 1 за 10 итераций получаем маскимальную точность для Экселя.
|
|
|
|
|
Feb 6 2014, 00:16
|
Местный
  
Группа: Свой
Сообщений: 443
Регистрация: 11-02-09
Пользователь №: 44 698

|
Цитата(_Ivana @ Feb 5 2014, 23:38)  Вам писали выше про Ньютона. Это не мне. Я не ТС. Можно и так. Но тогда можно наверное и NIOS внедрить и посчитать.
|
|
|
|
|
Feb 6 2014, 12:27
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
2 ТС: Покрутил немножко вашу функцию. Если отбросить перевод в градусы и сдвиги/отражения, то на самом деле функция u = (y-sin(y))/pi является обратной не к вашей, а к ее содержательной части: y = (2.6829)*u.^(1/3)+0.1984*u+0.2602*u.^(5/3), но суть от этого не меняется. Эти волшебные константы-множители перед степенями u рассчитаны так, что эта функция аппроксимирует обратную к исходной красивой u = (y-sin(y))/pi с некоторой точностью - я проверил, второй/третий знак после запятой. Так что вам нет нужды точнее рассчитывать эту приближенную функцию, она сама содержит отклонения от нужной (насколько я понимаю). Вдобавок, вам (ТС  ) все-таки писали про Ньютона, с помощью которого можно сразу искать корни u = (y-sin(y))/pi - получается рекуррентная последовательность y(k+1) = (pi*u - y(k) + sin(y(k)))/(1 - cos(y(k))) + y(k), которая при y(0) = 2 сходится за тройку итераций с большой точностью. А если задать таблицу начальных приближений y(0) в зависимости от u, то и за одну/две итерации сойдется. Синусы/косинусы можно считать через ряд Тэйлора, тоже сходятся очень быстро. И не требуется никаких приближенных обратных функций с волшебными константами, и результат точнее. Хотя, именно требуемая точность результата и определяет сложность метода. С вашей заложенной ошибкой в третьем знаке (если она вас устраивает) можно и интерполяцию несложную сделать по малому массиву точек.
|
|
|
|
|
Feb 6 2014, 15:47
|
Группа: Участник
Сообщений: 14
Регистрация: 17-01-14
Пользователь №: 80 083

|
Вы что? Функция не моя. Я подкидывал идею вычислений автору темы.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|