| 28.10.2011 12:00 | |
Это вторая часть рассказа о вычислении многочлена в точке. Первую часть можно найти тут.
Здесь мы рассмотрим алгоритм Патерсона и Стокмеера, который делает наименьшее (из известных мне) количество умножений, при условии, что при запросах к вычислению значения можно использовать только арифметические операции (*, +, -). На стадии предподсчета понадобится еще и деление. Можно ли сделать это быстрее при таких ограничениях - пока открытый вопрос [1].
К сожалению, еще одним необходимимым фактором является то, что поле над которым рассматриваются многочлены должно быть нулевой характеристики. Грубо говоря, это означает, что все элементы вида (1 + 1 + ... + 1) различны. Хорошей новостью является, что подойдут как вещетвенные, так и комплексные и рациональные числа. Из часто встречаемых на практике отпадает только модулярная арифметика.
Заявленное количество умножений n/2 + 2log(n), сложений 3n/2 - 1, на один запрос вычисления многочлена. (здесь и далее все логарифмы по двоичному основанию).
Для начала предположим, что в данном нам многочлене ровно n = 2^k слагаемых и коэффициент при старшей степени равен единице. Т.е. многочлен приведенный степени n - 1.
Тогда его можно удобно поделить на две половины, тоже длиной степени двойки и воспользоваться известным принципом "разделяй и властвуй":
к правой части никаких замечаний нет, но у левой старший коэффициент не равен единице. Но это легко исправить, заметив, что в скобках "почти такой же" многочлен:

Если сравнить это с предыдущим выражением, понятно, что неизвестные выражаются по следующим формулам:

Эти коэффициенты и находятся на стадии предподсчета. А при вычислении многочлена в точке мы просто счтаем его на левой половине, на првой и складываем (все иксы в степени 2^i подсчитаем, всего за log(n) умножений, и они нам еще потом понадобятся!).
Количество умножений выражается реккурентной формулой M(k) = 2 * M(k - 1) + 1, где M(k) - количество умножений на многочлене длины 2^k. Приведенный многочлен степени один (т.е. длины 2 = 2^1) высчитывается без умножений, т.е. M(1) = 0.
Решая реккурентное соотношение, получаем: M(k) = 2^{k-1} - 1 = n / 2 - 1.
Если мы хотим, чтобы начальный многочлен был общего вида, а не приведенный, то понадобится еще одно умножение (а на стадии предподсчета нормировка, т.е. деление всех коэф. на старший). Итого на вычисление многочлена длины n = 2^k требуется n / 2 умножений.
Аналогично для сложения: A(k) = 2 * A(k - 1) + 2, A(1) = 1. Т.о. A(k) = 3*2^{k-1} - 2 = 3n/2 - 2.
Формулы для реккурентных соотношений легко доказываются по индукции, если знать ответ, или же можно использовать производящие ряды и явно получить их =)
Теперь у нас многочлен общего вида, и в нем ровно n слагаемых. Допустим в битовой записи числа n ровно k единичек (k ~ log(n)). Тогда можно представить число n в виде суммы соответствующих степеней двоек, а сам многочлен разложить в виде:


Каждый "маленький многочлен" длиной pj мы вычисляем за pj / 2 умножений.
Стало быть, всего (p1 + ... + pk) / 2 = n / 2 умножений.
Еще один log(n) - вычисление степеней x, второй - умножение на них, соответствующих частей выражения.
Итого n/2 + 2log(n).
Аналогично со сложениями 3n/2 - log(n).
Ни один "из маленьких" многочленов не должен иметь нулевой старший коэффициент, а то его длина будет меньше степени двойки, предыдущая часть не сможет его нормировать и сломается. Но если какой-то коэффициент многочлена нулевой, на стадии предподсчета легко сдвинуть x' = x + c, и пересчитать коэффициенты многочлена. Это добавит нам еще одно сложение в копилку при вычислении запроса (сдвиг исходного x).
Ну вот и все, спасибо за внимание, тем дочитал аж до сюда! Я могу вам предложить интереснейшую литературу по этому и другим вопросам алгебраической сложности:
[1] P. Burgisser, M. Clausen, M. Amin Shokrouahi, Agebraic Complexity Theory.
Пожалуйста, обратитесь к странице Уведомление об оптимизации для более подробной информации относительно производительности и оптимизации в программных продуктах компании Intel.
Комментарии (0) 
Обратная ссылка (0)
Оставить комментарий 
Для получения технической помощи посетите сайт службы поддержки.
Автор
adavydow
|

