Умножение многочлена на многочлен правило. Произведение многочленов

Во всех приведенных ниже формулах буквами u и v обозначены дифференцируемые функции независимой переменной x : , , а буквами a , c, n - постоянные:

3.

4.

5.

6.

Остальные формулы записаны как для функций независимой переменной, так и для сложных функций:

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

7а.

8а.

9а.

10а.

11а.

12а.

13а.

14а.

15а.

16а.

17а.

При решении приведенных ниже примеров сделаны подробные записи. Однако следует научиться дифференцировать без промежуточных записей.

Пример 1. Найти производную функции .

Решение. Данная функция есть алгебраическая сумма функций. Дифференцируем ее, используя формулы 3, 5, 7 и 8:

Пример 2. Найти производную функции

Решение. Применяя формулы 6, 3, 7 и 1, получим

Пример 3. Найти производную функции и вычислить ее значение при

Решение. Это сложная функция с промежуточным аргументом . Используя формулы 7а и 10, имеем

Вычислим значение производной при :

.

Пример 4. Найти производную функции .

Решение. Это сложная функция с промежуточным аргументом . Применяя формулы 3, 5, 7а, 11, 16а, получим

Пример 5. Найти производную функции .

Решение. Дифференцируем данную функцию по формулам 6, 12, 3 и 1:

Пример 6. Найти производную функции

Решение. Сначала преобразуем функцию, используя свойства логарифмов :

Теперь дифференцируем по формулам 3, 16а, 7 и 1:

.

Вычислим значение производной при .

Пример 7. Найти производную функции и вычислить ее значение при .

Решение. Используем формулы 6, 3, 14а, 9а, 5 и 1:

.

Вычислим значение производной при :

.

Геометрический смысл производной.

Производная функции имеет простую и важную геометрическую интерпретацию .

Если функция дифференцируема в точке х , то график этой функции имеет в соответствующей точке касательную, причем угловой коэффициент касательной равен значению производной в рассматриваемой точке.

Угловой коэффициент касательной, проведенной к графику функции в точке (х 0 , у 0), равен значению производной функции при х = х 0 , т.е. .

Уравнение этой касательной имеет вид

Пример 8 . Составить уравнение касательной к графику функции в точке А (3,6).

Решение. Для нахождения углового коэффициента касательной найдем производную данной функции:

.

х = 3:

Уравнение касательной имеет вид

Или , т.е.

Пример 9. Составить уравнение касательной, проведенной к графику функции в точке с абсциссой х=2 .

Решение. Сначала найдем ординату точки касания . Так как точка А лежит на кривой, то ее координаты удовлетворяют уравнению кривой, т.е.


; .

Уравнение касательной, проведенной к кривой в точке , имеет вид . Для нахождения углового коэффициента касательной найдем производную:

.

Угловой коэффициент касательной равен значению производной функции при х = 2:

Уравнение касательной таково:

, , т.е.

Физический смысл производной. Если тело движется по прямой по закону s=s(t ), то за промежуток времени (от момента t до момента ) оно пройдет некоторый путь . Тогда есть средняя скорость движения за промежуток времени .

Скоростью движения тела в данный момент времени t называется предел отношения пути к приращению времени , когда приращение времени стремиться к нулю:

.

Следовательно, производная пути s по времени t равна скорости прямолинейного движения тела в данный момент времени:

.

Скорость протекания физических, химических и других процессов также выражается с помощью производной.

Производная функции равна скорости изменения этой функции при данном значении аргумента х :

Пример 10. Закон движения точки по прямой задан формулой (s - в метрах, t - в секундах). Найти скорость движения точки в конце первой секунды.

Решение. Скорость движения точки в данный момент времени равна производной пути s по времени t :

,

Итак, скорость движения точки в конце первой секунды равна 9 м/с.

Пример 11. Тело, брошенное вертикально вверх, движется по закону , где v 0 - начальная скорость, g - ускорение свободного падения тела. Найти скорость этого движения для любого момента времени t . Сколько времени будет подниматься тело и на какую высоту оно поднимется, если v 0 = 40 м/с?

Решение. Скорость движения точки в данный момент времени t равна производной пути s по времени t:

.

В высшей точке подъема скорость тела равна нулю:

, , , , с.

За 40/g секунд тело поднимается на высоту

Вторая производная.

Производная функции в общем случае является функцией от х . Если от этой функции вычислить производную, то получим производную второго порядка или вторую производную функции .

Второй производной функции называется производная от ее первой производной .

Вторая производная функции обозначается одним из символов - , , . Таким образом, .

Аналогично определяются и обозначаются производные любого порядка. Например, производная третьего порядка:

или ,

Пример 12. .

Решение. Сначала найдем первую производную

Пример 13. Найти вторую производную функции и вычислить ее значение при х=2 .

Решение. Сначала найдем первую производную:

Дифференцируя еще раз, найдем вторую производную:

Вычислим значение второй производной при х=2 ; имеем

Физический смысл второй производной.

Если тело движется прямолинейно по закону s = s(t) , то вторая производная пути s по времени t равна ускорению движения тела в данный момент времени t:

Таким образом, первая производная характеризует скорость некоторого процесса, а вторая производная - ускорение того же процесса.

Пример 14. Точка движется по прямой по закону . Найти скорость и ускорение движения .

Решение. Скорость движения тела в данный момент времени равна производной пути s по времени t, а ускорение - второй производной пути s по времени t . Находим:

; тогда ;

; тогда

Пример 15. Скорость прямолинейного движения пропорциональна квадратному корню из пройденного пути (как, например, при свободном падении). Доказать, что это движение происходит под действием постоянной силы.

Решение. По закону Ньютона , сила F, вызывающая движение, пропорциональна ускорению, т.е.

или

Согласно условию, . Дифференцируя это равенство, найдем

Следовательно, действующая сила .

Приложения производной к исследованию функции .

1) Условие возрастания функции : Дифференцируемая функция y = f(x) монотонно возрастает на промежутке Х тогда и только тогда, когда её производная больше ноля, т. е. y = f(x) f’(x) > 0 . Это условие геометрически означает, чтокасательная к графику данной функции образует острый угол с положительным направлением к оси оХ.

2) Условие убывания функции : Дифференцируемая функция y = f(x) монотонно убывает на промежутке Х тогда и только тогда, когда её производная меньше ноля, т. е.

y = f(x)↓ f’(x)Это условие геометрически означает, чтокасательная к графику данной функции образует тупой угол с положительным направлением оси оХ)

3) Условие постоянства функции: Дифференцируемая функция y = f(x) постоянна на промежутке Х тогда и только тогда, когда её производная равна нулю, т. е. y = f(x) - постоянна f’(x) = 0 . Это условие геометрически означает, чтокасательная к графику данной функции параллельна оси оХ, т. е. α = 0)

Экстремумы функции.

Определение 1 : Точку х = х 0 называют точкой минимума функции y = f(x), если у этой точки существует окрестность, для всех точек которой (кроме самой точки) выполняется неравенство f(x)> f(x 0)

Определение 2: Точку х = х 0 называют точкой максимума функции y = f(x), если у этой точки существует окрестность, для всех точек которой (кроме самой точки) выполняется неравенство f(x) < f(x 0).

Определение 3: Точку минимума или максимума функции называют точкой экстремума . Значение функции в этой точке называют экстремальным.

Замечания : 1. Максимум (минимум) не является обязательно наибольшим (наименьшим) значением функции;

2. Функция может иметь несколько максимумов или минимумо;

3. Функция, определённая на отрезке, может достигать экстремума только во внутренних точках этого отрезка.

5) Необходимое условие экстремума: Если функция y = f(x) имеет экстремум в точке х = х 0 , то в этой точке производная равна нулю или не существует. Эти точки называются критическими точками 1 рода .

6) Достаточные условия существования экстремума функции: Пусть функция y = f(x) непрерывна на промежутке Х и имеет внутри этого промежуткак ритическую точку 1 рода х = х 0 , то:

а) если у этой точки существует такая окрестность, в которой при х < х 0 f’(x) < 0, а при x> x 0 f’(x) > 0, то х = х 0 является точкой минимума функции y = f(x);

б) если у этой точки существует такая окрестность, в которой при х < х 0 f’(x) > 0, а при x> x 0

f’(x) < 0, то х = х 0 является точкой максимума функции y = f(x);

в) если у этой точки существует такая окрестность, что в ней и справа и слева от точки х 0 знаки производной одинаковы, то в точке х 0 экстремума нет.

Промежутки убывания или возрастания функции называются промежутками монотонности.

Определение1: Кривая у = f(x) называется выпуклой вниз на промежутке а < х <в, если она лежит выше касательной в любой точке этого промежутка и кривая у = f(x) называется выпуклой вверх на промежутке а < х <в, если она лежит ниже касательной в любой точке этого промежутка.

Определение 2: Промежутки, в которых график функции обращён выпуклостью вверх или вниз, называются промежутками выпуклости графика функции.

Достаточное условие выпуклости кривой. График дифференцируемой функции Y = f(x) является выпуклым вверх на промежутке а < х <в, если f”(x) < 0 и выпуклым вниз , если f”(x) > 0.

Определение 1: Точки, в которых вторая производная равна нулю или не существует, называются критическими точками II рода .

Определение 2: Точка графика функцииY = f(x), разделяющая промежутки выпуклости противоположенных направлений этого графика, называется точкой перегиб.

точка перегиба

Пример : Дана функция у = х 3 - 2х 2 + 6х - 4.Исследовать функцию на промежутки монотонности и точки экстремума. Определить направление выпуклости и точки перегиба.

Решение: 1. Найдем область определения функции: D(y) = ;

2. Найдем первую производную: y’ = 3x 2 - 4x+ 6;

3. Решим уравнение: y’ = 0, 3x 2 - 4x+ 6 = 0, D 0, то данное уравнение не имеет решения, следовательно точек экстремуму нет. y’ , то функция возрастает на всей области определения.

4. Найдем вторую производную:y” = 6x - 4;

5. Решим уравнение: y” = 0, 6x - 4 = 0, х =

Ответ: ( ; - ) - точка перегиба, функция выпукла вверх при х и выпукла вверх при х

Асимптоты.

1. Определение : Асимптотой кривой называется прямая, к которой неограниченно приближается график данной функции.

2. Виды асимптот :

1) Вертикальные асимптоты . График функции y = f(x) имеет вертикальную асимптоту, если . Уравнение вертикальной асимптоты имеет вид х = а

2) Горизонтальные асимптоты . График функции y = f(x) имеет горизонтальную асимптоту, если . Уравнение горизонтальной асимптоты имеет вид у = b.

Пример 1 : Для функция y = найдите асимптоты.

3) Наклонные асимптоты. Прямая y = kx + b называется наклонной асимптотой графика функции y = f(x), если . Значения k и b вычисляются по формулам: k = ; b = .

Решение: , то y = 0 - горизонтальная асимптота;

(т. к. х - 3 ≠ 0, х ≠3), то х = 3 - вертикальная асимптота. ,т. е. k = 0, то кривая наклонной асимптоты не имеет.

Пример 2 : Для функции y = найдите асимптоты.

Решение: x 2 - 25 ≠ 0 при x ≠ ± 5, то х = 5 и х = - 5 являются горизонтальными асимптотами;

y = , то кривая не имеет вертикальной асимптоты;

k = ; b = , т. е. y = 5x - наклонная асимптота.

Примеры построения графиков функций .

Пример 1 .

Исследовать функцию и построить график функции у = х 3 - 6х 2 + 9х - 3

1. Найдём область определения функции: D(y) = R

2. Выясним, является ли данная функция чётной или нечетной:

у(- х) = (- х) 3 - 6·(- х) 2 + 9·(-х) - 3 = - х 3 - 6х 2 - 9х - 3 = - (х 3 + 6х 2 + 9х + 3), т. е.

(у = х 5 - х 3 - нечетная, у = х 4 + х 2 - четная)

3. Не является периодической.

4. Найдем точки пересечения с осями координат: если х = 0, то у = - 3 (0; - 3)

если У = 0, х найти затруднительно.

5. Найдем асимптоты графика функции: Вертикальных асимптот нет, т.к. нет значений х, при которых функция неопределенна; у = , т. е. горизонтальных асимптот нет;

k = , т. е. наклонных асимптот нет.

6. Исследуем функцию на промежутки монотонности и её экстремумы: y’ = 3x 2 - 12x + 9,

y’= 0, 3x 2 - 12x + 9 = 0 x 1 = 1; x 2 = 3 - критические точки 1 рода.

Определим знаки производной: y’(0) = 9 > 0; y’(2) = - 3 < 0; y’(4) = 9 > 0

y max = y(1) = 1, (1;1) - точка максимума; y min = y(3) = - 3, (3; - 3) - точка минимума, функция у при х и у .

7. Исследуем функцию на промежутки выпуклости и точки перегиба:

y” = (y’)’ = (3x 2 - 12x + 9)’ = 6x - 12, y” = 0, 6x - 12 = 0 x = 2 - критическая точка 1 рода.

Определим знаки второй производной: y”(0) = - 12 < 0; y”(3) = 6 > 0

Y(2) = - 1 (2; - 1) - точка перегиба, функция выпукла вверх при х и выпукла вниз при х .

8. Дополнительные точки:

х - 1
у - 19

9. Построим график функции:

Исследовать функцию и построить график функции у =

1. Найдём область определения функции: 1 - х ≠ 0, х ≠ 1, D(y) = .

2. Выясним, является ли данная функция чётной или нечетной: ,

у(- х) ≠ у(х) - не является чётной и у(- х) ≠ - у(х) - не является нечётной

3. Не является периодической.

4. Найдем точки пересечения с осями координат: х = 0, то у = - 2; у = 0, , то , т. е. (0; - 2); ().

5. Найдем асимптоты графика функции: т.к. х ≠ 1,то прямая х = 1 - вертикальная асимптота;

Правило вычисления произведения многочленов.

Для того чтобы рассмотреть произведение многочленов, для начала вспомним, как умножить одночлен на многочлен.

Произведение одночлена и многочлена находится следующим образом:

  • составляется произведение одночлена и многочлена.
  • раскрываются скобки.
  • группируются числа с числами, одинаковые переменные друг с другом.
  • перемножаются числа и складываются степени соответствующих одинаковых переменных.

Рассмотрим теперь умножение двух многочленов на примере:

Пример 1

Умножим многочлен $x-y+z$ на многочлен $\ {xy}^5+y^6-{xz}^5$.

Вначале запишем произведение многочленов:

\[\left(x-y+z\right)({xy}^5+y^6-{xz}^5)\]

Сделаем следующую замену. Пусть $x-y+z=t$, получим:

Получили произведение одночлена на многочлен. Найдем его по выше изложенному правилу.

Раскроем скобки:

Сделаем обратную замену:

\[{\left(x-y+z\right)xy}^5+{\left(x-y+z\right)y}^6-{\left(x-y+z\right)xz}^5\]

В данном выражении мы видим присутствие трех произведений одночленов на многочлен. Найдем их по отдельности по выше изложенному правилу:

\[{\left(x-y+z\right)xy}^5=x{xy}^5-y{xy}^5+z{xy}^5={x^2y}^5-{xy}^6+z{xy}^5\] \[{\left(x-y+z\right)y}^6=xy^6-yy^6+zy^6=xy^6-y^7+zy^6\] \[{\left(x-y+z\right)xz}^5=x{xz}^5-y{xz}^5+z{xz}^5=x^2z^5-xyz^5+{xz}^6\]

Перепишем наше выражение:

\[\left({x^2y}^5-{xy}^6+z{xy}^5\right)+\left(xy^6-y^7+zy^6\right)-(x^2z^5-xyz^5+{xz}^6)\]

Раскроем скобки. Напомним, что если перед скобками стоит знак плюс, то знаки в скобках остаются неизменными, а если перед скобками стоит знак минус, то знаки в скобках изменятся на противоположные. Получим

\[{x^2y}^5-{xy}^6+z{xy}^5+xy^6-y^7+zy^6-x^2z^5+xyz^5-{xz}^6\]

Получили многочлен. Осталось только привести его к стандартному виду. Итого, в ответе, получим:

\[{x^2y}^5+xy^5z-y^7+zy^6-x^2z^5+xyz^5-{xz}^6\]

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

Правило: Для того, чтобы умножить многочлен на многочлен, необходимо каждый член первого многочлена умножить на каждый член второго многочлен, сложить полученные произведения и полученный многочлен привести к стандартному виду.

Пример 2

Выполнить умножение $2x+y$ и $x^2+2y+3$.

Запишем произведение:

\[\left(2x+y\right)(x^2+2y+3)\]

\[\left(2x+y\right)\left(x^2+2y+3\right)=2x^3+4xy+6x+x^2y+2y^2+3y\]

Видим, что полученный многочлен имеет стандартный вид, значит умножение закончено.

Примеры задач на произведение многочленов

Пример 3

Выполнить умножение многочлена на многочлен:

а) $(2z+1)\ и\ (z^2-7z-3)$

б) $(1-4x^2)\ и\ (5y^2-3x-2)$

Решение:

а) $(2z+1)\ и\ (z^2-7z-3)$

Составим произведение:

\[(2z+1)\cdot (z^2-7z-3)\]

Раскроем скобки по правилу произведения многочленов:

б) $(1-4x^2)\ и\ (5y^2-3x-2)$

Составим произведение:

\[(1-4x^2)\cdot (5y^2-3x-2)\]

Раскроем скобки по правилу произведения многочленов:

Видим, что полученный многочлен имеет стандартный вид, следовательно:

Ответ: $5y^2-3x-2-20x^2y^2+12x^3+8x^2$.

в) $(2n-5n^3)\ и\ (3n^2-n^3+n)$

Составим произведение:

\[(2n-5n^3)\cdot (3n^2-n^3+n)\]

Раскроем скобки по правилу произведения многочленов:

Приведем данный многочлен к стандартному виду:

г) $(a^2+a+1)\ и\ (a^2-24a+6)$

Составим произведение:

\[(a^2+a+1)\cdot (a^2-24a+6)\]

Раскроем скобки по правилу произведения многочленов:

Приведем данный многочлен к стандартному виду.

Для умножения многочлена на многочлен существует очень легкое правило. Чтобы умножить два многочлена между собой, надо каждый член первого многочлена умножить на каждый член второго многочлена. После это полученные произведения сложить и привести подобные.

На рисунке представлена общая схема перемножения.

Решим пример представленный на рисунке.
(4*x + 8*x*y) * (2*x + 3*y - 4) =
4*x*2*x + 4*x*3*y + 4*x*(-4) + 8*x*y*2*x + 8*x*y*3*y + 8*x*y*(-4) =
8*x^2 + 12*x*y - 16*x + 16*x^2*y + 24*x*y^2 - 32*x*y

Теперь приводим подобные слагаемые и получаем многочлен в стандартном виде.
8*x^2-20* x*y - 16*x + 16*x^2*y + 24*x*y^2
Если необходимо перемножить многочлены, у которых только одна переменная то можно умножение производить с помощью таблицы.

Рассмотрим пример:
Требуется перемножить два полинома x^5 +x^3 - 2*x^2 +3 и 2*x^4 - 3*x^3 + 4*x^2 - 1.
Для начала выпишем их коэффициенты. При чем в порядке убывания степеней неизвестных переменных, то есть от большей степени к меньшей. Если переменной в какой-то степени нет, то коэффициент взять равным нулю.

Таким образом, для полинома x^5 +x^3 - 2*x^2 +3 коэффициенты следующие 1; 0; 1; -2; 0; 3
Для полинома 2*x^4 - 3*x^3 + 4*x^2 - 1 коэффициенты 2; -3; 4; 0; -1.

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

Теперь остается записать ответ.
2*x^9 - 3*x^8 + 6*x^7 - 7*x^6 + 9*x^5 - 2*x^4 - 10*x^3 + 14*x^2 -3.

Нужна помощь в учебе?



Предыдущая тема:

Добрый вечер.
Этот пост посвящён быстрому преобразованию Фурье. Будут рассмотрены прямое и обратное преобразования (в комплексных числах). В следующей части я планирую рассмотреть их применения в некоторых задачах олимпиадного программирования (в частности, одна задача про «похожесть» строк), а также рассказать про реализацию преобразования в целых числах.
БПФ - это алгоритм, вычисляющий значения многочлена степени n =2 k в некоторых n точках за время O (n ⋅logn ) («наивный» метод выполняет ту же задачу за время O (n 2 )). За то же время можно выполнить и обратное преобразование. Так как складывать, вычитать и умножать массивы чисел гораздо легче, чем многочлены (особенно умножать), БПФ часто применяется для ускорения вычислений с многочленами и длинными числами.

Определения и способы применения

Для начала давайте определимся, что такое многочлен:
P (x )=a 0 +x a 1 +x 2 a 2 +x 3 a 3 +... +x n -1 a n -1

Комплексные числа

Если Вы знакомы с комплексными числами, то можете пропустить этот пункт, в противном случае, вот краткое определение:
x =a +i b , где i 2 =-1
Здесь a называется вещественной (Real ) частью, а b - мнимой (Imaginary ). В этих числах, как нетрудно заметить, можно извлекать корень из отрицательных (да и вообще любых) чисел - это очень удобно при работе с многочленам - как следует из основной теоремы алгебры, у каждого многочлена степени n имеется ровно n комплексных корней (с учётом кратности).
Также их очень удобно представлять в виде точек на плоскости:

Еще одним замечательным свойством комплексных чисел является то, что их можно представить в виде x =(cosα+i sinα)r , где α - полярный угол «числа» (называется аргументом ), а r - расстояние от нуля до него (модуль ). А при умножении двух чисел:
a =(cosα+i ⋅sinα)r a
b =(cosβ+i ⋅sinβ)r b
a b =(cosα+i ⋅sinα)(cosβ+i ⋅sinβ)r a r b
a b =(cosα⋅cosβ-sinα⋅sinβ+i (sinα⋅cosβ+cosβ⋅sinα))r a r b
a b =(cos(α+β)+i ⋅sin(α+β))r a r b
Их модули перемножаются, а аргументы складываются.

Комплексные корни из 1

Теперь давайте поймём, как выглядят комплексные корни n -ой степени из 1 . Пусть x n =1 , тогда его модуль, очевидно, равен единице, а n ⋅argx =2 πk , где k - целое. Это обозначает, что после n умножений числа на самого себя (т.е. возведения в n -ю степень) его аргумент станет «кратен» 2 π (360 градусам).
Вспомним формулу числа, если известен аргумент и модуль, получаем:
α=2 π⋅x /n , где 0 x
ω i =cosα+i ⋅sinα
Т.е. если порисовать, то мы получим просто точки на окружности через равные промежутки:

Прошу заметить три вещи, которыми мы будем активно пользоваться (без них ничего не получится):
ω a ⋅ω b =ω (a +b )modn
ω 0 1 2 +... n -1 =0
ω 0 n /2 2 n /2 4 n /2 =... =1 (при чётном n )
Из-за этих свойств именно в этих точках мы и будем считать значение многочлена. Разумеется, результаты необязательно будут вещественными, поэтому в программе потребуется работать с комплексными числами.

Почему сумма корней - ноль

Доказательство очень простое: пусть φ=ω 0 1 +... . Домножим обе части на ω 1 (!= 1). Т.к. ω i ⋅ω 1 i +1 , то φ⋅ω 1 1 2 +... n -1 0 . От перестановки слагаемых сумма не меняется, поэтому φ=φ⋅ω 1 , соответственно φ⋅(ω 1 -1 )=0 . Т.к. ω 1 != 1, то φ=0 .

Как работает

Будем считать, что наш многочлен имеет степень n =2 k . Если нет, дополним старшие коэффициенты нулями до ближайшей степени двойки.
Основная идея БПФ очень проста:
Пусть:
A (x )=a 0 +x a 2 +x 2 a 4 +... +x n /2 -1 a n -2 (четные коэффициэнты P )
B (x )=a 1 +x a 3 +x 2 a 5 +... +x n /2 -1 a n -1 (нечётные коэффициенты P ).
Тогда P (x )=A (x 2 )+x B (x 2 ).
Теперь применим принцип «разделяй и властвуй»: чтобы посчитать значения P в n точках (ω 0 1 ,... ), посчитаем значения A и B рекурсивно в n /2 точках (ω 0 2 ,... ). Теперь значение P i ) восстановить достаточно просто:
P i )=A 2 i )+ω i B 2 i )
Если обозначить за ξ i 2 i точки, в которых мы считаем значения многочлена степени n /2 , формула преобразится:
P i )=A i )+ω i B i )
Её уже можно загонять в программу, не забыв что i принимает значения от 0 до n -1 , а ξ i определено лишь от 0 до n /2 -1 . Вывод - надо будет взять i по модулю n /2 .
Время работы выражается рекуррентной формулой T (n )=O (n )+2 T (n /2 ). Это довольно известное соотношение и оно раскрывается в O (n ⋅log 2 n ) (грубо говоря, глубина рекурсии - log 2 n уровней, на каждом уровне суммарно по всем вызовам выполняется O (n ) операций).

Напишем что-нибудь

Вот пример неэффективной рекурсивной реализации БПФ:
Slow FFT
#include #include using namespace std; typedef complex cd; // STL-ное комплексное число. Нам нужен double, ведь мы работает с sin и cos typedef vector vcd; vcd fft(const vcd &as) { // Возвращает вектор значений в корнях из 1 int n = as.size(); // Когда-то же надо прекратить рекурсию? if (n == 1) return vcd(1, as); vcd w(n); // Считаем корни for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; w[i] = cd(cos(alpha), sin(alpha)); } // Считаем коэффициенты A и B vcd A(n / 2), B(n / 2); for (int i = 0; i < n / 2; i++) { A[i] = as; B[i] = as; } vcd Av = fft(A); vcd Bv = fft(B); vcd res(n); for (int i = 0; i < n; i++) res[i] = Av + w[i] * Bv; return res; }
Можете добавить ввод-вывод и проверить правильность своей реализации. Для многочлена P (x )=4 +3 x +2 x 2 +x 3 +0 x 4 +0 x 5 +0 x 6 +0 x 7 значения должны получиться такими:
P (w 0 )=(1 0 .0 0 0 ,0 .0 0 0 )
P (w 1 )=(5 .4 1 4 ,4 .8 2 8 )
P (w 2 )=(2 .0 0 0 ,2 .0 0 0 )
P (w 3 )=(2 .5 8 6 ,0 .8 2 8 )
P (w 4 )=(2 .0 0 0 ,0 .0 0 0 )
P (w 5 )=(2 .5 8 6 ,-0 .8 2 8 )
P (w 6 )=(2 .0 0 0 ,-2 .0 0 0 )
P (w 7 )=(5 .4 1 4 ,-4 .8 2 8 )
Если это так - можете засекать время рекурсивного и наивного метода на больших тестах.
У меня на многочлене степени 2 12 эта реализация работает 62 мс, наивная - 1800 мс. Разница налицо.

Избавляемся от рекурсии

Для того, чтобы сделать процедуру нерекурсивной, придётся подумать. Легче всего, как мне кажется, провести аналогию с MergeSort (сортировка слиянием) и нарисовать картинку, на которой показаны все рекурсивные вызовы:


Как мы видим, можно сделать один массив, заполнить его изначально значениями fft(a 0 ), fft(a 4 ), fft(a 2 ), ... . Как несложно понять, номера a i - это «развёрнутые» в двоичном представлении числа 0 ,1 ,2 ,3 ,... . Например, 1 1 0 =0 0 1 2 ,4 1 0 =1 0 0 2 или 6 =1 1 0 2 ,3 =0 1 1 2 . Понять это можно следующим образом: при спуске на нижний уровень рекурсии у нас определяется еще один младший бит (с конца). А при «нормальной» нумерации бит определяется с начала. Поэтому нужно «развернуть» число. Это можно сделать «в лоб» за O (n ⋅log 2 n ), а можно динамическим программированием за O (n ) по следующему алгоритму:
  1. Пробежимся циклом от 0 до n -1
  2. Будем хранить и динамически пересчитывать номер старшего единичного бита числа. Он меняется, только когда текущее число - степень двойки: увеличивается на 1.
  3. Когда мы знаем старший бит числа, перевернуть всё число не составляет труда: «отрезаем» старший бит (XOR), переворачиваем остаток (уже посчитанное значение) и добавляем «отрезанную» единицу
Теперь придумаем алгоритм, позволяющий нам из «ступеньки» получить ступеньку повыше. Хранить все значения с предыдущего шага мы будем в одном массиве. Как хорошо видно на рисунке, надо обрабатывать данные блоками по k , причём вначале k =1 , а потом с каждым шагом увеличивается вдвое. Мы обрабатываем два блока длиной k и получаем на выходе один блок длиной 2 k . Давайте на примере разберём, как это делалось рекурсивно, вспомним формулу из начала статьи и повторим:

Аргументами процедуры для слияния двух блоков будут два vector"а (естесственно, по ссылке, исходный и результат), номер стартового элемента первого блока (второй идёт сразу после) и длина блоков. Можно было бы конечно сделать и iterator"ами - для большей STL"ности, но мы ведь всё равно будем переносить эту процедуру внутрь основной для краткости.
Объединение блоков
void fft_merge(const vcd &src, vcd &dest, int start, int len) { int p1 = start; // Позиция в первом блоке int en1 = start + len; // Конец первого блока int p2 = start + len; // Позиция во втором блоке int en2 = star + len * 2; // Конец второго блока int pdest = start; // Текущая позиция в результатирующем массиве int nlen = len * 2; // Длина нового блока for (int i = 0; i < nlen; i++) { double alpha = 2 * M_PI * i / nlen; cd w = cd(cos(alpha), sin(alpha)); // Текущий корень dest = src + w * src; if (++p1 >= en1) p1 = start; if (++p2 >= en2) p2 = start + len; } }
И основная процедура преобразования:
<< k) < n) k++; vi rev(n); rev = 0; int high1 = -1; for (int i = 1; i < n; i++) { if ((i & (i - 1)) == 0) // Проверка на степень двойки. Если i ей является, то i-1 будет состоять из кучи единиц. high1++; rev[i] = rev; // Переворачиваем остаток rev[i] |= (1 << (k - high1 - 1)); // Добавляем старший бит } vcd cur(n); for (int i = 0; i < n; i++) cur[i] = as]; for (int len = 1; len < n; len <<= 1) { vcd ncur(n); for (int i = 0; i < n; i += len * 2) fft_merge(cur, ncur, i, len); cur.swap(ncur); } return cur; }

Оптимизация

На многочлене степени 2 1 6 рекурсия работает 640 мс, без рекурсии - 500. Улучшение есть, но программу можно сделать еще быстрее. Воспользуемся тем свойством, что ω i =-ω i +n /2 . Значит, можно не считать два раза корень и a i ⋅ω j - синус, косинус и умножение комплексных чисел очень затратные операции.
fft_merge()
for (int i = 0; i < len; i++) { double alpha = 2 * M_PI * i / nlen; cd w = cd(cos(alpha), sin(alpha)); // Текущий корень cd val = w * src; dest = src + val; dest = src - val; pdest++; if (++p1 >= en1) p1 = start; if (++p2 >= en2) p2 = start + len; }
Перехо с такой оптимизацией называется «преобразованием бабочки». Программа стала работать 260 мс. Для закрепления успеха давайте предподсчитаем все корни из 1 и запишем их в массив:
fft_merge()
int rstep = roots.size() / nlen; // Шаг в массиве с корнями for (int i = 0; i < len; i++) { cd w = roots; cd val = w * src;
fft()
roots = vcd(n); for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; roots[i] = cd(cos(alpha), sin(alpha)); }
Теперь скорость работы - 78 мс. Оптимизация в 8 раз по сравнению с первой реализацией!

Оптимизация по коду

На данный момент весь код преобразования занимает порядка 55 строк. Не сотню, но это достаточно много - можно короче. Дляначала избавимся от кучи лишних переменных и операций в fft_merge :
void fft_merge(const vcd &src, vcd &dest, int start, int len) { int p1 = start; //int en1 = start + len; // Не используется, см. конец цикла int p2 = start + len; //int en2 = start + len * 2; // Аналогично int pdest = start; //int nlen = len * 2; // Используется только в следующей строчке //int rstep = roots.size() / nlen; int rstep = roots.size() / (len * 2); for (int i = 0; i < len; i++) { //cd w = roots; // Также используется только в следующей строчке //cd val = w * src; cd val = roots * src; dest = src + val; dest = src - val; pdest++, p1++, p2++; //if (++p1 >= en1) p1 = start; // Так как у нас теперь цикл не до 2len, а только до len, переполнения быть не может //if (++p2 >= en2) p2 = start + len; // Убираем } }
Теперь можно переместить цикл из fft_merge в основную процедуру (также можно убрать p2 , поскольку p2=p1+len - у меня это также дало небольшой выигрыш по времени. Что любопытно, если убрать p1=pdest , то у меня лично выигрыш по времени убивается):
fft()
for (int len = 1; len < n; len <<= 1) { vcd ncur(n); int rstep = roots.size() / (len * 2); for (int pdest = 0; pdest < n;) { int p1 = pdest; for (int i = 0; i < len; i++) { cd val = roots * cur; ncur = cur + val; ncur = cur - val; pdest++, p1++; } pdest += len; } cur.swap(ncur); }
Как видите, само преобразование занимает не так много - 17 строк. Всё остальное - предподсчёт корней и разворот чисел. Если Вы готовы сэкономить код в обмен на время работы (O (n ⋅log 2 n ) вместо O (n )), можете заменить 13 строк разворота чисел на следующие шесть:
В начале процедуры fft()
vcd cur(n); for (int i = 0; i < n; i++) { int ri = 0; for (int i2 = 0; i2 < k; i2++) // Перебираем биты от младших к старшим ri = (ri << 1) | !!(i & (1 << i2)); // И приписываем в конец числа cur[i] = as; }
В результате теперь код выглядит так:
vcd fft(const vcd &as) { int n = as.size(); int k = 0; // Длина n в битах while ((1 << k) < n) k++; vector rev(n); rev = 0; int high1 = -1; for (int i = 1; i < n; i++) { if ((i & (i - 1)) == 0) // Проверка на степень двойки. Если i ей является, то i-1 будет состоять из кучи единиц. high1++; rev[i] = rev; // Переворачиваем остаток rev[i] |= (1 << (k - high1 - 1)); // Добавляем старший бит } vcd roots(n); for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; roots[i] = cd(cos(alpha), sin(alpha)); } vcd cur(n); for (int i = 0; i < n; i++) cur[i] = as]; for (int len = 1; len < n; len <<= 1) { vcd ncur(n); int rstep = roots.size() / (len * 2); for (int pdest = 0; pdest < n;) { int p1 = pdest; for (int i = 0; i < len; i++) { cd val = roots * cur; ncur = cur + val; ncur = cur - val; pdest++, p1++; } pdest += len; } cur.swap(ncur); } return cur; }

Обратное преобразование

Получить значения многочлена в точках - это, конечно, хорошо, но преобразование Фурье умеет больше - по этим значениям построить сам многочлен, причём за то же самое время! Оказывается, что если применить преобразование Фурье к массиву значений, как к коэффициентам многочлена, потом разделить результат на n и перевернуть отрезок с 1 до n -1 (нумерация с 0 ), то мы получим коэффициенты исходного многочлена.
Код тут предельно простой - всё уже написано. Думаю, Вы справитесь.

Доказательство

Пусть мы применяем обратное преобразование к многочлену P (x ) с коэффициентами v i (исходный многочлен имел коэффициенты a i ):
v i =a 0 i a 1 2 i a 2 3 i a +...
Посмотрим на результат преобразования:
b i =v 0 i v 1 2 i v 2 3 i v 3 +...
Подставим значения v j (помним, что ω a ω b a +b m o d n :

Теперь давайте докажем один замечательный факт: при x 0 , ω 0 x 2 x +... +ω (n -1 )x =0 .
Доказывается аналогично тому, что сумма корней - ноль: обозначим за φ сумму, домножим обе части на ω x и посмотрим, что получилось.
Теперь применим этот факт к вычислению значения b i . Заметим, что все строки, кроме одной, в которой содержится a n -i , обнулятся.

Таким образом:

b i =a n -i ⋅(ω 0 0 0 0 +... )

b i =a n -i n

Что и требовалось доказать.

Применение

Вообще говоря, о применении я уже чуть-чуть говорил в начале статьи. В частности, теперь перемножение многочленов можно выполнять следующим образом:
Быстрое перемножение многочленов
vcd a, b; // Многочлены // Чтение многочленов vcd a_vals = fft(a); vcd b_vals = fft(b); vcd c_vals(a_vals.size()); for (int i = 0; i < a_vals.size(); i++) c_vals[i] = a_vals[i] * b_vals[i]; vcd c = fft_rev(c_vals); // Вывод ответа
Легко заметить, что время работы этой программы - O (n ⋅log 2 n ) и самые трудоёмкие операции - преобразования Фурье. Также можно заметить, что если нам требуется вычислить более сложное выражение с двумя многочленами, то по-прежнему можно выполнять лишь три приобразования - сложение и вычитание также будут работать за линейное время. К сожалению, с делением не всё так просто, поскольку многочлен может случайно принять значение 0 в какой-нибудь из точек. UPD2: не забудьте, что степень произведения двух многочленов степени n будет равна 2n , поэтому при вводе следует добавить «лишние» нулевые старшие коэффициенты.
Если представить число в десятичной (или более) системе счисления, как многочлен с коэффициентами - цифрами, то умножение длинных чисел также можно выполнять очень быстро.
И, напоследок, задача, которую я разберу в следующем посте: у вас есть две строки одинаковой длины порядка 1 0 5 из букв A, T, G, C. Требуется найти такой циклический сдвиг одной из строк, чтобы совпало максимальное количество символов. Очевидно наивное решение за O (n 2 ), но есть решение при помощи БПФ.
Удачи!

UPD: Выложил код целиком на


Продолжаем изучать действия с многочленами . В этой статье мы разберем умножение многочлена на многочлен . Здесь мы получим правило умножения, после чего рассмотрим его применение при решении примеров на умножение многочленов различного вида.

Навигация по странице.

Правило

Чтобы подойти к правилу умножения многочлена на многочлен, рассмотрим пример. Возьмем два многочлена a+b и c+d и выполним их умножение.

Сначала составим их произведение, для этого заключим каждый из многочленов в скобки, и поставим между ними знак умножения, имеем (a+b)·(c+d) . Теперь обозначим (c+d) как x , после этой замены записанное произведение примет вид (a+b)·x . Выполним умножение так, как проводится умножение многочлена на одночлен : (a+b)·x=a·x+b·x . На этом этапе проведем обратную замену x на c+d , что нас приведет к выражению a·(c+d)+b·(c+d) , которое с помощью правила умножения одночлена на многочлен преобразуется к виду a·c+a·d+b·c+b·d . Таким образом, умножению исходных многочленов a+b и c+d соответствует равенство (a+b)·(c+d)=a·c+a·d+b·c+b·d .

Из проведенных рассуждений можно сделать два важных вывода. Во-первых, результатом умножения многочлена на многочлен является многочлен. Это утверждение справедливо для любых умножаемых многочленов, а не только для тех, которые мы взяли в примере. Во-вторых, произведение многочленов равно сумме произведений каждого члена одного многочлена на каждый член другого. Отсюда следует, что при умножении многочленов, содержащих m и n членов соответственно, указанная сумма произведений членов будет состоять из m·n слагаемых.

Теперь сделанные выводы нам позволяют сформулировать правило умножения многочленов:
чтобы провести умножение многочлена на многочлен, нужно каждый член одного многочлена умножить на каждый член другого многочлена и сложить полученные произведения.

Примеры умножения многочлена на многочлен

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

  • Так сначала записывается произведение умножаемых многочленов. При этом умножаемые многочлены заключаются в скобки и между ними ставится знак «· ».
  • Дальше строится сумма произведений каждого члена первого многочлена на каждый член второго. Для этого берется первый член первого многочлена и умножается на каждый член второго многочлена. После этого берется второй член первого многочлена и тоже умножается на каждый член второго многочлена. И так далее.
  • Наконец, при возможности остается полученную сумму преобразовать в многочлен стандартного вида .

Разберемся с этим на конкретном примере.

Пример.

Выполните умножение многочленов 2−3·x и x 2 −7·x+1 .

Решение.

Записываем произведение: (2−3·x)·(x 2 −7·x+1) .

Теперь составляем сумму произведений каждого члена многочлена 2−3·x на каждый член многочлена x 2 −7·x+1 . Для этого берем первый член первого многочлена, то есть, 2 , и умножаем его на каждый член второго многочлена, имеем 2·x 2 , 2·(−7·x) и 2·1 . Теперь берем второй член первого многочлена −3·x и умножаем его на каждый член второго многочлена, имеем −3·x·x 2 , −3·x·(−7·x) и −3·x·1 . Из всех полученных выражений составляем сумму: 2·x 2 +2·(−7·x)+2·1− 3·x·x 2 −3·x·(−7·x)−3·x·1 .

Чтобы убедиться, что мы все сделали правильно и не забыли про произведение каких-нибудь членов, посчитаем количество членов в полученной сумме. Там их 6 . Так и должно быть, так как исходные многочлены состоят из 2 и 3 членов, а 2·3=6 .

Осталось полученную сумму преобразовать в многочлен стандартного вида:
2·x 2 +2·(−7·x)+2·1− 3·x·x 2 −3·x·(−7·x)−3·x·1= 23·x 2 −17·x+2−3·x 3 .

Таким образом, умножение исходных многочленов дает многочлен 23·x 2 −17·x+2−3·x 3 .

Удобно решение записывать в виде цепочки равенств, которая отражает все выполняемые действия. Для нашего примера краткое решение выглядит так:
(2−3·x)·(x 2 −7·x+1)= 2·x 2 +2·(−7·x)+2·1− 3·x·x 2 −3·x·(−7·x)−3·x·1= 2·x 2 −14·x+2−3·x 3 +21·x 2 −3·x= (2·x 2 +21·x 2)+(−14·x−3·x)+2−3·x 3 = 23·x 2 −17·x+2−3·x 3 .

Ответ:

(2−3·x)·(x 2 −7·x+1)=23·x 2 −17·x+2−3·x 3 .

Стоит заметить, что если умножаемые многочлены заданы в виде, отличном от стандартного, то перед умножением их целесообразно привести к стандартному виду. В результате получится тот же результат, что и при умножении многочленов в исходном не стандартном виде, но решение получится намного короче.

Пример.

Выполните умножение многочленов и x·y−1 .

Решение.

Многочлен дан не в стандартном виде. Прежде чем выполнять умножение, приведем многочлен его к стандартному виду:

Теперь можно выполнять умножение многочленов:

Ответ:

В заключение скажем, что иногда приходится выполнять умножение трех, четырех и большего количества многочленов. Оно сводится к последовательному умножению двух многочленов. То есть, сначала умножаются первые два многочлена, полученный результат умножается на третий многочлен, этот результат умножается на четвертый многочлен и так далее.

Пример.

Найдите произведение трех многочленов x 2 +x·y−1 , x+y и 2·y−3 .

Список литературы.

  • Алгебра: учеб. для 7 кл. общеобразоват. учреждений / [Ю. Н. Макарычев, Н. Г. Миндюк, К. И. Нешков, С. Б. Суворова]; под ред. С. А. Теляковского. - 17-е изд. - М. : Просвещение, 2008. - 240 с. : ил. - ISBN 978-5-09-019315-3.
  • Мордкович А. Г. Алгебра. 7 класс. В 2 ч. Ч. 1. Учебник для учащихся общеобразовательных учреждений / А. Г. Мордкович. - 17-е изд., доп. - М.: Мнемозина, 2013. - 175 с.: ил. ISBN 978-5-346-02432-3.
  • Алгебра и начала математического анализа. 10 класс: учеб. для общеобразоват. учреждений: базовый и профил. уровни / [Ю. М. Колягин, М. В. Ткачева, Н. Е. Федорова, М. И. Шабунин]; под ред. А. Б. Жижченко. - 3-е изд. - М.: Просвещение, 2010.- 368 с. : ил. - ISBN 978-5-09-022771-1.
  • Гусев В. А., Мордкович А. Г. Математика (пособие для поступающих в техникумы): Учеб. пособие.- М.; Высш. шк., 1984.-351 с., ил.