|
Очень нужна помощь в оптимизации алгоритма извлечения квадратного корня |
|
|
|
 |
Ответов
Guest_TSerg_*
|
Dec 21 2012, 07:12
|
Guests

|
Топик-стартер слушает только себя в попытке изобрести велосипед.  Вам уже приводились идеи и работающие варианты. Науке известны разные способы ивлечения целочисленного корня на разные вкусы. Еще раз приведу (для 16р сетки), число иттераций всегда 9 и никаких умножений. function QuickSqrt_(Val : word) : word; var bitSqr : word; begin bitSqr := $10000; Result := 0; While bitSqr <> 0 do begin if (Val >= bitSqr + Result) then begin Dec(Val, bitSqr + Result); Result := (Result shr 1) or bitSqr; end else Result := Result shr 1; bitSqr := bitSqr shr 2; end; end;
|
|
|
|
|
Dec 21 2012, 11:10
|
Частый гость
 
Группа: Участник
Сообщений: 127
Регистрация: 6-07-08
Из: Москва
Пользователь №: 38 765

|
Цитата(TSerg @ Dec 21 2012, 10:12)  Топик-стартер слушает только себя в попытке изобрести велосипед.  Вам уже приводились идеи и работающие варианты. Науке известны разные способы извлечения целочисленного корня на разные вкусы. Уважаемый TSerg, ну тё Вы ругаетесь? Себя я, конечно же, слушаю))) Велосипед? Да, изобретаю! Не мешайте мне побыть гениальным  Ваш вариант действительно очень эффективен. Да, выполняется за всего за 9 циклов! Я бы добавил его в начало темы, но не могу. Первое сообщение не доступно уже для изменения. Более того, в последнем Вашем коде есть ошибка: bitSqr : word. Это говорит о том, что Вы лично его не проверяли в деле. Судя по тому, что маске присваивается значение 0x010000, маска bitSqr должна быть 32-х разрядной (как и было в первом Вашем варианте). Далее в коде все операции с ней происходят как с 32-х разрядным числом (компилятор не будет динамически менять разрядность), это требует дополнительной памяти данных и инструкций. Это первое. Второе. Объем кода в Вашем варианте мне показался больше, чем в моем (к тому же, учитывая операции с 32-х разрядным числом в микроконтроллере с 8-ми разрядной архитектурой (даже с аппаратным умножителем 8х8), например). Но это на вскидку. Если все совсем делать серьезно, то, по идее, оба алгоритма нужно перевести на ассемблер микроконтроллера PIC16, например, и сравнить. Но, Ваш код прост. Мой имеет один (?) недостаток - операция умножения. В микроконтроллере с аппаратным умножителем это не будет проблемой, в остальных да. Вариантов, действительно, было множество. Но ищется оптимальный (имеющий малый объем кода, простоту вычислений, быстрый). Не все они отвечают этим требованиям. И вкус, часто определяется архитектурой вычислительного ядра. Ищу золотую середину))) ЗЫ. Кстати, очень интересно какие все же идеи есть у beaRTS)))
Сообщение отредактировал Rostislav - Dec 21 2012, 11:16
|
|
|
|
|
Dec 22 2012, 09:01
|
Местный
  
Группа: Участник
Сообщений: 211
Регистрация: 27-12-11
Из: Челябинск
Пользователь №: 69 111

|
Цитата(Rostislav @ Dec 21 2012, 14:10)  ЗЫ. Кстати, очень интересно какие все же идеи есть у beaRTS))) да какие там идеи... =) тож начитался много чего (по диагонали) мне корень нужен для нахождения модуля вектора, т.е.: имею синфазную и квадратурную составляющую сигнала (I и Q), т.е. как бы координаты вектора, ну и надо модуль найти, чтобы два канала I и Q соединить в один. Так вот. У меня на проце TMS320F28335 есть FPU (в общем, floating-point понимает и перемножитель даже есть аппаратный), работаю с числами float (вещественными одинарной точности). Ну и показался метод Ньютона (он же вроде вырождается в метод Вавилонский) более подходящий из всех, т.к. ему пофигу что считать: либо целые либо вещественны числа. Стал думать как делать для него первое приближение g0 (в книге Уоррен Генри. "Алгоритмические трюки для программистов такие обозначения" ). Ну а тут прям в масть ознакомился с неким алгоритмом "максимум альфа плюс минимум бета", который линейно аппроксимирует выражение sqrt( I^2 + Q^2) с приемлемой точностью и быстротой (точность зависит от коэффициентов альфа и бета). ну и решил первое приближение g0 делать при помощи него. итого, программка работает. только мне еще вкурить надо как должным образом проверить ее производительность во времени (что-то типа профилирования), сколько итераций расчета по методу ньютона производит с таким начальным/первым приближением. и сравнить по времени выполнения со стандартными функциями С++. Ну и величину ошибки тоже вычислить. Что успел бегло подметить: что количество итераций для разных чисел - разное, что многие значения высчитываются точно в сравнении со стандартными функциями, а некоторые с некоторой ошибкой... В общем статистику еще не проводил и не оформлял. но стопудово сделаю какую-нить статейку. ну вот сырые данные в картинке во вложении. Под итерациями я здесь подразумеваю сколько раз алгоритму требуется пройтись по циклу while() : Код while( firstEstimation - nextEstimation != 0 ) { firstEstimation = nextEstimation;
nextEstimation = ( firstEstimation + quotient )/2;
//for next iteration check in while() quotient = radicand/firstEstimation;
//for debug ++iterationCnt; } //while а в main() прогоняю такие числа: Код for( int k = 0, g = 50; k < 50; ++k, --g) { temp = k*k + g*g; i = ( float )k; q = ( float )g; std::cout << "<cmath> sqrt(): " << sqrt(temp) << " my sqrt(): " << sqrtIQ(i, q) << " perform in " << iterationCnt << " iterations"<< std::endl; } // for
Эскизы прикрепленных изображений
--------------------
"Об уме человека вернее судить по его вопросам, нежели по его ответам" (с)
|
|
|
|
Сообщений в этой теме
Rostislav Очень нужна помощь в оптимизации алгоритма извлечения квадратного корня Dec 4 2012, 22:16 alexeyv Если нужна только целая часть квадратного корня, т... Dec 5 2012, 03:37 Rostislav Цитата(alexeyv @ Dec 5 2012, 06:37) 1 = 1... Dec 5 2012, 06:09  Tanya Цитата(Rostislav @ Dec 5 2012, 10:09) Заб... Dec 5 2012, 06:28 Rostislav Что забавляет? Все)) Магия чисел в особенности))
... Dec 5 2012, 06:55 MrYuran Цитата(Rostislav @ Dec 5 2012, 10:55) Где... Dec 5 2012, 06:59 Rostislav Кстати, детская арифметика заканчивается начиная с... Dec 5 2012, 07:11 skyv Я использовал просто таблицу, которую предваритель... Dec 5 2012, 10:59 Rostislav Цитата(skyv @ Dec 5 2012, 13:59) Я исполь... Dec 5 2012, 11:04  Lmx2315 QUOTE (Rostislav @ Dec 5 2012, 15:04) А В... Dec 5 2012, 11:14   skyv Цитата(Lmx2315 @ Dec 5 2012, 15:14) ..мог... Dec 6 2012, 10:52 MrYuran
Можно скомбинировать.
Таблицу для грубого опреде... Dec 5 2012, 11:28 Rostislav Цитата(MrYuran @ Dec 5 2012, 14:28) Можно... Dec 5 2012, 11:39 sysel Не знаю, как называется метод, но пашет:
Код// Выч... Dec 5 2012, 13:56 анатолий Вот функция корня по алгоритму CORDIC
Кодfunction ... Dec 8 2012, 21:23 Rostislav Цитата(анатолий @ Dec 9 2012, 00:23) Вот ... Dec 11 2012, 06:07  анатолий Цитата(Rostislav @ Dec 11 2012, 08:07) чт... Dec 11 2012, 19:16 TSerg Кодfunction intSqrt_(Val : Longword) ... Dec 11 2012, 11:41 akorud Есть возможность использовать floating-point? Може... Dec 11 2012, 18:41 VitekSVM http://algolist.manual.ru/maths/count_fast/index.p... Dec 20 2012, 13:41 ASN Rostislav
С какой практической точностью нужно выч... Dec 20 2012, 14:38 Rostislav Цитата(ASN @ Dec 20 2012, 17:38) С какой ... Dec 20 2012, 20:46  beaRTS Цитата(Rostislav @ Dec 21 2012, 00:46) [c... Dec 21 2012, 02:07   Rostislav Цитата(beaRTS @ Dec 21 2012, 05:07) temp ... Dec 21 2012, 05:56    beaRTS Цитата(Rostislav @ Dec 21 2012, 08:56) Да... Dec 21 2012, 06:16     Rostislav Цитата(beaRTS @ Dec 21 2012, 09:16) а, ну... Dec 21 2012, 06:19 blackfin Сто раз уже обсуждали: ReAl. Dec 21 2012, 06:19 Rostislav Цитата(blackfin @ Dec 21 2012, 09:19) Сто... Dec 21 2012, 06:24 beaRTS Цитата(blackfin @ Dec 21 2012, 09:19) Сто... Dec 21 2012, 06:27  Rostislav Цитата(beaRTS @ Dec 21 2012, 09:27) ...я ... Dec 21 2012, 06:31  beaRTS Цитата(Rostislav @ Dec 21 2012, 14:10) ЗЫ... Dec 22 2012, 08:50  TSerg Цитата(Rostislav @ Dec 21 2012, 15:10) Ва... Dec 22 2012, 17:47 Rostislav TSerg, Ваш вариант описывается тут: http://en.wiki... Dec 22 2012, 08:25 beaRTS по поводу своей идеи начал новую тему. вот здесь к... Dec 22 2012, 16:06
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|