Алгоритм Ремеза в экселе

Sep 15, 2021 21:53

Вот и до него руки дошли, причина станет ясна в следующем посте. Изучать чужие библиотеки было лениво (в том же BOOSTе сам чёрт ногу сломит), писать самому - тоже, а вот "в полуавтоматическом режиме" в Excel - вышло в пол-пинка.

Для примера возьмём приближение


при условии x2+y2=1.

Чтобы подобрать коэффициенты, делаем "замену" x=cos(z), y=sin(z), и по сути:



Используя метод наименьших квадратов и "вручную" подбирая диапазон оптимизации, мы смогли подобрать α, β чтобы арктангенс считался с точностью не хуже 2,5 угловых минут. Позже, сделав интерполяцию по узлам Чебышёва, смог получить результат чуть лучше: 2,36 угловых минут. Интересно, можно ли улучшить этот результат, и насколько сильно.

Нам понадобится график ошибки, который приводили в прошлый раз:




Мы должны выписать все значения z, на которых достигаются минимумы и максимумы этой функции ошибки. Я его строил с шагом в 0,1 градус, поэтому значения получаются такие:

13,8° (минимум); 36,3° (максимум); 45° (конец диапазона, "в минус").

Обычно для самой первой итерации, когда ещё НИКАКОГО ПРИБЛИЖЕНИЯ НЕТ, вместо нахождения этих минимумов и максимумов просто берут узлы Чебышева, сколько нужно. В моём случае весь диапазон от -45 до 45 градусов, на нём получится 6 максимумов/минимумов, значит, взяли бы n=6.

Вышло бы 11,65°; 31,82°, 43,46° и такие же со знаком "-". Довольно близко...

И далее решаем систему линейных уравнений: мы хотим, чтобы







Неизвестными здесь являются α, β и величина ошибки E. Т.е мы ТРЕБУЕМ, чтобы функция ошибки прыгала вверх-вниз, и чтобы все её максимумы и минимумы были одинаковы!

Это система линейных уравнений. Я в Excel сначала выписал значения z1, z2, z3:




Формулы частично на русском языке - то ещё "удовольствие", ну да ладно. Главное, у меня переключение раскладки стоит по Ctrl+Shift, потому что Alt+Shift слишком уж часто "теряет фокус", куда-то на меню его уносит, бесило страшно!

Нам, понятно, это в радианах нужно, градусы это мне для удобства. Выходит так:




Далее ввожу формулы для коэффициентов системы уравнений. Одну строчку "ручками", затем "растягиваю" на строчку вниз, и единицу во второй строке заменяю на "умножение прошлого значения на -1" , и растягиваю ещё на строчку. Вот показываю формулы:




В виде значений:



Далее требуется "ловкость рук", чтобы найти обратную матрицу. Сначала выделяем пустую область 3х3 где-нибудь ниже:



И вводим формулу:



Но закрыв скобку, нажимаем Ctrl+Shift+Enter! Только в этом случае он воспримет результат этой операции в виде массива 3х3 - и распределит его по выбранной области:




Осталось умножить эту обратную матрицу на столбец (Z1,Z2,Z3), который у нас уже торчит наверху. Для этого выделяем пустой столбец в 3 ячейки, вводим в него формулу =МУМНОЖ(A10:C12;B2:B4) и снова Ctrl+Shift+Enter. Вуаля:



На этом одна итерация алгоритма Ремеза завершена!

Мы получили новые значения α и β и ещё значение E=0,000664579 радиан = 0,038 градусов. Правда, не нужно радоваться раньше времени! данное значение ещё не означает, что ошибка будет именно такова - такая она получилась в этих 3 точках, а больше ни о чём данный алгоритм "не знает". Чтобы узнать реальную ошибку, надо снова построить графики. Я это делаю "по-старинке", вот так:




Понятно: первую строку ввожу "от руки", причём ткнувшись мышкой по "альфе", тут же жму F4, что "оборачивает" её в доллары, т.е при копировании данная ячейка смещаться никуда не будет. А дальше достаточно "растянуть" вниз, пока не дойдёт до угла в 45 градусов. Вот что у нас выходит:



Очень чётко все 3 максимума/минимума совпадают по абсолютной величине: 0,038°. Можно ещё "честно" найти минимальное и максимальное значения на этой "простыне", и мы получим:

-0,038079292
0,038082253

Вот этому значению уже вполне можно доверять!

Давайте проведём ещё одну итерацию, это очень просто:
надо найти координаты новых максимумов и минимумов, это 13,72°, 36,22° и, разумеется, 45°. Подставляем их в столбец z1,z2,z3, с которого мы начали - и далее всё пересчитается автоматически.

Но "визуально" ничего не изменилось, но теперь мы получаем следующие максимум и минимум:

-0,038080136
0,038080136

Вот теперь они совпали, насколько хватает разрядности, и на самую-самую малость максимальная ошибка снизилась, аж на 0,0076 угловой секунды!

В общем, делать ещё итерации большого смысла уже нет.

Как я и ожидал, удалось добиться улучшения, но не очень большого: с 2,36 угловых минут до 2,28 угловых минут (ещё минус 3,3%) и это, похоже, предел для такой формулы.

Кстати, далеко не факт, что "стандартная реализация" алг. Ремеза мне бы помогла. Тут были заморочки с тем, что функция нечётная, поэтому я брал полный интервал, но на деле использовал точки только на его половине и ни капли не возмущался, что в нуле ошибка уходит в ноль. По-моему, если здесь подойти слишком "в лоб" - система уравнений получилась бы вырожденной, с повторяющимися значениями, и пришлось бы танцевать с бубном, соображая, как так ему это впихнуть. А ещё далеко не все принимают такой интересный набор базисных функций, как синусы. Для большинства используются многочлены, но только от одной переменной. Да и самостоятельно писать программу, которая бы позволяла всё это дело учесть - я бы зарылся ещё на недельку-другую...

странные девайсы, математика, ПЛИС, программки, работа

Previous post Next post
Up