interface de la bibliothèque PATRICIA; implémentation de la bibliothèque PATRICIA ;
interface de la bibliothèque sur les séries formelles ; implémentation de la bibliothèque sur les séries formelles
Retour à la page générale de La lettre de Caml.
type arbre_de_recherche = { chercher : string -> bool ; insérer : string -> unit ; supprimer : string -> unit } ;; value nouvel_arbre : unit -> arbre_de_recherche ;;
let rec intervalle i j = if i <= j then i :: (intervalle (i+1) j) else [] ;; let bits_of_char c = let c' = int_of_char c in it_list (fun l i -> (c' lsr i) land 1 :: l) [] (intervalle 0 7) ;; let bits_of_string s = list_it (fun i l -> bits_of_char s.[i] @ l) (intervalle 0 (string_length s - 1)) [0;0;0;0;0;0;0;0] ;; type arbre = Feuille of string | Nud of int * arbre * arbre ;; let rec skip k l = if k = 0 then l else skip (k - 1) (tl l) ;; let recherche a s = let rec aux l = function | Feuille s' -> s = s' | Nud(k,g,d) -> try let t :: q = skip k l in aux q (if t = 0 then g else d) with _ -> false in aux (bits_of_string s) a ;; let rec suppression a s = let rec aux l = function | Feuille s' when s <> s' -> Feuille s' | Feuille _ -> failwith "Arbre vide !" | Nud(k,Feuille s',d) when s' = s -> ( match d with | Feuille _ -> d | Nud(k',g',d') -> Nud(k + k' + 1,g',d') ) | Nud(k,g,Feuille s') when s' = s -> ( match g with | Feuille _ -> g | Nud(k',g',d') -> Nud(k + k' + 1,g',d') ) | Nud(k,g,d) -> try match skip k l with t :: q -> if t = 0 then Nud(k,(aux q g),d) else Nud(k,g,(aux q d)) with _ -> Nud(k,g,d) in aux (bits_of_string s) a ;; let trouve_place s a = let rec descend = function | Feuille s' -> s' | Nud(_,g,_) -> descend g in let rec aux l = function | Feuille s' -> s' | Nud(k,g,d) -> try match skip k l with t :: q -> aux q (if t = 0 then g else d) with _ -> descend g in aux (bits_of_string s) a ;; let rec discrimine l1 l2 i = match l1,l2 with t1 :: q1,t2 :: q2 -> if t1 <> t2 then i,t1,t2 else discrimine q1 q2 (i + 1) ;; let insertion a s = let s' = trouve_place s a in if s = s' then a else let l,l' = (bits_of_string s),(bits_of_string s') in let i,c,_ = discrimine l l' 0 in let rec aux j l = function | Feuille s' as a -> if c = 0 then Nud(j,Feuille s,a) else Nud(j,a,Feuille s) | Nud(k,g,d) as a -> if j > k then let t :: q = skip k l in if t = 0 then Nud(k,(aux (j - k - 1) q g),d) else Nud(k,g,(aux (j - k - 1) q d)) else if j < k then if c = 0 then Nud(j,Feuille s,Nud(k-j-1,g,d)) else Nud(j,Nud(k-j-1,g,d),Feuille s) else (* j = k *) failwith "Erreur irrécupérable" in aux i l a ;; (******************************************* ce type est défini dans le fichier .mli, sa définition ne doit pas être répétée ! type arbre_de_recherche = { chercher : string -> bool ; insérer : string -> unit ; supprimer : string -> unit } ;; *********************************************) let nouvel_arbre () = let a = ref (Feuille "") in { chercher = (function s -> recherche !a s) ; insérer = (function s -> a := insertion !a s) ; supprimer = (function s -> a := suppression !a s) } ;;
#open "num" ;; type série_formelle ;; value prefix +@ : série_formelle -> série_formelle -> série_formelle and prefix -@ : série_formelle -> série_formelle -> série_formelle and prefix *@ : série_formelle -> série_formelle -> série_formelle and prefix /@ : série_formelle -> série_formelle -> série_formelle and prefix @@ : série_formelle -> série_formelle -> série_formelle and prefix ^@ : série_formelle -> num -> série_formelle and prefix !@ : num list -> série_formelle and prefix %@ : num -> série_formelle -> série_formelle and zéro : num and un : num and deux : num and trois : num and quatre : num and cinq : num and six : num and sept : num and huit : num and neuf : num and dix : num and un_demi : num and moins_un : num and moins_deux : num and moins_trois : num and moins_quatre : num and moins_cinq : num and moins_six : num and moins_sept : num and moins_huit : num and moins_neuf : num and moins_dix : num and moins_un_demi : num and print_SF : série_formelle -> int -> unit and print_par_défaut : série_formelle -> unit and installe_impression : unit -> unit and crée_SF_de : (num -> num) -> série_formelle and crée_SF_expo_de : (num -> num) -> série_formelle and intégration_SF : série_formelle -> num -> série_formelle and dérivation_SF : série_formelle -> série_formelle and sinus : série_formelle and cosinus : série_formelle and sinus_h : série_formelle and cosinus_h : série_formelle and tangente : série_formelle and tangente_h : série_formelle and arctangente : série_formelle and arctangente_h : série_formelle and exponentielle : série_formelle and ln_un_plus_z : série_formelle and arcsinus : série_formelle and arcsinus_h : série_formelle and catalan : série_formelle ;;
#open "num" ;; type 'a glaçon = | Gelé of unit -> 'a | Connu of 'a ;; type série_formelle = { Constante : num ; mutable Reste : série_formelle glaçon } ;; let moins_un = num_of_int (-1) and moins_deux = num_of_int (-2) ;; let [zéro;un;deux;trois;quatre;cinq;six;sept;huit;neuf;dix] = map num_of_int [0;1;2;3;4;5;6;7;8;9;10] ;; let [moins_un;moins_deux;moins_trois;moins_quatre;moins_cinq;moins_six;moins_sept;moins_huit;moins_neuf;moins_dix] = map num_of_int [-1;-2;-3;-4;-5;-6;-7;-8;-9;-10] ;; let un_demi = un // deux and moins_un_demi = moins_un // deux ;; let reste_SF s = match s.Reste with | Gelé r -> let a = r() in s.Reste <- Connu a ; a | Connu a -> a ;; let crée_SF_de f = let rec crée n = { Constante = f n ; Reste = Gelé (function () -> crée (n +/ un)) } in crée zéro ;; let SF_de_poly l = let rec crée = function | [] -> { Constante = zéro ; Reste = Gelé (function () -> crée []) } | a :: q -> { Constante = a ; Reste = Gelé (function () -> crée q) } in crée l ;; let crée_SF_expo_de f = let rec crée n nn = { Constante = (f n) // nn ; Reste = Gelé (function () -> crée (n +/ un) (nn */ (n +/ un))) } in crée zéro un ;; let rec liste_des_coefficients s = function | 0 -> [] | n -> s.Constante :: (liste_des_coefficients (reste_SF s) (n-1)) ;; let rec zéro_SF () = { Constante = zéro ; Reste = Gelé zéro_SF } ;; let rec zn_SF = function | 0 -> { Constante = un ; Reste = Gelé zéro_SF } | n -> { Constante = zéro ; Reste = Gelé (function () -> zn_SF (n-1)) } ;; let rec addition_SF s t = { Constante = s.Constante +/ t.Constante ; Reste = Gelé (function () -> addition_SF (reste_SF s) (reste_SF t)) } ;; let rec soustraction_SF s t = { Constante = s.Constante -/ t.Constante ; Reste = Gelé (function () -> soustraction_SF (reste_SF s) (reste_SF t)) } ;; let rec multiplication_SF_num s n = { Constante = s.Constante */ n ; Reste = Gelé (function () -> multiplication_SF_num (reste_SF s) n) } ;; let opposé_SF s = multiplication_SF_num s moins_un ;; let rec intégration_SF s k0 = { Constante = k0 ; Reste = Gelé (function() -> intègre_SF_depuis_un_certain_rang s un) } and intègre_SF_depuis_un_certain_rang s n = { Constante = s.Constante // n ; Reste = Gelé (function () -> intègre_SF_depuis_un_certain_rang (reste_SF s) (n +/ un)) } ;; let dérivation_SF s = let rec dérivation_aux s n = { Constante = s.Constante */ n ; Reste = Gelé (function () -> dérivation_aux (reste_SF s) (n +/ un)) } in dérivation_aux (reste_SF s) un ;; let multiplication_SF s t = let produit_de_Cauchy a b = let b' = rev b in it_list2 (fun t x y -> t +/ x */ y) zéro a b' in let rec multiplie_aux s t sl tl = let sl' = s.Constante :: sl and tl' = t.Constante :: tl in { Constante = produit_de_Cauchy sl' tl' ; Reste = Gelé (function () -> multiplie_aux (reste_SF s) (reste_SF t) sl' tl') } in multiplie_aux s t [] [] ;; let composition_SF s t = let rec intervalle i j = if i > j then [] else i :: (intervalle (i + 1) j) in let rec k_somme k s = (* k_somme 3 6 renvoie [[4; 1; 1]; [3; 2; 1]; [3; 1; 2]; ... *) if s = 0 then [] else if k = 1 then [ [ s ] ] else it_list (fun ll i -> (map (function l -> i :: l) (k_somme (k - 1) (s - i))) @ ll) [] (intervalle 1 s) in let coeff av bv = let n = vect_length av - 1 in let sbk l = it_list (fun x i -> x */ bv.(n - i)) un l in it_list (fun s k -> s +/ av.(n-k) */ (it_list (fun x l -> x +/ (sbk l)) zéro (k_somme k n))) zéro (intervalle 1 n) in let rec aux al bl s t = let al' = s.Constante :: al and bl' = t.Constante :: bl in { Constante = coeff (vect_of_list al') (vect_of_list bl') ; Reste = Gelé(function () -> aux al' bl' (reste_SF s) (reste_SF t)) } in if t.Constante <>/ zéro then failwith "La composée a(b(z)) n'existe que si v(b) > 1" ; { Constante = s.Constante ; Reste = Gelé(function () -> aux [ s.Constante ] [ t.Constante ] (reste_SF s) (reste_SF t)) } ;; let un_plus_z_puissance_a_SF a = let rec aux coef k = let k' = k +/ un in { Constante = coef ; Reste = Gelé (function () -> aux (coef */ (a -/ k) // k') k') } in { Constante = un ; Reste = Gelé (function () -> aux a un) } ;; let un_sur_a_plus_z_SF a = if a =/ zéro then failwith "1/z n'a pas de développement en série formelle" ; let a' = zéro -/ a in let rec aux coeff = { Constante = coeff ; Reste = Gelé (function () -> aux (coeff // a')) } in aux (un // a) ;; let rec division_SF s t = let rec Cauchy_inverse a b t0 sn = let b' = tl (rev b) in (sn -/ (it_list2 (fun s x y -> s +/ x */ y) zéro a b')) // t0 in let rec divise_aux s t ul tl t0 = let tl' = t.Constante :: tl in let u_n = Cauchy_inverse ul tl' t0 s.Constante in { Constante = u_n ; Reste = Gelé (function () -> divise_aux (reste_SF s) (reste_SF t) (u_n :: ul) tl' t0) } in if t.Constante =/ zéro then if s.Constante =/ zéro then division_SF (reste_SF s) (reste_SF t) else failwith "Division impossible : valuation du numérateur inférieure à celle du dénominateur" else divise_aux s t [] [] t.Constante ;; let puissance_SF_num s n = let a = s.Constante in try multiplication_SF_num (composition_SF (un_plus_z_puissance_a_SF n) { Constante = zéro ; Reste = Gelé(function () -> reste_SF (multiplication_SF_num s (un // a))) }) (if a =/ un then un else a **/ n) with _ -> failwith "Exponentiation impossible" ;; let rec évalue_SF s x n = if n = 0 then s.Constante else s.Constante +/ x */ (évalue_SF (reste_SF s) x (n-1)) ;; let prefix +@ = addition_SF and prefix -@ = soustraction_SF and prefix *@ = multiplication_SF and prefix /@ = division_SF and prefix @@ = composition_SF and prefix ^@ = puissance_SF_num and prefix !@ = SF_de_poly and prefix %@ n s = multiplication_SF_num s n ;; #open "format" ;; let print_num n = print_string (string_of_num n) ;; let print_variable = function | 0 -> false | 1 -> print_string " z" ; true | n -> print_string " z^" ; print_int n ; true ;; let print_term plus degré s = let c = s.Constante in if c =/ zéro then false else if c =/ un then begin print_string plus ; print_variable degré end else if c =/ moins_un then begin print_string "- " ; print_variable degré end else begin if c >=/ zéro then print_string plus else print_string "- " ; print_num (abs_num c) ; print_variable degré end ;; let rec print_SF s until = open_hovbox 1; let c = s.Constante in if until == 0 then print_num c else let rest = ref s in let nul = ref true in if not (c =/ zéro) then (print_num c ; print_space() ; nul := false) ; for i = 1 to until do rest := reste_SF !rest; let delim = if !nul then "" else "+ " in if print_term delim i !rest then ( nul := false ; print_space()) done ; if not !nul then print_string "+ " ; print_string "O(z^"; print_int (succ until) ; print_string ")" ; close_box() ;; let print_par_défaut s = print_SF s 11 ;; let installe_impression () = install_printer "print_par_défaut" ;; let rec sinus = { Constante = zéro ; Reste = Gelé (function () -> intègre_SF_depuis_un_certain_rang cosinus un) } and cosinus = { Constante = un ; Reste = Gelé (function () -> intègre_SF_depuis_un_certain_rang (opposé_SF sinus) un) } ;; let rec sinus_h = { Constante = zéro ; Reste = Gelé (function () -> intègre_SF_depuis_un_certain_rang cosinus_h un) } and cosinus_h = { Constante = un ; Reste = Gelé (function () -> intègre_SF_depuis_un_certain_rang sinus_h un) } ;; let tangente = sinus /@ cosinus ;; let tangente_h = sinus_h /@ cosinus_h ;; let arctangente = intégration_SF ((!@ [un]) /@ (!@ [un;zéro;deux])) zéro ;; let arctangente_h = intégration_SF ((!@ [un]) /@ (!@ [un;zéro;moins_deux])) zéro ;; let exponentielle = crée_SF_expo_de (function _ -> un) ;; let ln_un_plus_z = intégration_SF (un_plus_z_puissance_a_SF moins_un) zéro ;; let arcsinus = intégration_SF ((!@ [un;zéro;moins_deux]) ^@ moins_un_demi) zéro ;; let arcsinus_h = intégration_SF ((!@ [un;zéro;deux]) ^@ moins_un_demi) zéro ;; let catalan = ((!@ [un]) -@ ((!@ [un;moins_quatre]) ^@ un_demi)) /@ (!@ [zéro;deux]) ;;
Retour à la page générale de La lettre de Caml.