Metoda Hornera wyliczania wartości wielomianów

Wielomian

Jak wiadomo, wielomian (stopnia N), to wyrażenie postaci: w(x)=i=0NaixI

Wyliczanie wartości wielomianu

W naturalny sposób, kod (C) wyliczający jego wartość wyglądać może tak:

double wielomian (int N, double *a, double x)
{
  double w = 0.;
  int i;
  for (i = 0; i < N; i++)
    w += pow (x, i) * a[i];
  return w;
}

Sprytny student zauważy, że kod ten można „zoptymalizować" w sposób następujący:

double wielomian (int N, double *a, double x)
{
  double w = a[0];
  int i;
  for (i = 1; i < N; i++)
    w += pow (x, i) * a[i];
  return w;
}

oszczędzając jeden obieg pętli (i jedno wywołanie funkcji pow). Czy możliwe są dalsze optymalizacje? Oczywiście, można zrezygnować z funkcji pow:

double wielomian (int N, double *a, double x)
{
  double w = 0.;
  int i;
  double pow = 1;
  for (i = 0; i < N; i++)
    {
      w += pow * a[i];
      pow *= x;
    }
  return w;
}

(Prawdę mówiąc warto rezygnować z funkcji pow, gdyż jest to armata wystawiona na wróbelka: podnosimy x do potęgi całkowitej.)

Czy są możliwe dalsze optymalizacje? Czy może to mieć wpływ na dokładność obliczeń? Czy jakąś własność numeryczną algorytmu?

„Tradycyjna" metoda obliczeń wymaga 1+2++(N1)+N=N(N+1)2 mnożeń i N dodawań.

Metoda Hornera

Zapisując wielomian nieco inaczej: w(x)=a0+x(a1+x(a2++x(aN1+xaN))) redukujemy liczbę operacji do N dodawań i N mnożeń.

Co więcej algorytm Hornera jest numerycznie poprawny.

Algorytm Hornera może być również przydatny podczas dzielenia wielomianu w(y) przez dwumian yx dając w wyniku współczynniki wyniku (wielomianu będącego ilorazem w(y)yx).

Poprzedni
Następny