Как преобразовать в многочлен выражение. Где можно решить уравнение многочлена онлайн? Определение и примеры целых выражений

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

Инструкция

Раскройте все скобки выражения. Для этого воспользуйтесь формулами, например, (а+b)^2=a^2+2ab+b^2. Если вы не знаете формул, или их трудно применить к данному выражению, раскрывайте скобки последовательно. Для этого умножайте первый член первого выражения на каждый член второго выражения, затем второй член первого выражения на каждый член второго и т.д. В результате все элементы обоих скобок будут перемножены между собой.

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

Внимательно следите за соблюдением знаков перед множителями-одночленами. Если вы перемножаете два члена с одним знаком (например, оба положительны или оба отрицательны), одночлен будет со знаком «+». Если же один член имеет перед собой «-», не забудьте перенести его на произведение.

Приведите все одночлены к стандартному виду. То есть переставьте местами множители внутри и упростите. Например, выражение 2х*(3,5х) будет равно (2*3,5)*х*х=7х^2.

Когда все одночлены будут стандартизированы, попробуйте упростить многочлен. Для этого сгруппируйте члены, у которых одинакова часть с переменными, например, (2х+5х-6х)+(1-2). Упростив выражение, вы получите х-1.

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

Чтобы преобразовать в многочлен выражение, содержащее корень, выведите под ним такое выражение, которое будет возведено в квадрат. Например, воспользуйтесь формулой a^2+2ab+b^2 =(а+b)^2, затем уберите знак корня вместе с четной степенью. Если избавиться от знака корня невозможно, преобразовать выражение в многочлен стандартного вида не удастся.

19. Возьмем формулу

мы ее читали так: «разность числе a и b». Мы можем в этой формуле число a заменить нулем; тогда она обратится в

0 – b или просто в –b.

Из нуля вычесть b значит, согласно тому, что мы знаем о вычитании относительных чисел, к нулю приписать число b, взятое с обратным знаком. Поэтому выражение –b должно понимать, как число, обратное по знаку числу b. Если, напр., b = +5, то –b = –5; если b = –4, то –b = +4 и т. п. Если мы напишем выражение +a, то его надо понимать, как число, равное числу a. Если a = +5, то +a = +5; если a = –4, то +a = 4 и т. п.

Поэтому формулу

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

или в смысле

Таким образом мы всегда можем заменять вычитание сложением и всякую разность понимать, как сумму двух чисел:
a – b есть сумма чисел a и (–b)
x – y есть сумма чисел x и (–y)
–a – b есть сумма чисел (–a) и (–b) и т. п.

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

a – b + c + d – e – f,

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

a – b + c + d – e – f = (+a) + (–b) + (+c) + (+d) + (–e) + (–f).

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

20. Возьмем какую-нибудь алгебраическую сумму

a – b – c или –3bc² + 2ab – 4a²b и т. п.

Принято называть эти выражения именем многочлен , причем это слово заменяет собою слово «сумма» или название «алгебраическая сумма». Мы знаем что

a – b – c = (+a) + (–b) + (–c)
–abc – 3bc² + 2ab – 4a²b = (–abc) + (–3bc²) + (+2ab) + (–4a²b) и т. п.

Отдельно каждое слагаемое называют именем член многочлена.

Первый многочлен,

состоит из трех членов: (+a), (–b) и (+c).

Второй многочлен,

–abc – 3bc² + 2ab – 4a²b,

состоит из четырех членов: (–abc), (–3bc²), (+2ab) и (–4a²b).

Слагаемые суммы можно переставлять в любом порядке:

–abc – 3bc² + 2ab – 4a²b = (–abc) + (–3bc²) + (+2ab) + (–4a²b) =
= (+2ab) + (–3bc²) + (–4a²b) + (–abc) = 2ab – 3bc² – 4a²b – abc.

Это свойство суммы теперь можно выразить иначе: члены многочлена можно переставлять в любом порядке. Это и сделано выше для многочлена –abc – 3bc² + 2ab – 4a²b, притом так, что впереди теперь оказался член (+2ab). Это позволило несколько упростить выражение: впереди знак + можно не писать. Конечно, надо подобные перестановки делать сразу, не заключая предварительно (как выше) каждое слагаемое в скобки.

Еще пример:

1 – 3a + 2a² – a³ + 3a 4 = 3a 4 – a³ + 2a² – 3a + 1.

Первый член этого многочлена был первоначально (+1) – знак + подразумевался перед единицею; когда мы переносим этот член на другое, кроме первого, место (выше мы перенесли его на последнее место), то уже этот знак + пропускать нельзя.

Мы можем заметить, что в предыдущем примере мы перестановкою членов многочлена достигли некоторого порядка: на первом месте стоит член с буквою a в 4-ой степени, на следующем – член с буквою a в 3-ей степени, потом идет член с буквою a во 2-ой степени, потом – a в 1-ой степени и, наконец, член, где буквы a вовсе нет.

Подобное расположение членов многочлена выражают словами «многочлен расположен по нисходящим степеням буквы a».

Вот еще примеры подобного расположения:

3x 5 – 2ax 3 + b (по нисходящим степеням буквы x)
a 4 – a 3 b + a 2 b 2 – ab 3 + b 4 (по нисходящим степеням буквы a)
3ab 5 – 4a 3 b 3 + 5a 4 b 2 – 2a 6 (по нисходящим степеням буквы b)
4x 4 – 3x 3 + 2x 3 (по нисходящим степеням буквы x).

Употребляют часто и обратное «по восходящим степеням» расположение, при котором степень избранной буквы постепенно повышается, причем в 1-м члене или вовсе этой буквы нет, или она имеет здесь наименьшую степень сравнительно с другими членами. О втором из предыдущих примеров мы могли бы сказать, что здесь многочлен расположен по восходящим степеням буквы b. Вот примеры:
3 – 2a + 3a 2 – 4a 3 (по восходящим степеням буквы a );
–x + x 2 – 3x 3 – 4x 4 (по восходящим степеням буквы х );
ax 2 – bx 3 + cx 5 – dx 6 (по восходящим степеням буквы x );
a 3 – 2ab + b 2 (по восходящим степеням буквы b или по нисходящим степеням буквы a);
3x 5 – 4yx 4 – 5y 3 x 2 – 6y 4 x (по нисходящим степеням буквы x или по восходящим степеням буквы y ).

21. Многочлен о двух членах называется двучленом (напр., 3a + 2b), о трех членах – трехчленом (напр., 2a² – 3ab + 4b²) и т. д. Возможно говорить о сумму из одного слагаемого (другое слагаемое равно нулю), или о многочлене об одном члене. Тогда уже, конечно, название «многочлен» неуместно и употребляется название «одночлен». Каждый член любого многочлена, взятый в отдельности, является одночленом. Вот примеры простейших одночленов:

2; –3a; a²; 4x³; –5x4; ab; ab²; –3abc; и т. д.

Почти все одночлены из выше написанных являются произведениями двух или более множителей, причем у большинства из них имеются и числовой множитель и буквенные. Напр., в одночлене –3abc имеется числовой множитель –3 и буквенные множители a, b и c; в одночлене 4x³ имеется числовой множитель +4 (знак + подразумевается) и буквенный множитель x³ и т. д. Если бы мы написали одночлен с несколькими числовыми множителями (а также и с буквенными), вроде следующего

,

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

,

эти числовые множители перемножить – получим

–4a²bc² (точки, знаки умножения пропускаем).

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

4a, а не a 4
–3a²b, а не a²(–3)b

Числовой множитель одночлена называется коэффициентом.

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

a = (+1) ∙ a; ab = (+1)ab;
–a = (–1) ∙ a; a³ = (–1) ∙ a³ и т. п.

Итак, у одночленов a², ab, ab² подразумевается, у каждого, коэффициент 1 (точнее: +1). Если напишем одночлены –ab, –a², –ab² и т. п., то у них должно подразумевать коэффициент –1.

22. Более сложные примеры многочленов и одночленов.

(a + b)² + 3(a – b)² … эта формула выражает сумму двух слагаемых: первым является квадрат суммы чисел a и b, а вторым – произведение числа 3 на квадрат разности тех же чисел. Поэтому эту формулу должно признать двучленом: первый член есть (a + b)² и второй 3(a – b)². Если взять выражение (a + b)² отдельно, то в силу предыдущего, его надо считать одночленом, причем его коэффициент = +1.

a(b – 1) – b(a – 1) – (a – 1)(b – 1) … должно признать за трехчлен (сумма трех слагаемых): первый член есть a(b – 1) и его коэффициент = +1, второй член –b(a – 1), его коэффициент = –1, третий член –(a – 1)(b – 1), его коэффициент = – 1.

Иногда искусственно уменьшают число членов многочлена. Так трехчлен

можно, например, рассматривать за двухчлен, причем a + b, например, считают за один член (за одно слагаемое). Чтобы это яснее отметить, пользуются скобками:

Тогда у члена (a + b) подразумевается коэффициент +1

[в самом деле (a + b) = (+1)(a + b)].

Среди различных выражений, которые рассматриваются в алгебре, важное место занимают суммы одночленов. Приведем примеры таких выражений:
\(5a^4 - 2a^3 + 0,3a^2 - 4,6a + 8 \)
\(xy^3 - 5x^2y + 9x^3 - 7y^2 + 6x + 5y - 2 \)

Сумму одночленов называют многочленом. Слагаемые в многочлене называют членами многочлена. Одночлены также относят к многочленам, считая одночлен многочленом, состоящим из одного члена.

Например, многочлен
\(8b^5 - 2b \cdot 7b^4 + 3b^2 - 8b + 0,25b \cdot (-12)b + 16 \)
можно упростить.

Представим все слагаемые в виде одночленов стандартного вида:
\(8b^5 - 2b \cdot 7b^4 + 3b^2 - 8b + 0,25b \cdot (-12)b + 16 = \)
\(= 8b^5 - 14b^5 + 3b^2 -8b -3b^2 + 16 \)

Приведем в полученном многочлене подобные члены:
\(8b^5 -14b^5 +3b^2 -8b -3b^2 + 16 = -6b^5 -8b + 16 \)
Получился многочлен, все члены которого являются одночленами стандартного вида, причем среди них нет подобных. Такие многочлены называют многочленами стандартного вида .

За степень многочлена стандартного вида принимают наибольшую из степеней его членов. Так, двучлен \(12a^2b - 7b \) имеет третью степень, а трехчлен \(2b^2 -7b + 6 \) - вторую.

Обычно члены многочленов стандартного вида, содержащих одну переменную, располагают в порядке убывания показателей ее степени. Например:
\(5x - 18x^3 + 1 + x^5 = x^5 - 18x^3 + 5x + 1 \)

Сумму нескольких многочленов можно преобразовать (упростить) в многочлен стандартного вида.

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

Если перед скобками ставится знак «+», то члены, заключаемые в скобки, записываются с теми же знаками.

Если перед скобками ставится знак «-», то члены, заключаемые в скобки, записываются с противоположными знаками.

Преобразование (упрощение) произведения одночлена и многочлена

С помощью распределительного свойства умножения можно преобразовать (упростить) в многочлен произведение одночлена и многочлена. Например:
\(9a^2b(7a^2 - 5ab - 4b^2) = \)
\(= 9a^2b \cdot 7a^2 + 9a^2b \cdot (-5ab) + 9a^2b \cdot (-4b^2) = \)
\(= 63a^4b - 45a^3b^2 - 36a^2b^3 \)

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

Этот результат обычно формулируют в виде правила.

Чтобы умножить одночлен на многочлен, надо умножить этот одночлен на каждый из членов многочлена.

Мы уже неоднократно использовали это правило для умножения на сумму.

Произведение многочленов. Преобразование (упрощение) произведения двух многочленов

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

Обычно пользуются следующим правилом.

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

Формулы сокращенного умножения. Квадраты суммы, разности и разность квадратов

С некоторыми выражениями в алгебраических преобразованиях приходится иметь дело чаще, чем с другими. Пожалуй, наиболее часто встречаются выражения \((a + b)^2, \; (a - b)^2 \) и \(a^2 - b^2 \), т. е. квадрат суммы, квадрат разности и разность квадратов. Вы заметили, что названия указанных выражений как бы не закончены, так, например, \((a + b)^2 \) - это, конечно, не просто квадрат суммы, а квадрат суммы а и b. Однако квадрат суммы а и b встречается не так уж часто, как правило, вместо букв а и b в нем оказываются различные, иногда довольно сложные выражения.

Выражения \((a + b)^2, \; (a - b)^2 \) нетрудно преобразовать (упростить) в многочлены стандартного вида, собственно, вы уже встречались с таким заданием при умножении многочленов:
\((a + b)^2 = (a + b)(a + b) = a^2 + ab + ba + b^2 = \)
\(= a^2 + 2ab + b^2 \)

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

\((a + b)^2 = a^2 + b^2 + 2ab \) - квадрат суммы равен сумме квадратов и удвоенного произведения.

\((a - b)^2 = a^2 + b^2 - 2ab \) - квадрат разности равен сумме квадратов без удвоенного произведения.

\(a^2 - b^2 = (a - b)(a + b) \) - разность квадратов равна произведению разности на сумму.

Эти три тождества позволяют в преобразованиях заменять свои левые части правыми и обратно - правые части левыми. Самое трудное при этом - увидеть соответствующие выражения и понять, чем в них заменены переменные а и b. Рассмотрим несколько примеров использования формул сокращенного умножения.

Добрый вечер.
Этот пост посвящён быстрому преобразованию Фурье. Будут рассмотрены прямое и обратное преобразования (в комплексных числах). В следующей части я планирую рассмотреть их применения в некоторых задачах олимпиадного программирования (в частности, одна задача про «похожесть» строк), а также рассказать про реализацию преобразования в целых числах.
БПФ - это алгоритм, вычисляющий значения многочлена степени 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: Выложил код целиком на

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

Инструкция

1. Раскройте все скобки выражения. Для этого воспользуйтесь формулами, скажем, (а+b)^2=a^2+2ab+b^2. Если вы не знаете формул, либо их сложно применить к данному выражению, раскрывайте скобки ступенчато. Для этого умножайте 1-й член первого выражения на весь член второго выражения, после этого 2-й член первого выражения на весь член второго и т.д. В итоге все элементы обоих скобок будут перемножены между собой.

2. Если перед вами три выражения в скобках, вначале перемножьте первые две, оставляя третье выражение не тронутым. Упростив итог, получившийся в итоге реформирования первых скобок, перемножьте его с третьим выражением.

3. Наблюдательно следите за соблюдением знаков перед множителями-одночленами. Если вы перемножаете два члена с одним знаком (скажем, оба правильны либо оба негативны), одночлен будет со знаком «+». Если же один член имеет перед собой «-», не позабудьте перенести его на произведение.

4. Приведите все одночлены к стандартному виду. То есть переставьте местами множители внутри и упростите. Скажем, выражение 2х*(3,5х) будет равно (2*3,5)*х*х=7х^2.

5. Когда все одночлены будут стандартизированы, испробуйте упростить многочлен. Для этого сгруппируйте члены, у которых идентична часть с переменными, скажем, (2х+5х-6х)+(1-2). Упростив выражение, вы получите х-1.

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

7. Дабы преобразовать в многочлен выражение, содержащее корень, выведите под ним такое выражение, которое будет возведено в квадрат. Скажем, воспользуйтесь формулой a^2+2ab+b^2 =(а+b)^2, после этого уберите знак корня совместно с четной степенью. Если избавиться от знака корня нереально, преобразовать выражение в многочлен стандартного вида не удастся.

Краткость, как говорится, – сестра дара. Всякому хочется блеснуть даром, но вот его сестра – штука трудная. Феноменальные мысли отчего-то сами собой облекаются в сложноподчинённые предложения со большинством деепричастных циклов. Впрочем в ваших силах упростить свои предложения и сделать их внятными и доступными каждым.

Инструкция

1. Дабы облегчить адресату (будь то слушатель либо читатель) жизнь, постарайтесь заменять причастные и деепричастные циклы короткими придаточными предложениями, исключительно если вышеуказанных циклов слишком много в одном предложении. “Пришедший домой кот, только что съевший мышь, громко мурлыча, ласкался к владельцу, пытаясь заглянуть ему в глаза, веря выпросить рыбу, принесённую из магазина” – такое не пойдёт. Разбейте сходственную конструкцию на несколько частей, не спешите и не пытайтесь сказать всё одним предложением, и будет вам блаженство.

2. Если вы замыслили талантливое высказывание, но в нём оказалось слишком много придаточных предложений (тем больше с одним союзом), то отменнее разбить высказывание на несколько отдельных предложений либо опустить какой-то элемент. “Мы решили, что он расскажет Марине Васильевне, что Катя скажет Вите, что…” – дозволено продолжать беспредельно. Своевременно остановитесь и припомните о том человеке, кто будет это читать либо выслушивать.

3. Впрочем подводные камни кроются не только в структуре предложения. Обратите внимание на лексику. Иноязычные слова, длинные термины, слова, почерпнутые из художественной литературы 19 столетия – всё это только осложнит воспринятие. Нужно уточнить для себя, для какой аудитории вы составляете текст: технари, финально, осознают и трудные термины, и специфические слова; но если вы те же слова предложите учительнице литературы, вряд ли она вас поймёт.

4. Дар – великая вещь. Если вы гениальны (а людей без способностей не бывает), перед вами открывается уйма дорог. Но дар состоит не в трудности, а простоте, как ни необычно. Будьте проще, и ваши дары будут внятны и доступны каждом.

Видео по теме

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

Вам понадобится

  • лист бумаги
  • цветные ручки

Инструкция

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

2. Запишите начальный многочлен и приступайте к поиску сходственных слагаемых. Это члены данного вам уравнения, имеющие идентичную буквенную часть либо (и) цифровую. Для большей наглядности подчеркивайте обнаруженные пары. Обратите внимание, что подобие не обозначает идентичность, – основное, дабы один член пары содержал в себе 2-й. Так, сходственными будут члены ху, хy2z и хуz, – они имеют всеобщую часть в виде произведения х и у. Это же относится и к степенным выражениям.

3. Обозначайте различные сходственные члены по-различному. Для этого класснее подчеркивайте одинарными, двойными и тройными линиями, используйте цвет и другие формы линий.

4. Обнаружив все сходственные члены, приступайте к их комбинированию. Для этого в обнаруженных парах вынесите сходственные члены за скобки. Не забывайте, что в стандартной форме у многочлена нет сходственных членов.

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

6. Проследите за выполнением второго данные, требующегося для записи многочлена в стандартной форме: весь его участник должен быть изображен в виде одночлена в стандартном виде: на первом месте – числовой множитель, на втором – переменная либо переменны, следующие в теснее обозначенном порядке. При этом приоритет имеет буквенная последовательность, задаваемая алфавитом. Убывание степеней учитывается во вторую очередь. Так, стандартным видом одночлена является запись 7xy2, в то время как y27x, x7y2, y2x7, 7y2x, xy27 не отвечают требованиям.

Видео по теме

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

Инструкция

1. Многочлен либо полином (от греч. «поли» – много и лат. «номен» – имя) – класс элементарных функций классической алгебры и алгебраической геометрии. Это функция одной переменной, которая имеет вид F(x) = c_0 + c_1*x + … + c_n*x^n, где c_i – фиксированные показатели, x – переменная.

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

3. Основные определения многочлена: Каждое слагаемое полинома именуется одночленом либо мономом. Многочлен, состоящий из 2-х одночленов, называют двучленом либо биномом. Коэффициенты полинома – вещественные либо комплексные числа. Если старший показатель равен 1, то многочлен называют унитарным (приведенным). Степени переменной в всяком одночлене – целые неотрицательные числа, максимальная степень определяет степень многочлена, а его полной степенью именуется целое число, равное сумме всех степеней. Одночлен, соответствующий нулевой степени, именуется свободным членом. Многочлен, все одночлены которого имеют идентичную полную степень, именуется однородным.

4. Некоторые зачастую используемые многочлены названы по фамилии ученого, тот, что их определил, а также описал функции, которые они задают. Скажем, Бином Ньютона – это формула для разложения полинома 2-х переменных на отдельные слагаемые для вычисления степеней. Это знаменитые из школьной программы записи квадратов суммы и разности (a + b)^2 – a^2 + 2*a*b + b^2, (a – b)^2 = a^2 – 2*a*b + b^2 и разность квадратов (a^2 – b^2) = (a – b)*(a + b).

5. Если допустить в записи многочлена негативные степени, то получится многочлен либо ряд Лорана; многочлен Чебышева применяется в теории приближений; многочлен Эрмита – в теории вероятностей; Лагранжа – для численного интегрирования и интерполяции; Тейлора – при аппроксимации функции и т.д.

Обратите внимание!
Бином Ньютона зачастую упоминают в книгах («Мастер и Маргарита») и фильмах («Сталкер»), когда герои решают математические задачи. Данный термин на слуху, следственно считается самым вестимым многочленом.

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

Вам понадобится

  • – действия с дробями;
  • – формулы сокращенного умножения;
  • – калькулятор.

Инструкция

1. Простейшим реформированием является приведение сходственных. Если есть несколько слагаемых, которые представляют собой одночлены с идентичными сомножителями, показатель при них дозволено сложить, с учетом знаков, которые стоят перед этими показателями. Скажем, выражение 2 n-4n+6n-n=3 n.

2. Если же идентичные сомножители имеют различные степени, сходственным образом свести сходственные не допустимо. Группируйте только те показатели, которые имеют при себе сомножители с идентичными степенями. Скажем, упростите выражение 4 k?-6 k+5 k?-5 k?+k-2 k?=3 k?-k?-5 k.

3. Если есть такая вероятность, используйте формулы сокращенного умножения. К особенно знаменитым относятся куб и квадрат суммы либо разности 2-х чисел. Они представляют собой частный случай бинома Ньютона. К формулам сокращенного умножения также относят разность квадратов 2-х чисел. Скажем, дабы обнаружить значения выражения 625-1150+529=(25-23)?=4. Либо 1296-576=(36+24) (36-24)=720.

4. Когда необходимо преобразовать выражение , которое представляет собой естественную дробь, выделите из числителя и знаменателя всеобщий множитель и сократите на него числитель и знаменатель. Скажем, сократите дробь 3 (a+b)/(12 (a?-b?)). Для этого преобразуйте ее в вид 3 (a+b)/(3 4 (a-b) (a+b)). Сократите это выражение на 3 (a+b), получите 1/(4 (a-b)).

5. Преобразовывая тригонометрические выражения, используйте вестимые тригонометрические тождества. К ним относится основное тождество sin?(x)+cos?(x)=1, а также формулы тангенса и его соотношения с котангенсом sin(x)/cos(x)=tg(x), 1/ tg(x)= ctg(x). Формулы суммы разности доводов, а также кратного довода. Скажем, преобразуйте выражение (cos?(x)-sin?(x)) cos?(x) tg(x)= cos(2x) cos?(x) sin(x)/cos(x)= cos(2x) cos(x) sin(x)= cos(2x) cos(x) sin(x) 2/2= cos(2x) sin(2x)/2=cos(2x) sin(2x) 2/4= sin(4x)/4. Такое выражение рассчитать гораздо легче.

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

Вам понадобится

  • Знание правил математических тождественных реформирований, таблица математических тождеств.

Инструкция

1. Исследуйте выражение на присутствие дробей. Числитель и знаменатель дроби дозволено умножить либо поделить на одно и то же выражение, избавившись от знаменателя. В случае реформирования уравнения, проверьте, нет ли в знаменателях переменных. Если есть – добавьте условие, что выражение знаменателя не равно нулю. Из этого данные выделите недопустимые значения переменных, то есть ограничения в области определения.

2. Примените правила действий со степенями для идентичных оснований. В итоге уменьшится число слагаемых.

3. Перенесите слагаемые, содержащие переменную, в одну часть уравнения, не содержащие – в иную. К всякой части уравнения применяйте математические тождества для облегчения.

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

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

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

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