|
аппроксимация деления, почему не используется |
|
|
|
May 13 2015, 22:57
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 2-10-10
Пользователь №: 59 873

|
У меня стоит задача нормировки потока чисел (поток пикселей изображения) на некоторое переменное значение (например разницу максимальной и минимальной яркости изображения). Соответственно без деления не обойтись. Те алгоритмы, которые используются чаще всего, делятся на два типа: либо тупо LUT с забитой таблицей 1/х, либо итеративные алгоритмы, имитирующие деление в столбик, с различной степенью оптимизации. Еще можно складывать делитель, пока результат не превзойдет делимое и посчитать количество таких операций, но это совсем плохой алгоритм. Почему никто не использует тупо полиномиальную аппроксимацию 1/х? Вот здесь всего навсего полином 3-й степени, 100 слайсов на 3-ем Спартане и при этом точность 11 бит. Мне так кажется, что я здесь что-то не понимаю, это же так просто, почему так не делают? Еще и конкретно для моей задачи - даже при точности 11 бит, я мог бы получить приемлемый результат, забив на линейность нормировки. Спасибо.
|
|
|
|
|
 |
Ответов
|
May 15 2015, 09:46
|
Гуру
     
Группа: Свой
Сообщений: 3 106
Регистрация: 18-04-05
Пользователь №: 4 261

|
Цитата(Maverick @ May 15 2015, 08:53)  например? (хорошие по Вашему мнению - 32/64 бит) Ну можно, наверное, методом Ньютона попробовать.. Главное - выбрать правильное начальное приближение.. Например, мы хотим найти частное от деления: A/B = D, где A = 555555, B = 11 и, соответственно, D = 50505. Тогда: A/B = [(A*2 32/B)>>32] = D. Введем обозначение: x = 2 32/B. Это равносильно: 2 32/x = B. Или: f(x) == 2 32/x - B = 0. Находим производную: f'(x) = -2 32/x 2. Теперь подставляем всё это в формулу Ньютона и находим: x n+1 = x n - f(x n)/f'(x n), или x n+1 = x n + [2 32/x n - B]/[2 32/x n2], или x n+1 = 2*x n - B*x n2/2 32, или x n+1 = 2*x n - [(B*x n*x n)>>32]. Начальное приближение для x 0 выбираем равным: x 0 = 2 32-m, где m - максимальная степень двойки в двоичном представлении числа B.. То есть, для B = 11 это дает: B = 11 d = 1011 b = 1*2 3 + 0*2 2 + 1*2 1 + 1*2 0. Откуда находим, что m = 3, и: x 0 = 2 29. Тогда: x 1 = 2 30 - 11*2 26 = 335544320; x 2 = 2*335544320 - (11*335544320*335544320)>>32 = 382730240; x 3 = 2*382730240 - (11*382730240*382730240)>>32 = 390298880; x 4 = 2*390298880 - (11*390298880*390298880)>>32 = 390451513; x 5 = 2*390451513 - (11*390451513*390451513)>>32 = 390451572; x 6 = 2*390451572 - (11*390451572*390451572)>>32 = 390451572; После чего находим: A/B = [(A*x)>>32] = [(555555*390451572)>>32] = 50505 = D. Но в целом, все эти "быстро сходящиеся итерации" не слишком то оптимальны для FPGA, КМК.. Как-то так..
|
|
|
|
|
May 15 2015, 10:28
|

я только учусь...
     
Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839

|
Цитата(blackfin @ May 15 2015, 12:46)  Ну можно, наверное, методом Ньютона попробовать.. Главное - выбрать правильное начальное приближение.. Например, мы хотим найти частное от деления: A/B = D, где A = 555555, B = 11 и, соответственно, D = 50505. Тогда: A/B = [(A*2 32/B)>>32] = D. Введем обозначение: x = 2 32/B. Это равносильно: 2 32/x = B. Или: f(x) == 2 32/x - B = 0. Находим производную: f'(x) = -2 32/x 2. Теперь подставляем всё это в формулу Ньютона и находим: x n+1 = x n - f(x n)/f'(x n), или x n+1 = x n + [2 32/x n - B]/[2 32/x n2], или x n+1 = 2*x n - B*x n2/2 32, или x n+1 = 2*x n - [(B*x n*x n)>>32]. Начальное приближение для x 0 выбираем равным: x 0 = 2 32-m, где m - максимальная степень двойки в двоичном представлении числа B.. То есть, для B = 11 это дает: B = 11 d = 1011 b = 1*2 3 + 0*2 2 + 1*2 1 + 1*2 0. Откуда находим, что m = 3, и: x 0 = 2 29. Тогда: x 1 = 2 30 - 11*2 26 = 335544320; x 2 = 2*335544320 - (11*335544320*335544320)>>32 = 382730240; x 3 = 2*382730240 - (11*382730240*382730240)>>32 = 390298880; x 4 = 2*390298880 - (11*390298880*390298880)>>32 = 390451513; x 5 = 2*390451513 - (11*390451513*390451513)>>32 = 390451572; x 6 = 2*390451572 - (11*390451572*390451572)>>32 = 390451572; После чего находим: A/B = [(A*x)>>32] = [(555555*390451572)>>32] = 50505 = D. Но в целом, все эти "быстро сходящиеся итерации" не слишком то оптимальны для FPGA, КМК.. Как-то так..  спасибо... PS метод Ньютон работает для нахождения практически любых функций и как Вы правильно заметили для FPGA в чистом виде плохо подходят я думал, что есть уже какие-то модификации, которые лучше подходят для FPGA и менее итерационные...
--------------------
If it doesn't work in simulation, it won't work on the board.
"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
|
|
|
|
Сообщений в этой теме
alexkarnaukhov аппроксимация деления May 13 2015, 22:57 Lmx2315 ..я пользуюсь сдвигом вправо. May 14 2015, 04:16 Maverick Цитата(alexkarnaukhov @ May 14 2015, 01:5... May 14 2015, 05:11 alexkarnaukhov Цитата(Maverick @ May 14 2015, 09:11) Вот... May 14 2015, 10:32  Maverick Цитата(alexkarnaukhov @ May 14 2015, 13:3... May 14 2015, 10:44 des00 Цитата(alexkarnaukhov @ May 14 2015, 05:5... May 14 2015, 05:32 _pv если в a/b делитель не так часто меняется, посчита... May 14 2015, 10:59 alexkarnaukhov Цитата(_pv @ May 14 2015, 14:59) если в a... May 14 2015, 11:13 XVR Цитата(alexkarnaukhov @ May 14 2015, 01:5... May 14 2015, 11:17 alexkarnaukhov Цитата(XVR @ May 14 2015, 15:17) Наверное... May 14 2015, 11:29 alexkarnaukhov Ну вообще Ньютон как раз может и быть интересен. П... May 15 2015, 14:23
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|