Horner-elrendezés

Innen: Hungaropédia
(Horner-séma szócikkből átirányítva)
Ugrás a navigációhozUgrás a kereséshez

A Horner-elrendezés a matematikában egy módszer, ami leegyszerűsíti a behelyettesítést a polinomokba. Használható a polinom értékének meghatározására vagy gyökök közelítésére. Az utóbbi felhasználást Ruffini-Horner módszerként ismerik.[1][2] Az eljárást az angol William George Hornerről nevezték el, habár Paolo Ruffini[3] és (hat évszázaddal korábban) Quin Jiushao is ismerte.[4]

Definíció

Tetszőleges polinomgyűrű fölötti n-edfokú p(x)=a0+a1x+a2x2++anxn polinom Horner-elrendezése:

p(x)=((anx+an1)x+)x+a0.[5]

Az algoritmus leírása

Adva legyen a

p(x)=i=0naixi=a0+a1x+a2x2+a3x3++anxn,

polinom, ahol az a0,,an együtthatók valósak, és értékét az x egy bizonyos helyén szeretnénk kiszámítani, ezt jelölje x0. Ehhez a következő sorozatot számítjuk ki:

bn:=anbn1:=an1+bnx0b0:=a0+b1x0.

Ekkor b0 éppen a p(x0) érték. Ennek bizonyítására írjuk fel a polinomot így:

p(x)=a0+x(a1+x(a2++x(an1+anx))).

Ebbe a kifejezésbe helyettesítsük vissza bi-t:

p(x0)=a0+x0(a1+x0(a2++x0(an1+bnx0)))=a0+x0(a1+x0(a2++x0(bn1)))=a0+x0(b1)=b0.

Alkalmazások

A leggyakoribb alkalmazása a polinomba helyettesítés, de számítható vele a polinom valahányadik deriváltja is. A Newton-módszerrel párosítva segít meghatározni az összes gyököt, amire a függvénydiszkusszióhoz vagy a grafikon felrajzolásához is szükséges. A Definícióban említett felírás a fordított lengyelforma kezelésére is alkalmas. Használható különböző helyi értékes számrendszerek közötti átváltásra, ahol is az x a számrendszer alapja, és az ai együtthatók az x alapú számrendszerbeli jegyek. Mátrixok behelyettesítésével a számítás sebessége tovább gyorsítható a mátrixszorzás sajátságainak felhasználásával. Így n helyett csak n szorzásra van szükség Paterson és Stockmeyer módszerével.[6] 1975 és 2003 között német nyelvterületen Horner-sémával számították a jövedelemadót a kerekítési hibák elkerülésére.[7][8]

Táblázatos írásmód

A táblázatokat ezzel a polinommal mutatjuk be:

11+7x5x24x3+2x4=11+x(7+x(5+x(4+x2)))

Legyenek most

α:= 2
β:= 2x4=αx4
γ:= (2x4)x5=βx5
δ:= ((2x4)x5)x+7=γx+7
ϵ:= (((2x4)x5)x+7)x+11=δx+11

A három soros táblázat első sorába írjuk az együtthatókat, a másodikba a köztes szorzatokat, a harmadikba a részösszegeket. Tehát a táblázat:

2       4       5       7       11
      +       +       +       +
      αx       βx       γx       δx
               
  x   =   x   =   x   =   x   =
               
2=α       αx4=β       βx5=γ       γx+7=δ       δx+11=ϵ

Más írásmódok is léteznek, például a kaszkádolt, de erről majd később.

Polinomok

Polinomfüggvény értékének kiszámítása

Értékeljük ki az f(x)=2x36x2+2x1 polinomot az x=3. helyen: Polinomosztás:

 x₀│   x³    x²    x¹    x⁰
 3 │   2    −6     2    −1
   │         6     0     6
   └────────────────────────
       2     0     2     5

A harmadik sor elemei az első két sor elemeinek összegei. A második sor minden eleme az x-be helyettesített érték (itt 3) és a harmadik sor balra eső elemének szorzata. Az első sorban rendre a polinom együtthatói szerepelnek. Eszerint az f(x) maradéka x3-mal osztva 5. A polinomok maradéktétele szerint ez a maradék éppen f(3), tehát f(3)=5.

Polinomosztás

Ebben a példában a3=2,a2=6,a1=2,a0=1. Megfigyelve a táblázatot láthatjuk, hogy b3=2,b2=0,b1=2,b0=5, ami éppen a harmadik sor. Így a polinomosztás is a Horner-elrendezésen alapul. A polinomok maradéktétele szerint a harmadik sorban a polinomosztás hányadosának együtthatói szerepelnek, azaz f(x) és x3 hányadosa. Emiatt a polinomosztás hányadosának meghatározására is alkalmas a Horner-elrendezés. Most osszuk az x36x2+11x6 polinomot x2-vel:

 2 │   1    −6    11    −6
   │         2    −8     6
   └────────────────────────
       1    −4     3     0

A hányados x24x+3. Legyen f1(x)=4x46x3+3x5 és f2(x)=2x1. Osszuk f1(x)-et f2(x)-vel a Horner-elrendezés szerint:

  2 │  4    −6    0    3   │   −5
────┼──────────────────────┼───────
  1 │        2   −2   −1   │    1
    └──────────────────────┼───────
       2    −2   −1    1   │   −4

A harmadik sor az első két sor összege 2-vel osztva. A második sor minden eleme 1 és a harmadik sor balra eső elemének szorzata. Az eredmény:

f1(x)f2(x)=2x32x2x+142x1.

Gyökkeresés

Polinom gyökeinek közelítése a Newton-módszer és a Horner-elrendezés kombinálásával

A Newton-módszerrel kombinálva felgyorsítja a Newton-módszert, és alkalmazhatóvá teszi arra, hogy megtalálja a polinom összes valós gyökét. Adva legyen az n-edfokú pn(x) polinom, aminek gyökei zn<zn1<<z1,, és legyen x0 a kezdeti becslés. Ismételjük a következő lépéseket: 1. A Newton-módszerrel megkeressük az x0 közelében levő gyök közelítő értékét. 2. A Horner-módszerrel kiosztjuk (xz1)-et, így kapjuk a pn1 közelítő tényezőt. Ezzel visszatérünk az 1. lépéshez, és kezdeti becslésnek z1-et vesszük. Ezeket a lépéseket ismételjük mindaddig, amíg az eredmény elég pontos nem lesz. Ha nem elég pontosak, akkor az eredmény finomításához inkább az eredeti polinomot használjuk, mint a köztes közelítő tényezőket, és a gyökök kapott közelítő értékeit.[9] Tekintsük a p6(x)=(x3)(x+3)(x+5)(x+8)(x2)(x7) polinomot, ami kifejtve p6(x)=x6+4x572x4214x3+1127x2+1602x5040. Most tudjuk, hogy ennek a legnagyobb gyöke 7; kezdeti becslésnek vegyünk 8-at. Newton-módszerrel megtaláljuk a 7-et, mint legnagyobb gyököt. Az ábrán feketével jelölve. Leosztva (x7)-tel kapjuk a következő polinomot: p5(x)=x5+11x4+5x3179x2126x+720, aminek grafikonját pirossal láthatjuk az ábrán. A Newton-módszert 7-ből indítva meg is találjuk a gyököt 3-nál, amit piros kör jelez. Leosztva (x3)-mal kapjuk, hogy: p4(x)=x4+14x3+47x238x240 aminek grafikonját sárgával mutatja az ábra. A Newton-módszer most 2 körül jelzi a gyököt, ezt sárgával mutatja az ábra. A következő polinom p3(x)=x3+16x2+79x+120 zölddel szerepel. Ennek egy gyökét -3 közelében találjuk, zöld körrel. Leosztva p2(x)=x2+13x+40 kék színnel, amiből a -5 gyök egy közelítését nyerjük, ezt kék kör jelzi. Az utolsó gyök becslését leosztva kaphatjuk, vagy egyenlet felírásával és megoldásával. Az utolsó gyök -8.

Lineáris transzformáció

Bizonyos esetekben, például a Newton-módszer használata esetén, nagyon hasznos lehet, ha egy polinomot eltolunk egy konstanssal. Jelölje a polinomot P, amit eltolunk egy a konstanssal. Ehhez elvégezzük az x=a+y helyettesítést:

P(x)=P(a+y)=Pa(y)=Pa(xa)

Egy ilyen lineáris transzformáció eredményét megkaphatjuk a zárójelek kibontásával és összevonással. Ezt megkönnyíti a Horner-elrendezés. Legyen P(x)=i=0naixi n-edfokú polinom, és legyen a helyettesítés y=xa. Ezt akarjuk y hatványai szerint kifejteni. Ehhez a P(x) polinomot osztjuk y=xa-val, ahol a hányadost E1(x), a maradékot r0 jelöli. Így

P(x)=E1(x)(xa)+r0

A következő lépésben E1(x)-et osztjuk, ezzel kapjuk az E2 hányadost és az r1 maradékot:

E1(x)=E2(x)(xa)+r1

n osztás után:

En1(x)=En(x)(xa)+rn1 mit En(x)=an=:rn

Következik, hogy:

P(x)=E1(x)(xa)+r0=(E2(x)(xa)+r1)(xa)+r0=((rn(xa)+rn1)(xa)++r1)(xa)+r0

Az y=xa helyettesítéssel a lineáris transzformáció: Pa

Pa(y)=((rny+rn1)y++r1)y+r0=i=0nriyi

Így a transzformációval kapott polinom jegyei a különböző számrendszerek közötti átváltáshoz hasonlóan adják Pa együtthatóit. Például a P(x)=x32x5 polinomba helyettesítünk x2-t, mivel a Newton-módszerrel az x=2 közelében levő gyököt keressük. Tegát keressük a P2(x)=P(2+x) polinom együtthatóit.

1 0 −2 −5
2) 2 4 4
1 2 2 −1
2) 2 8
1 4 10
2) 2
1 6

Tehát a keresett polinom P2(x)=x3+6x2+10x1.

Deriválás

A Horner-elrendezés hasznos eszköz a derivált kiszámítására. Végezzük el az

P(x)(xx0)

osztást. Ekkor az eredmény kiolvasható a Horner-elrendezésből:

Pe(x)+r(xx0),

Az előzményekből látható, hogy r=P(x0). Továbbá

P(x)(xx0)=Pe(x)+P(x0)(xx0)

P(x)P(x0)(xx0)=Pe(x) A P(x) derivált differenciálhányadossal számolható. Teljesül, hogy:

P(x0)=dP(x0)dx=limxx0P(x)P(x0)(xx0)

innen

P(x0)=Pe(x0)

Eszerint a Horner-elrendezés harmadik sorában álló számok éppen Pe(x0) együtthatói. Még egyszer alkalmazva P(x0) értéke is megkapható. Példaként tekintsük a P(x)=x54x4+4x3+3x28x+4 polinomot az x=2 helyen.

5 −16 12 6 −8
2) 10 −12 0 12
5 −6 0 6 4

Az elrendezésből leolvasható, hogy P(2)=0 és P(2)=4. Ellenőrzésként számítsuk ki a deriváltat, és helyettesítsünk be: P(x)=5x416x3+12x2+6x8

5 −16 12 6 −8
2) 10 −12 0 12
5 −6 0 6 4

A Horner-elrendezés szerint is P(2)=4.

Magasabb rendű deriváltak

A magasabb rendű deriváltak értékei is kiolvashatók a Horner-elrendezésből. Legyen :P(x)=i=0naixiaz és Pa(y)=i=0nriyi, ahol x=a+y a polinom, aminek együtthatóit a Lineáris transzformáció szakaszban leírtak szerint számítottuk. Így

P(k)(a)=P(k)(a+0)=Pa(k)(0)=k!rk

Számrendszerek közötti átváltás

Átváltás tízes számrendszerbe

Helyi értékes számrendszerekben a számokat polinomokként ábrázoljuk, ahol is a határozatlan a számrendszer alapjával egyezik. Például, ha számrendszer tízes, akkor x=10 Kettes számrendszerben x=2 Például az 110101 kettes számrendszerbeli számot szeretnénk átváltani tízes számrendszerbe. Felírjuk az 110101-et polinomként: P110101(x)=1x5+1x4+0x3+1x2+0x1+1x0 Behelyettesítve az x=2 alapot:

d=P110101(2)=125+124+023+122+021+120

Horner-elrendezésben:

d=((((12+1)2+0)2+1)2+0)2+1

A számításokat lépésekben végezzük, ahol egy lépés egy szorzásból és egy összeadásból áll. Áttekintésként a lépéseket egymás alá írjuk, és megjelöljük a részeredményeket:

d0=1(1. jegy)d1=d02+1=12+1=3(2. jegy)d2=d12+0=32+0=6(3. jegy)d3=d22+1=62+1=13(4. jegy)d4=d32+0=132+0=26(5. jegy)d5=d42+1=262+1=53(6. jegy)d=d5=53

Ezzel meg is határoztuk a tízes számrendszerbeli felírást. Általánosítva, az x alapú számrendszerből váltunk át, ahol a számításokat az y alapú számrendszerben végezzük, amibe a számot átváltjuk.

  • az első jegy a kezdőérték
  • minden lépésben az eddigi értéket szorozzuk x-szel, és hozzáadjuk a következő jegyet
  • amíg a szám végére nem érünk.

Mivel általában tízes számrendszerben számolunk, azért itt többnyire y=10. A másik irányba inkább egy másik módon végezzük az átváltást, habár ez is használható lenne. A legegyszerűbb újra a táblázatos forma:

1 1 0 1 0 1
2) 2 6 12 26 52
1 3 6 13 26 53

Kaszkádolt Horner-elrendezés

Az egyszerű felírás hátránya az, hogy lehet, hogy nagy tényezőkkel kell szorozni. Ahhoz, hogy a klis egyszeregynél maradhassunk, kaszkádolni kell. Lényege, hogy a tízeseket átvitelként a következő oszlop egyesei alá írjuk. A fenti példában a 13-ból a 3-ast a 12 alá írjuk, az 1-est a 3 alá. A következő lépésben csak a 3*2 + 0 = 6-ot számoljuk ki. Az eredményt itt is hasonlóan kezeljük, csak itt a tízes átvitel 0 lesz. Az utolsó számítás (6*2 + 1) újra 13-at eredményez, melynek utolsó jegye a végeredmény utolsó jegyével egyezik.

1 1 0 1 0 1
2)   2 6 12 6 12
1 3 6 3 6 3
0 0 1 0 1

A további jegyek számításához újra fel kell írni a Horner-sémát az utolsó sorban álló tízesekre (00101):

1 1 0 1 0 1
2)   2 6 12 6 12
1 3 6 3 6 3
0 0 1 0 1
2)         2 4
      1 2 5
0 0

Mivel itt az átvitel csupa nulla, az eljárás véget ér. A végeredményt az egyes táblázatokban kiemelt számjegyek adják.

Egyszerűsített írásmód

A kaszkádolt Horner-elrendezés több fejszámolás árán egyszerűsíthető. Ez gyorsítja a számítást. Az eredeti szám jegyeit függőlegesen írjuk egymás alá. Emellé balra függőleges vonalat húzunk. Az utolsó jegy alá pedig egy vízszintest, ez alá kerül az eredmény. Először a legnagyobb helyi értékű jegyet (1) eggyel lejjebb másoljuk a függőleges mellé balra. A bal oldalon álló számot megszorozzuk az alappal, és hozzáadjuk a jobbra álló számot (1). Az eredmény tízesét (0) eggyel balra írjuk, egyesét (3) a bal oldalon álló szám alá. Ezt az eljárást ismételjük, amíg az oszlop aljára nem érünk. A következő lépésben ezt a számot (3) szorozzuk az alappal, és hozzáadjuk a következő jegyet (0). Az eredményt (3*2 + 0 = 6) az előzőhöz hasonlóan jegyezzük fel. A harmadik számítás 6*2 + 1 = 13, a negyedik 3*2 + 0 = 6, az ötödik 6*2 + 1 = 13. Az eredmény utolsó jegye a vízszintes vonal alá jut.

        1
        1
        0
        1
        0
        1
        (2)
 
        1
      1 1
        0
        1
        0
        1
        (2)
 
        1
    0 1 1
      3 0
        1
        0
        1
        (2)
 
        1
    0 1 1
    0 3 0
      6 1
        0
        1
        (2)
 
        1
    0 1 1
    0 3 0
    1 6 1
      3 0
        1
        (2)
 
        1
    0 1 1
    0 3 0
    1 6 1
    0 3 0
      6 1
        (2)
 
        1
    0 1 1
    0 3 0
    1 6 1
    0 3 0
    1 6 1
      3 (2)

A további számításokban az itt fel nem használt tízesekből indulunk ki, amivel ugyanúgy számolunk, mint az előző egyesekkel. A vezető nullákat elhagyhatjuk. Az első értékes jegyet (1) eggyel lejjebb másoljuk az újabb függőleges vonal túlsó oldalára. Megszorozzuk az alappal, és hozzáadjuk a következő jegyet (0). A tízeseket és az egyeseket az előzőhöz hasonlóan, átlósan jegyezzük fel. Az utolsó számítás (2*2 + 1 = 05) egyese a vízszintes vonal alá jut. EZ a végeredmény következő jegye.

        1
    0 1 1
    0 3 0
    1 6 1
    0 3 0
    1 6 1
      3 (2)
 
        1
    0 1 1
    0 3 0
    1 6 1
  1 0 3 0
    1 6 1
      3 (2)
 
        1
    0 1 1
    0 3 0
    1 6 1
0 1 0 3 0
  2 1 6 1
      3 (2)
 
        1
    0 1 1
    0 3 0
    1 6 1
0 1 0 3 0
0 2 1 6 1
  5   3 (2)
 
        1
    0 1 1
    0 3 0
    1 6 1
0 1 0 3 0
0 2 1 6 1
  5   3 (2)

Mivel a tízesek oszlopában csupa nulla áll, a számítás befejeződött. A végeredmény a vízszintes vonal alatt áll, és mivel jobbról balra haladtunk, helyes sorrendben.

Átváltás tízes számrendszerből

Használhatnánk a fenti módszert, de mivel a tízes számrendszerhez vagyunk szokva, kényelmesebb fordítva visszaszámolni. A szorzást a cél számrendszer alapszámával végzett maradékos osztás helyettesíti. A végeredményt jobbról balról olvasva kapjuk a maradékokból. A táblázatban a kiindulási szám jegyeit egymás alá írjuk, és az eredménynek vízszintes vonalat húzunk. A cél számrendszer alapját emlékeztetőül feljegyezhetjük a jobb alsó sarokba.

  5  
  3  
    (2)

Az első jegyet egy vezető nullával bővítjük (05), és osztjuk az új számrendszer alapjával (2). A hányadost a balra következő oszlopba írjuk, a maradékot pedig a következő jegy elé.

 
  05  
  3  
    (2)
 
2 05  
  13  
    (2)

A maradék, mint tízes a következő jeggyel (3), mint egyes kétjegyű számot alkot. Ezt újra elosztjuk a számrendszer alapjával, a hányadost balra, a maradékot a következő jegy elé írjuk tízesként, ha van következő jegy. Ha ilyen nincs, akkor megkaptuk az átváltott szám egyes helyi értékű jegyét.

 
2 05  
  13  
    (2)
 
2 05  
6 13  
  1 (2)

A hányadosokat összefogva egy újabb számmal végezzük el az átváltást, így megkapjuk a hátulról következő jegyet.

  02 05  
  6 13  
    1 (2)
 
1 02 05  
  06 13  
    1 (2)
 
1 02 05  
  06 13  
    1 (2)
 
1 02 05  
3 06 13  
  0 1 (2)

Most egy nullát kapunk következő jegyként, és a hányadosokból további feldolgozásra 13-at.

  01 02 05  
  3 06 13  
    0 1 (2)
 
0 01 02 05  
  13 06 13  
    0 1 (2)
 
0 01 02 05  
  13 06 13  
    0 1 (2)
 
0 01 02 05  
6 13 06 13  
  1 0 1 (2)

A következő lépésben további feldolgozásra 06-ot kapunk. Ebből elhagyhatjuk a vezető nullát, és a feldolgozást közvetlenül a 6-os jeggyel kezdhetjük.

  0 01 02 05  
  06 13 06 13  
    1 0 1 (2)
 
  0 01 02 05  
3 06 13 06 13  
  0 1 0 1 (2)

A következő adódó hányados a 3.

    0 01 02 05  
  03 06 13 06 13  
    0 1 0 1 (2)
 
    0 01 02 05  
1 03 06 13 06 13  
  1 0 1 0 1 (2)

Most már csak egy egyes van hátra.

      0 01 02 05  
  01 03 06 13 06 13  
    1 0 1 0 1 (2)
 
      0 01 02 05  
0 01 03 06 13 06 13  
  1 1 0 1 0 1 (2)
 
      0 01 02 05  
0 01 03 06 13 06 13  
  1 1 0 1 0 1 (2)

Ezután az eljárás befejeződik, mivel a hányadosok oszlopába csak egy nulla kerül. Az eredménysorban a szám 2-es számrendszerbeli alakja áll, a jegyek helyes sorrendjében.

Lebegőpontos szorzás és osztás

A Horner-elrendezés gyors és hatékony módja annak, hogy kettes számrendszerben végezzen szorzásokat egy mikrokontroller, aminek nincs beépített szorzóegysége. Az egyik számot polinomnak tekinti, ahol 2 = x. Ezután 2-t és hatványait kiszorozza. Például 0,15625 és az m szám szorzata:

(0.15625)m=(0.00101b)m=(23+25)m=(23)m+(25)m=23(m+(22)m)=23(m+22(m)).

Két kettes számrendszerbeli szám, d és m szorzatának kiszámítása:

1. Egy regiszterben eltárolja a d számot, ide később a köztes eredményt menti.
2. Az m legkisebb helyi értékű szignifikáns jegyével kezdve:
2b. Megszámolja, hány nulla van a következő szignifikáns jegyig. Ha nincs több szignifikáns jegy, akkor a jelenlegi bit helyét veszi.
2c. Ezzel az értékkel baleltolást hajt végre a köztes eredményt tároló regiszterben.
3. Ha nincs több szignifikáns bit, akkor a köztes eredményt tartalmazó regiszterben a végeredmény van. Különben ehhez még hozzáadja d-t, és folytatja a 2. lépéssel.

Általában egy d3d2d1d0 bitekből álló kettes számrendszerbeli szám esetén a szorzat:

(d323+d222+d121+d020)m=d323m+d222m+d121m+d020m

Ebben az algoritmusban a nulla bitek kimaradnak, ezért csak azokat a biteket számolja, amelyeknek értéke 1, így a nullával való osztás nem fordulhat elő. A leosztással kapott egyenlet:

=d0(m+2d1d0(m+2d2d1(m+2d3d2(m)))).

Mivel minden nevező értéke egy, azért

=d0(m+2d1(m+2d2(m+2d3(m)))),

vagy ekvivalensen:

=d3(m+21d2(m+21d1(m+d0(m)))).

Kettes számrendszerben a kettő hatványaival való szorzás és osztás ugyanaz, mint a megfelelő számú bittel végzett eltolás. Például a 2−1 megfelelője egy jobbra eltolás, a 20 = 1 megfelelője helyben maradás, azaz eltolás nullával, és 21 megfelelője egy balratolás. Ezzel a kettes számrendszerbeli szorzás visszavezethető eltolásokra, kivonásokra és összeadásokra. A módszer gyors azokon a processzorokon, amelyek egy utasításkészletűek, és eltolás és összeadás akkumulációra képesek. A C lebegőpontos könyvtárral összehasonlítva a Horner-módszer pontatlanabb, de gyorsabb: névlegesen 13-szor gyorsabb, és CSD (kanonikus előjeles bit) esetén 16-szor gyorsabb, és a kódtérnek csak 20%-át használja.[10]

Implementációk

Octave

A fenti példa készítéséhez ezt az Octave implementációt használták:

function [y b] = horner(a,x)
  % Input a is the polynomial coefficient vector, x the value to be evaluated at.
  % The output y is the evaluated polynomial and b the divided coefficient vector.
  b(1) = a(1);
  for i = 2:length(a)
    b(i) = a(i)+x*b(i-1);
  end
  y = b(length(a));
  b = b(1:length(b)-1);
end

Python

Az alábbi kód Pythonban valósítja meg az algoritmust:

def horner(x, *polynomial):
    """A function that implements the Horner Scheme for evaluating a
    polynomial of coefficients *polynomial in x."""
    result = 0
    for coefficient in polynomial:
        result = result * x + coefficient
    return result

C nyelven

Ez C-ben íródott:

double HornerEvaluate (double x, double * CoefficientsOfPolynomial, unsigned int DegreeOfPolynomial)
{
    /*
        We want to evaluate the polynomial in x, of coefficients CoefficientsOfPolynomial, using Horner's method.
        The result is stored in dbResult.
    */
    double dbResult = 0.0;
    int i;
    for(i = DegreeOfPolynomial; i >= 0; i--)
    {
        dbResult = dbResult * x + CoefficientsOfPolynomial[i];
    }
    return dbResult;
}

Explicit szorzás-akkumulációt használó változat, az FMA utasításkészletet támogató processzorokon gyorsabb:

// gcc -std=c11 -lm horner.c -o horner
#include <math.h>
double horner_fma(double x, const double *coeffs, size_t count)
{
    double result = 0.0;
    for (int idx = count-1; idx >= 0; idx--)
        result = fma(result, x, coeffs[idx]);
    return result;
}

Hatékonysága

A naiv módszer többnyire n összeadást és (n2 + n)/2 szorzást igényel. Feltételezzük, hogy az egyes hatványokat ismételt szorzással számoljuk külön-külön, tehát nem használjuk fel a más monomokhoz kiszámított hatványt. Iteratív kiértékeléssel a szorzások száma 2n − 1-re csökkenthető, ez felhasználja az előző monomokhoz kiszámított hatványokat. Numerikus adatokkal számolva 2n-szer x jegyeinek számát kell eltárolni, mivel a kiértékelt polinomnak a nagyságrendje xn, ezért várhatóan ennyi jegye lesz a végeredménynek, és még xn-t is tárolni kell. Horner-elrendezéssel mindössze n szorzásra és n összeadásra van szükség, a tárhely pedig legfeljebb x jegyeinek számának n -szerese. Alternatív módszerrel a Horner-elrendezés n szorzás-akkumulációt igényel. A Horner-elrendezés a polinom k-adik deriváltjának kiszámítására is alkalmas, ehhez kn szorzást és összeadást használ.[11] A Horner-elrendezés optimális abban az értelemben, hogy bármely, tetszőleges polinomot kiértékelő algoritmus legalább ennyi műveletet igényel. Alexander Ostrowski 1954-ben bizonyította, hogy az összeadások száma minimális.[12] Victor Pan 1966-ban bizonyította, hogy a szorzások száma minimális.[13] Mátrixok helyettesítése esetén azonban a Horner-elrendezés javítható. Mátrixok esetén akkor optimális a Horner-elrendezés, ha a prekondicionálás nincs megengedve. Ez akkor szokásos, ha csak egyszer értékeljük ki a polinomot. Ha azonban a prekondicionálás megengedett, akkor gyorsabb algoritmusok is léteznek, amelyek transzformálják a polinom reprezentációját. Általában, az n-edfokú polinom kiértékeléséhez n/2+2 szorzás és n összeadás szükséges.[14]

Források

Jegyzetek

  1. Cormen et al. 2009, pp. 41, 900, 990.
  2. Weisstein, Eric W.: Horner's Rule (angol nyelven). Wolfram MathWorld
  3. Cajori 1911.
  4. Nyilvánvaló, hogy ez az eljárás kínai találmány, in Libbrecht 2005, p. 178.
  5. Josef Stoer: Numerische Mathematik 1. (németül) 9. (hely nélkül): Springer. 2004.  
  6. Higham 2002, Section 5.4.
  7. Interaktiver Lohn- und Einkommensteuerrechner: Rundungsvorschrift Archiválva 2014. május 21-i dátummal a Wayback Machine-ben Bundesministerium der Finanzen: Interaktiver Lohn- und Einkommensteuerrechner: Rundungsvorschrift
  8. Die Einkommensteuertarif-Formeln seit 1958 Wolfgang & Johannes Parmentier: Die Einkommensteuertarif-Formeln seit 1958
  9. Kress 1991, p. 112.
  10. Kripasagar 2008, p. 62.
  11. Pankiewicz 1968.
  12. Ostrowski 1954.
  13. Pan 1966.
  14. Knuth 1997.

Fordítás

  • Ez a szócikk részben vagy egészben a Horner's method című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.
  • Ez a szócikk részben vagy egészben a Horner-Schema című német Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.