Calcul entropie ocaml
jeremux
Messages postés
60
Statut
Membre
-
jeremux Messages postés 60 Statut Membre -
jeremux Messages postés 60 Statut Membre -
Bonjour, je dois calculer l'entropie d'un fichier vu comme une source de couple d'octets. Le problème de mon programme c'est qu'il retourne un résultat négatif! Je suis pourtant sur de la formule...Je suis dessus depuis hier soir. Quelqu'un aurait-il une idée sur mon erreur ?
Merci d'avance.
Pour creer l'exécutable: (sous linux) (si votre fichier se nomme entropie.ml)
ocamlc -c entropie.ml
ocamlc -o entropie entropie.cmo
./entropie <nom_du_fichier_a_calculer_lentropie>
Merci à tous!
Merci d'avance.
let entropie fichier =
let compteurs = Array.make 256 (Array.make 256 0) (* compteurs pour chacun des couples d'octets *)
and somme = ref 0. (* compteur total de couple d'octets *) in
(* Parcours du fichier pour compter les différents couple d'octets qu'il contient *)
let entree = open_in_bin fichier in
let res = ref (0,0.0) in
begin
try
while true do
let n = input_byte entree in
let p = input_byte entree in
compteurs.(n).(p) <- compteurs.(n).(p) + 1; (* Comptabilisation de tel couple *)
somme := !somme +. 1. (* comptabilisation des couples *)
done;
with
End_of_file ->
let tmp = ref 0.0 in
let ns = ref 0.0 in
for i=0 to 255 do
for j=0 to 255 do
ns := float_of_int(compteurs.(i).(j));
if compteurs.(i).(j)<>0 then (* le couple doit apparaitre au moins une fois *)
tmp := !tmp +. !ns*.(log(!ns)/.(log(2.)));
done;
done;
res:=(int_of_float(!somme),((1./.log(2.))*.(log(!somme)))-.(!tmp/.(!somme)));
close_in entree;
end;
!res;;
(**[usage ()] imprime sur la sortie standard l'utilisation normale du programme.*)
let usage () =
Printf.printf "Usage : %s <fichier>\n" Sys.argv.(0) ;
Printf.printf "\t <fichier> = nom du fichier dont on veut l'entropie.\n" ;
exit 1
(** Procédure principale.*)
let principal () =
if Array.length Sys.argv <> 2 then
usage ()
else
let nb,ent = entropie Sys.argv.(1)
in
Printf.printf "%d paires d'octets lu(s).\n" nb ;
Printf.printf "Entropie = %f bits par seizet.\n" ent
let _ = principal ()
Pour creer l'exécutable: (sous linux) (si votre fichier se nomme entropie.ml)
ocamlc -c entropie.ml
ocamlc -o entropie entropie.cmo
./entropie <nom_du_fichier_a_calculer_lentropie>
Merci à tous!
A voir également:
- Calcul entropie ocaml
- Calcul km marche à pied gratuit - Télécharger - Sport
- Calcul charpente bois gratuit - Télécharger - Architecture & Déco
- Calcul moyenne excel - Guide
- Logiciel gratuit calcul valeur nutritionnelle - Télécharger - Santé & Bien-être
- Logiciel gratuit calcul surface m2 - Télécharger - Outils professionnels
2 réponses
bonsoir
d'abord je suis desole pour mon mal Francais; dans ce code je pense que vous faites votre premier faute en utilisant array d'array :
"let compteurs = Array.make 256 (Array.make 256 0) "
ici si vous utilisez cette expression; la somme de toutes elements de tableaux compteurs va devenir plus grande que la valeur de variable "somme"(c'est absurde car la somme des occurrence doit etre egale a la "somme"). Pour stocker les qte d'occurrence des couples vous devez utilisez une matrix. (Array.make_matrix compteures dim1 dim2 e et ici dim1=dim2=256 et e=0).
deuxiemment par exemple vous utilisez log(a)/log(2) pour calculer logarithme en base 2 de "a" mais en OCAML log(a) est le logarithme neperien de "a" pour calculer log2(a) vous devez utiliser log10(a)/log10(2) et ici log10(a) = logarithme de a en base 10
d'abord je suis desole pour mon mal Francais; dans ce code je pense que vous faites votre premier faute en utilisant array d'array :
"let compteurs = Array.make 256 (Array.make 256 0) "
ici si vous utilisez cette expression; la somme de toutes elements de tableaux compteurs va devenir plus grande que la valeur de variable "somme"(c'est absurde car la somme des occurrence doit etre egale a la "somme"). Pour stocker les qte d'occurrence des couples vous devez utilisez une matrix. (Array.make_matrix compteures dim1 dim2 e et ici dim1=dim2=256 et e=0).
deuxiemment par exemple vous utilisez log(a)/log(2) pour calculer logarithme en base 2 de "a" mais en OCAML log(a) est le logarithme neperien de "a" pour calculer log2(a) vous devez utiliser log10(a)/log10(2) et ici log10(a) = logarithme de a en base 10