$$\newcommand{\mtn}{\mathbb{N}}\newcommand{\mtns}{\mathbb{N}^*}\newcommand{\mtz}{\mathbb{Z}}\newcommand{\mtr}{\mathbb{R}}\newcommand{\mtk}{\mathbb{K}}\newcommand{\mtq}{\mathbb{Q}}\newcommand{\mtc}{\mathbb{C}}\newcommand{\mch}{\mathcal{H}}\newcommand{\mcp}{\mathcal{P}}\newcommand{\mcb}{\mathcal{B}}\newcommand{\mcl}{\mathcal{L}} \newcommand{\mcm}{\mathcal{M}}\newcommand{\mcc}{\mathcal{C}} \newcommand{\mcmn}{\mathcal{M}}\newcommand{\mcmnr}{\mathcal{M}_n(\mtr)} \newcommand{\mcmnk}{\mathcal{M}_n(\mtk)}\newcommand{\mcsn}{\mathcal{S}_n} \newcommand{\mcs}{\mathcal{S}}\newcommand{\mcd}{\mathcal{D}} \newcommand{\mcsns}{\mathcal{S}_n^{++}}\newcommand{\glnk}{GL_n(\mtk)} \newcommand{\mnr}{\mathcal{M}_n(\mtr)}\DeclareMathOperator{\ch}{ch} \DeclareMathOperator{\sh}{sh}\DeclareMathOperator{\th}{th} \DeclareMathOperator{\vect}{vect}\DeclareMathOperator{\card}{card} \DeclareMathOperator{\comat}{comat}\DeclareMathOperator{\imv}{Im} \DeclareMathOperator{\rang}{rg}\DeclareMathOperator{\Fr}{Fr} \DeclareMathOperator{\diam}{diam}\DeclareMathOperator{\supp}{supp} \newcommand{\veps}{\varepsilon}\newcommand{\mcu}{\mathcal{U}} \newcommand{\mcun}{\mcu_n}\newcommand{\dis}{\displaystyle} \newcommand{\croouv}{[\![}\newcommand{\crofer}{]\!]} \newcommand{\rab}{\mathcal{R}(a,b)}\newcommand{\pss}[2]{\langle #1,#2\rangle} $$
Bibm@th

Algorithme de Horner

Lorsqu'on cherche à évaluer un polynôme $P(x)=a_n x^n+a_{n-1}x^{n-1}+\dots+a_0$, il n'est clairement pas optimal de calculer chaque $a_k x^k$, puis de les ajouter. En effet, pour calculer $a_n x^n$, il est intéressant de se souvenir que l'on a déjà calculé $a_{n-1}x^{n-1}$, et donc $x^{n-1}$.

Le mathématicien anglais Horner a mis au point une méthode efficace utilisant cette remarque. Voici comment elle fonction sur un exemple simple : pour calculer $5x^4-4x^3+3x^2-2x+1$, on peut remarquer que cette quantité est égale à $(x(x(x(5x-4)+3)-2)+1)$. On calcule alors successivement $a=5$, $b=xa-4=5x-4$, $c=xb+3=(x(5x-4)+3$, $d=xc-2$, et enfin $e=xd+1$ qui est le résultat souhaité. Plus généralement, pour un polynôme $P(x)=a_n x^n+a_{n-1}x^{n-1}+\cdots+a_1x+a_0$, on écrit $$P(x)= (\cdots(((a_n x+a_{n-1})x+a_{n-2})x+a_{n-3})\cdots)x+a_0.$$ Le calcul nécessitera simplement $n$ multiplications et $n$ additions.

Voici une fonction écrite sous Python qui prend en entrée la liste des coefficients d'un polynôme $P$ et un réel $x$, et qui retourne $P(x)$ grâce à la méthode de Horner.

def horner(P,x):
    n=len(P)
    valeur=P[n-1]
    for i in range(n-2,-1,-1):
        valeur=valeur*x+P[i]
    return valeur