(* Puissance efficace, suppose n ≥ 0 *) let rec puissance x n = match n with | 0 -> 1 | _ -> let y = puissance x (n/2) in if n mod 2 = 0 then y * y else x * y * y ;; |
La solution la plus simple consiste ensuite à bêtement calculer la somme de la valeur des monômes.
let evaluer p x = List.fold_left (fun r m -> r + m.coeff * puissance x m.degre) 0 p ;; |
Mais on peut faire un peu mieux (c'est à dire faire moins de multiplications) en s'inspirant de la règle dite de Horner. Rappelons la règle:
Puis on explicite l'évaluation :
Avec les polynômes creux, l'application directe donne plus ou moins ceci (en replaçant les monômes absents par des monômes de coefficient nul)
(* Méthode dite de Horner, pdeg est le degré du monome précédant *) let rec horner pdeg r x p = match p with | [] -> if pdeg = 0 then r else horner (pdeg-1) (r*x) x [] | m::rem -> if pdeg = m.degre then horner m.degre (r + m.coeff) x rem else horner (pdeg-1) (r*x) x p ;; let evaluer p x = match p with | [] -> 0 | m::rem -> horner m.degre m.coeff x rem ;; |
Mais on peut employer notre function puissance en réflechissant un peu:
let rec horner pdeg r x p = match p with | [] -> r * puissance x pdeg | m::rem -> horner m.degre (r * (puissance x (pdeg-m.degre)) + m.coeff) x rem ;; |