реклама на сайте
подробности

 
 
> Табличное предстваление нелинейной функции - проблема точности
syoma
сообщение Jan 22 2014, 11:41
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 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 итераций. А хотелось бы одну.

Я думаю есть более простые алгоритмы вычисления. Подскажите.


Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 12)
iosifk
сообщение Jan 22 2014, 11:47
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(syoma @ Jan 22 2014, 15:41) *
Я думаю есть более простые алгоритмы вычисления. Подскажите.

Первое, что приходит в голову, так это сделать таблицу только для поправок = функция минус линейная аппроксимация...
И разбить функцию на несколько диапазонов по изменениям.. Соотв. для каждого поддиапазона - своя линейная часть и свои поправки... Тогда удастся уменьшить общий объем памяти.


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Fat Robot
сообщение Jan 22 2014, 11:57
Сообщение #3


ʕʘ̅͜ʘ̅ʔ
*****

Группа: Свой
Сообщений: 1 008
Регистрация: 3-05-05
Пользователь №: 4 691



варианты:
- старшие биты аргумента указывают на таблицу, а младшие на позицию значения в таблице
- log2(аргумента) или log2(старших бит аргумента) указывает на таблицу, а младшие биты на позицию значения в таблице (для вашей функции я бы предпочел этот вариант)

вместо таблицы можно взять коэффициенты интерполятора. самое простое - линейного

отдаленный аналог: PCM u-law или A-law

log2 в данном случае - это позиция msb

И да, у вас функция монотонная на заданном интервале, т.е. обратная функуция, которая более пригодна для работы, на этом интервале существует. имея таблицу обратных значений, можно найти аргумент методом дихотомии/бисекции или более быстрым последовательным приближением (золотое сечение, например). Для дихотомии будет ~10 итераций для вашего размера таблицы
Go to the top of the page
 
+Quote Post
_pv
сообщение Jan 22 2014, 12:36
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



фунция монотонная, поэтому бинарный поиск по обратной таблице это всё таки 10, а не 900 операций
Go to the top of the page
 
+Quote Post
syoma
сообщение Jan 29 2014, 07:59
Сообщение #5


Профессионал
*****

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



Кстати обратная функция от этой это:
u=(y-sin(y))/pi - в общем-то изза ее проблемности и весь сыр бор.
Может есть более простые методы нахождения y в этом случае?
Go to the top of the page
 
+Quote Post
Task Solver
сообщение Jan 30 2014, 19:14
Сообщение #6





Группа: Участник
Сообщений: 14
Регистрация: 17-01-14
Пользователь №: 80 083



Цитата(syoma @ Jan 29 2014, 11:59) *
Кстати обратная функция от этой это:
u=(y-sin(y))/pi - в общем-то изза ее проблемности и весь сыр бор.
Может есть более простые методы нахождения y в этом случае?

Может корень искать с помощью касательных, методом Ньютона? Очень быстро.
Go to the top of the page
 
+Quote Post
sifadin
сообщение Feb 4 2014, 15:55
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 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 двоичного кода
может в квартусе есть уже готовый такой модуль - с плавающими, вещественными числами
Go to the top of the page
 
+Quote Post
SM
сообщение Feb 4 2014, 22:26
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



ПЛИС плисе рознь... Умножители там есть? Может быть, достаточную точность даст интерполяция чем нибудь посложнее линейной, но в общем, не сложным, например каким нибудь простым сплайном, с таблицей с вменяемым числом значений. Хотя, судя по тому, что возведения в квадрат для Вас не проблема, то можно интерполироваться полиномами и 4-ой степени, и пятой, храня, например в таблицах сразу коэффициенты полиномов для каждого отрезка. А судя по картинке, есть матлаб, вот прямо в нем и проанализируйте разные варианты интерполяций.
Go to the top of the page
 
+Quote Post
_Ivana
сообщение Feb 5 2014, 20:38
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 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 итераций получаем маскимальную точность для Экселя.
Go to the top of the page
 
+Quote Post
sifadin
сообщение Feb 6 2014, 00:16
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 443
Регистрация: 11-02-09
Пользователь №: 44 698



Цитата(_Ivana @ Feb 5 2014, 23:38) *
Вам писали выше про Ньютона.


Это не мне. Я не ТС.


Можно и так. Но тогда можно наверное и NIOS внедрить и посчитать.




Go to the top of the page
 
+Quote Post
_Ivana
сообщение Feb 6 2014, 12:27
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 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 с некоторой точностью - я проверил, второй/третий знак после запятой. Так что вам нет нужды точнее рассчитывать эту приближенную функцию, она сама содержит отклонения от нужной (насколько я понимаю). Вдобавок, вам (ТС sm.gif) все-таки писали про Ньютона, с помощью которого можно сразу искать корни 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, то и за одну/две итерации сойдется. Синусы/косинусы можно считать через ряд Тэйлора, тоже сходятся очень быстро. И не требуется никаких приближенных обратных функций с волшебными константами, и результат точнее. Хотя, именно требуемая точность результата и определяет сложность метода. С вашей заложенной ошибкой в третьем знаке (если она вас устраивает) можно и интерполяцию несложную сделать по малому массиву точек.
Go to the top of the page
 
+Quote Post
Task Solver
сообщение Feb 6 2014, 15:47
Сообщение #12





Группа: Участник
Сообщений: 14
Регистрация: 17-01-14
Пользователь №: 80 083



Вы что? Функция не моя. Я подкидывал идею вычислений автору темы.
Go to the top of the page
 
+Quote Post
_Ivana
сообщение Feb 6 2014, 16:35
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710



Первый раз я перепутал автора темы, но сейчас имхо всему прогрессивному человечеству понятно, что ТС - это не Таск Солвер, а Топик Стартер sm.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th June 2025 - 02:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01479 секунд с 7
ELECTRONIX ©2004-2016