Разделяй и властвуй. Повышение эффективности алгоритмов. Часть 3
В прошлой части мы рассмотрели общий подход к расчету эффективности алгоритмов с принципом "разделяй и властвуй", а также применение принципа к различным базовым алгоритмам.
Сегодня поговорим о следующем приеме. Как известно, составная часть принципа, это поделить задачу на подзадачи. Мы ни разу не касались, как именно делить. Просто делили на равные части. Но тут вот и есть нюанс, если поделить не абы как, а используя какую-то стратегию, то можно добиться применения принципа там, где это даже не очевидно. И именно эта тема станет предметом данной статьи на примере задачи умножения полиномов. Как и в предыдущих частях, я упрощаю математическую часть, опуская различные нюансы и частные случаи, с целью сохранить научно-популярный характер публикации. При этом я пытаюсь сохранить основные элементы алгоритмов и математических основ. Я хочу подать информацию в кратком доступном виде, в виде математического пересказа, и если у кого-либо возникнет интерес, тот может легко найти полные и строгие математические выкладки по данной теме.
Сигналы
Этот раздел об обработке сигналов здесь добавлен просто для иллюстрации того, как решение задачи умножения полиномов используется в нашей повседневной жизни. Этот раздел больше является познавательным. Если познавательная информация об обработке сигналов не интересна и вам хочется побыстрее перейти к разбору самого алгоритма, то можно пропустить этот раздел и перейти к разделу: Модель полиномов
Сигнал в общем случае, это некоторый показатель изменяющийся во времени. Это может быть огибающая звука, диаграмма распределения, статистические данные, яркость видеосигнала и др. Для того чтобы обрабатывать сигнал компьютерными алгоритмами сигнал "оцифровывают", т.е. заменяют непрерывный сигнал
Также принято следующее компактное представление оцифрованного сигнала, облегчающего математику с сигналом
Данный сигнал оцифрован в набор из
Далее компьютерная программа занимается преобразованием
Большой интерес в работе с сигналами представляют, так называемые, линейные преобразования. Это такие преобразования
не зависят от сдвига по времени. То есть, если сигнал
сдвинут по времени, то результат его преобразования также сдвигается по времени на ту же величину сохраняют линейное преобразование сигнала. То есть если сигнал
, то результат его преобразования будет
Используя второе свойство линейности, можем записать преобразование используя представление сигнала из формулы (1)
Далее используя первое свойство независимости линейного преобразования от сдвига по времени
И получается, чтобы выполнить линейное преобразование любого сигнала,нам нужно лишь посчитать одно преобразование от "дельта-сигнала"
Тогда, продолжим преобразование в формуле (2)
Наивное вычисление по этой формуле всех составляющих сигнала
Резюме:
Любой сигнал для обработки оцифровывается и представляется в виде некоторого набора дискретных значений
Линейное преобразование сигнала также возможно задать набором дискретных значений
Формула (3) позволяет вычислить результат линейного преобразования сигнала
Модель полиномов
Итак выше мы получили задачу, которую нам надо оптимально вычислять, чтобы обрабатывать сигналы. Сформулируем ее еще раз:
Даны
Эффективное решение данной задачи позволит нам эффективно обрабатывать оцифрованные сигналы, как мы видели в разделе выше.
Как будем решать такую задачу? Более того, как свести эту задачу к методу "Разделяй и властвуй"? Если подойти к решению наивным методом, то мы для каждого
Формула (4) выглядит довольно простой. Применима она не только для линейного преобразования сигналов. Можно легко вспомнить еще одну простую математическую задачу, для решения которой потребуется выполнить вычисления по формуле (4)
Пусть у нас есть два полинома:
И нам нужно вычислить новый полином, который является произведением этих двух данных полиномов
Легко проверяется, что в общем случае, чтобы вычислить
Что в точности соответствует нашей исходной задаче (4)
Таким образом мы свели исходную задачу к задаче нахождения произведения двух полиномов за оптимальное время, и теперь мы будем решать эту задачу.
Альтернативное представление полинома
Любой полином степени
, то в этой интерпретации легко вычислить результирующий полином. Ведь если мы хотим в той же "системе счисления" получить произведение двух полиномов, то есть найти новый полином со значения в этих точках, то очевидно, что нам достаточно просто перемножить значение одного полинома на значение другого полинома:
Что потребует всего
Если мы найдем алгоритм, которым сможем эффективно переводить полиномы, задаваемые коэффициентами
, то далее у нас будет задача линейной сложности по вычислению
Как эффективно вычислить полином
в
Но, что если точки, в количестве
Полином из (5) можно разрезать на две части, с четными степенями
В этом случае данный полином можно записать как
Где два полинома
Но самое главное, что для четно-нечетных пар нам потребуется вычислить значения этих полиномов уже не в
Ничего не напоминает? Мы начали вычислять значения полинома степени
Рекурсивное соотношение
Согласно мастер-теореме дает результат
Но, позвольте, ведь, когда мы спускались на нижний уровень рекурсии, мы возвели в квадрат наши положительно-отрицательные пары и получили вместо положительно-отрицательных пар положительные числа, с которыми уже так просто не спустишься на следующий уровень рекурсии.
Казалось бы да, но на помощь приходят комплексные числа. Допустим у нас есть набор из 4-ёх положительно-отрицательных пар:
После того как мы каждую из этих пар возведем в квадрат, исчезнет плюс/минус, и получится 4 числа.
Заметьте, у нас опять вышли две положительно отрицательные пары:
Если мы возведем их в квадрат, то опять исчезнет плюс/минус, первое число даст +1, второе даст -1 и у нас опять будет одна положительно отрицательная пара.
То есть, для вычисления значения полинома можно выбрать такие точки, которые будут положительно отрицательными парами, и при возведении в квадрат останутся также набором положительно-отрицательных пар, что позволит совершать рекурсии. Тогда значения полинома можно вычислить по формуле (6) для квадратов этих положительно отрицательных пар. Затем, так как эти квадраты все еще остались положительно-отрицательными парами, мы можем повторить рекурсивно разбиение по формуле (6) и выйти на полиномы еще меньшей степени.
В общем случае, чтобы выбрать нужные точки, в которых провести вычисления, в количестве
Тогда в качестве точек, образующих положительно-отрицательные пары будет для
Уравнение в комплексных числах решается довольно просто и имеет следующие корни
Для чётного
для 1 это
для
это и т.д.
При возведении этих чисел в квадрат, каждая положительно-отрицательная пара дает число, которое также является одним из корней, то есть также находится в множестве
Подведем промежуточный итог:
Мы получили алгоритм, который позволяет вычислить значения полиномов степени
в точке за время и, используя этот алгоритм, перевели перемножаемые полиномы, задаваемые коэффициентами ; при степенях в полиномы задаваемыми значениями в точках
Далее мы за линейное время вычислили произведения этих полиномов
Осталась одна задача. Перевести полином, заданный значениями в
точке в привычный вид
Интерполяция
Это известная задача - интерполяция полинома степени
В
По этим значениям надо вычислить коэффициенты
В общем случае (8) это линейная система уравнений, которую надо решить относительно неизвестных
Надо просто найти матрицу, обратную к квадратной
Проблема в том, что в общем случае нахождение обратной матрицы имеет сложность
На помощь приходит то, что множество точек для интерполяции
Тогда, с учетом (7) матрица M выглядит следующим образом
Если задать формулу для
Данная матрица называется оператором дискретного преобразования Фурье и обладает рядом замечательных свойств, применяемые в различных областях. Заметим, что эта матрица является постоянной, совершенно не зависящей от того, какие полиномы мы перемножаем и зависящей только от размерности
Возьмем матрицу
По известной формуле умножения двух матриц
Заметим, что для сопряженного значения справедливо следующее:
Тогда
Действительно, если
Интуитивно понятно, но если хотите более математического обоснования, то оно следующее:
Пусть
Умножим эту сумму на
Так как
Следовательно, матрица
То есть
Заметим, что имея вычисленную матрицу
Аналогично, можно отразить элементы и по горизонтали. Обозначим эту матрицу как
Чтобы наивно провести вычисления по формуле (9) потребуется вычисления сложности
Прием следующий. Давайте в матрице (10) переставим колонки. Сначала будут идти все четные колонки (0,2,4...), потом все нечетные (1,3,5...)
Чтобы результат вычислений по формуле (9) после такой перестановки не изменился, то мы одновременно переставим коэффициенты
Разобьем эту матрицу на 4 равных матричных блока
Элементы матрицы
Элементы матрицы
Элементы матрицы
Элементы матрицы
Получается, что вместо наивного вычисления по формуле (9), мы можем провести следующие рекурсивные вычисления:
Для
Для
И мы опять свели задачу вычисления формулы (9) размера
что по мастер-теореме дает нам результат
Данный алгоритм, который мы рассматривали в этой публикации называется алгоритмом быстрого преобразования Фурье
Заключение
Мы рассмотрели решение вычислительной задачи
Мы разделили ее на следующие этапы, где почти на каждом этапе применяли метод "Разделяй и властвуй"
Свели задачу к умножению двух полиномов
Привели полиномы к альтернативному представлению за время
За линейное время нашли произведение полиномов этом альтернативном представлении
Привели результирующий полином из альтернативного к традиционному представлению за время