Rozważamy wielomiany
P(
x) stopnia
n − 1, gdzie
n jest potęgą dwójki:
P(
x) =
a0 +
a1x +
a2x2 + ... +
an–1 xn -1 ,
n = 2
m
Do obliczania wartości
P(
x) można zastosować technikę „dziel i zwyciężaj” w następujący
sposób: dzielimy postać ogólną wielomianu
P(
x) na dwie części:
gdzie k = n/2. Jeśli w drugiej części wydzielimy czynnik xk, to otrzymamy równość,
(*)P(x) = A(x) + B(x) ⋅ xk
gdzie A(x) i B(x) (są wielomianami stopnia k − 1:
A(x) = ak – 1xk – 1 + ... + a2x2 + a1x + a0
B(x) = an – 1xk – 1 + ... + ak + 2x2 + ak + 1x + ak
W ten sposób problem obliczenia wartości P(x) dzielimy na dwa podproblemy — obliczenia A(x) i obliczenia B(x) przy czym każdy z nich ma rozmiar o połowę mniejszy. Na przykład
aby obliczyć wartość wielomianu (n = 8)
P(x) = –8 + 7x + 6x2 – x3 + 4x4 + 5x5 – 2x6 + 3x7,
obliczamy
k = n/2 = 4,
A(x) = –8 + 7x + 6x2 – x3
oraz
B(x) = 4 + 5x – 2x2 + 3x3.
Następnie korzystamy ze wzoru P(x) = A(x) + B(x) ⋅ x4.
Ponieważ do pełnej realizacji algorytmu we wzorze (*) potrzebne jest obliczenie wartości xk
więc najpierw obliczamy wszystkie potęgi x, x2, x4, ..., x2m – 1 i zapamiętujemy je w tablicy
Z[0 .. m – 1], np. za pomocą poniższej procedury.
Obliczanie tablicy Z[0..m – 1]:
Dane:
n — liczba całkowita postaci 2
m, gdzie
m jest liczbą całkowitą nieujemną,
x — liczba rzeczywista.
Wynik:
tablica Z[0 ..m – 1], dla której Z[
j] =
x2j Z[0] ←
x
m ← 1
w ← 2
dopóki w <
n wykonuj Z[
m] ← Z[
m – 1] ⋅ Z[
m – 1]
m ←
m + 1
w ← 2 ⋅
w
Mając tablicę Z, obliczamy wartość
P(
x) za pomocą funkcji rekurencyjnej
F.
Dane:
tablica liczb rzeczywistych T[0..
n − 1] ze współczynnikami ܽ
a0,
a1, ...,
an – 1, gdzie
n = 2
m, a
m jest liczbą całkowitą nieujemną;
tablica Z[0..m – 1], dla której Z[
j] =
x2j.
Wynik:
wartość ܽ
an – 1xn – 1 + ... +
a2x2 +
a1x +
a0.
funkcja F(
T[0..
n − 1]):
jeżeli n = 1
zwróć T[0]
i zakończ
k ←
n/2
A[0..
k – 1] ←
T[0..
k – 1]
B[0..
k – 1] ←
T[
k..
n – 1]
zwróć F(
A) + F(
B) ⋅ Z[
m – 1]
i zakończ
Prześledźmy na przykład obliczenie wartości wielomianu
P(
x) = –8 + 7
x + 6
x2 –
x3 + 4
x4 + 5
x5 – 2
x6 + 3
x7, (
n = 2
m m = 3)
dla
x = 3.
W pierwszym kroku algorytm obliczy tablicę Z[0..2]:
ܼZ[0] = 3,
Z[1] = 3
2,
Z[2] = 3
4 = 81.
Następnie algorytm obliczy F([-8,7,6,-1,4,5,-2,3]), tzn.
F([-8,7,6,-1,4,5,-2,3]) = F([-8,7,6,-1]) + F([4,5,-2,3])*Z[2]
Obliczanie F([4,5,-2,3]) i F([-8,7,6,-1]) odbywa się w analogiczny sposób, tzn.
F([-8,7,6,-1]) = F([-8,7])+ F([6,-1])*Z[1]
= F([-8])+F([7])*Z[0]+(F([6])+F([-1])*Z[0])*Z[1]
= (-8)+7*Z[0] + (6+(-1)*Z[0])*Z[1]
= (-8)+7*3+(6+(-1)*3)*9 = 40,
F([4,5,-2,3]) = F([4,5])+F([-2,3])*Z[1]
= F([4])+F([5])*Z[0]+(F([-2])+F([3])*Z[0])*Z[1]
= 4+5*Z[0]+((-2)+3*Z[0])*Z[1]
= 4+5*3+((-2)+3*3)*9=82.
Zatem
F([-8,7,6,-1,4,5,-2,3]) = F([-8,7,6,-1])+F([4,5,-2,3])*Z[2] = 40+82*81 = 6682.
Można zauważyć, że podczas obliczania F([-8,7,6,-1,4,5,-2,3]) łącznie zostanie wykonanych
7 mnożeń:
• 3 mnożenia podczas obliczania F([-8,7,6,-1])=40,
• 3 mnożenia podczas obliczania F([4,5,-2,3])=82,
• 1 mnożenie przy obliczaniu F([-8,7,6,-1])+ F([4,5,-2,3])*Z[2] = 40+82*Z[2].
Liczba wszystkich wywołań rekurencyjnych jest równa 15. Oto wszystkie wywołania funkcji F:
• F([-8,7,6,-1,4,5,-2,3])
o F([-8,7,6,-1])
▪ F([-8,7])
• F([-8])
• F([7])
▪ F([6,-1])
• F([6])
• F([-1])
o F([4,5,-2,3])
▪ F([4,5])
• F([4])
• F([5])
▪ F([-2,3])
• F([-2])
• F([3])