begin process at 2010 03 22 00:13:46
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > LOI DE POISSON (STATS-PROBA)

LOI DE POISSON (STATS-PROBA)


 Information sur la source

Note :
8,5 / 10 - par 2 personnes
8,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Classé sous :loi, poisson, binomiale, combinaison, probabilité Niveau :Débutant Date de création :29/11/2006 Vu :13 813

Auteur : otodidact

Ecrire un message privé
Commentaire sur cette source (12)
Ajouter un commentaire et/ou une note

 Description

Bonjour :)

Autodidacte, le code reste imparfait mais correct.
Restant incertain sur la logique mathématique employée, j'attends vos remarques autant sur le code que sur la logique mathématique ;)

Loi binomiale : P(x=k) = (Combinaison k de n)*(p exposant k)* (q exposant(n-k))
Combinaison k de n = n! / (k!(n-k)!)
E(x) = np     ecart type e(x) = racine carré de npq

Loi de Poisson : P(x=k) = exponentielle(-t)*(t exposant k)/k!
E(x) = t      variance V (x = t) = t

Source

  • #include <stdio.h>
  • #include <math.h>
  • long fact(int i)
  • {
  • long f;
  • if (i==0)
  • {
  • return 1;
  • }
  • else
  • {
  • f = fact(i - 1);
  • return i*f;
  • }
  • }
  • main ()
  • {
  • int n, k;
  • double e, p, q, r, t, x, y, z;
  • printf("entrez la valeur de k entier non nul positif\n");
  • scanf("%d", &k);
  • printf("entrez le nombre d'essais n entier non nul positif\n");
  • scanf("%d", &n);
  • x = fact(n);
  • y = fact(k);
  • z = fact(n-k);
  • r = x/(y*z);
  • printf("la combinaison n de k est : %lf\n", r);
  • x = n-1;
  • y = k-1;
  • z = x-y;
  • x = fact(x);
  • y = fact(y);
  • z = fact(z);
  • e = x/(y*z);
  • e = e/x;
  • p = pow(e, k);
  • printf("la probabilite de succes k de n est : %lf\n", p);
  • x = n-k;
  • y = 1-p;
  • q = pow(y, x);
  • r = r*p*q;
  • printf("le resultat de la loi binomiale est : %lf\n", r);
  • e = n*p;
  • printf("l'esperance est de : %lf\n", e);
  • t = sqrt(e*q);
  • printf("l'ecart type est de : %lf\n", t);
  • x = exp(-e);
  • y = pow (e,k);
  • z = x*y;
  • k = fact(k);
  • x = z/k;
  • printf("la loi de poisson est : %g\n", x);
  • }
#include <stdio.h>
#include <math.h>

long fact(int i)
{
       long f;
       
       if (i==0)
       {
          return 1;
       }
       else
       {
           f = fact(i - 1);
           return i*f;
       }
       
}

main ()
{
     int n, k;
     double e, p, q, r, t, x, y, z;
     
     printf("entrez la valeur de k entier non nul positif\n");
     scanf("%d", &k);
     printf("entrez le nombre d'essais n entier non nul positif\n");
     scanf("%d", &n);
     
     x = fact(n);
     y = fact(k);
     z = fact(n-k);
     
     r = x/(y*z);
     
     printf("la combinaison n de k est : %lf\n", r);
     
     x = n-1;
     y = k-1;
     z = x-y;
     x = fact(x);
     y = fact(y);
     z = fact(z);    
  
     e = x/(y*z);
     e = e/x;
     p = pow(e, k);

     printf("la probabilite de succes k de n est : %lf\n", p);
     
     x = n-k;
     y = 1-p;
     q = pow(y, x);
     
     r = r*p*q;
     printf("le resultat de la loi binomiale est : %lf\n", r);
     e = n*p;
     printf("l'esperance est de : %lf\n", e);
     t = sqrt(e*q);
     printf("l'ecart type est de : %lf\n", t);
     
     x = exp(-e);
     y = pow (e,k);
     z = x*y;
     k = fact(k);     
     x = z/k;
     printf("la loi de poisson est : %g\n", x);
}

 Conclusion

Après 4 heures de mal de crâne en compagnie de Messieurs Claude Delannoy et Michel Divay (pour leurs bouquins ;) ), je tiens à remercier Pascal, Pascale et Laurent qui se reconnaîtront si d'aventure ils passent par là... (je sais, je peux optimiser !!!).

Le code reste certainement perfectible bien que je sois fier (modestement) d'avoir réussi à le faire fonctionner. Limité par le 32 bits, n'entrez pas de valeur trop élevées.

Dernière précision, les éditions Casteilla n'édite plus le phénoménal "Mémo formulaire" de M. Yves Déplanche d'où j'ai tiré des heures de programmation et les formules mathématiques de ce programme. Une réédition de cette bible serait la bienvenue pour tous les futurs techniciens...


 Sources de la même categorie

Source avec Zip TRANSFORMER UN ENTIER EN DEUX NOMBRES COMPOSÉ DES MEMES CHIF... par thebroyeur
CALCULE LOG(X) par tagtog
Source avec Zip Source avec une capture ALGORITHME DE TRI D'UN TABLEAU PAR ORDRE CROISSANT OU DÉCROI... par Thuzhen
Source avec une capture CALCUL DE VARIANCE par Minilogus
Source avec une capture GÉNÉRATEUR DE CLÉS SUR 26 DIGITS AU FORMAT HEXADÉCIMAL par besilent

 Sources en rapport avec celle ci

Source avec Zip SIMULATION DES LOIS DE PROBABILITÉ par Ali_usto
Source avec Zip GÉNÉRATEUR D'ARRANGEMENTS par islem1982
GÉNÉRATION D'UNE LISTE DES COMBINAISONS SANS RÉPÉTITION D'ÉL... par AlexN

Commentaires et avis

Commentaire de yann_lo_san le 29/11/2006 15:46:44

Et bien pour un autodidacte, ça vaut bien 9 !

Commentaire de otodidact le 30/11/2006 18:28:00

Merci Yann.

Ces lignes de codes représentent la synthèse de différents programmes sur des formules statistiques (bien qu'écrits en 2002) qui existaient déjà sur le site, et réécrits pour la Loi de Poisson. De manière un peu brouillonne pour les variables réutilisées, et sans passer par de multiples fonctions, afin d'éviter la gourmandise en ressources.

Bien que le résultat mathématique obtenu soit correct, le tableau de Poisson est destiné à des valeurs d'espérance E(x) beaucoup plus élevées. Mais il s'agit d'apprendre et de prendre plaisir.

Commentaire de pgassie le 11/12/2006 07:13:54

Cher otodidacte,
Puisque tu sollicites des remarques, voici mes encouragements pour un code très propre, très proche de la formulation mathématique et quelques pistes pour l'améliorer.
1°)il n'y a aucun contrôle de validité, ni de dépassement de capacité, et des petits problèmes de type.
- si la fonction fact(int i)est attaquée par un négatif, la condition d'arrêt n'est jamais atteinte.
- tu prends la peine de retourner un long avec fact()mais ligne 65, tu la renvoies sur un pauvre int.(C'est pas très grave, voir ci-dessous)
- le MAXINT dépend du compilateur, avec le mien, la fonction fact(i)renvoie des valeurs correctes pour i de 0 à 12.
On est tenté de modifier les int et les long par "unsigned", toujours sur 32 bits, mais en ne prenant que les positifs on atteint 2^32-1, soit presque 4 300 000 000.
Malheureusement 13! est plus grand. Damned!
Alors, on ne touche à rien et on fait un test pour que i soit entre 0 et 12 et arrêt sinon.
L'autre solution, pas très élégante, est de transformer fact() pour qu'elle renvoie un double. Avec mon compilateur j'arrive à 171! (beaucoup).
Malheureusement (bis), avec les doubles, il est illusoire de croire qu'un nb x qui s'affiche 2.000 soit forcément égal à un nb y qui s'affiche aussi 2.000 .
Il faut alors définir un très petit epsilon (qui dépend de ta machine) et
remplacer le test x==y par x-y<=epsilon.
2°)Les fractions de factorielles.
-ce sont des entiers positifs, risquer des dépassements de capacités des erreurs d'arrondis en les transformant en rééls n'est pas terrible.
- les fractions d'entiers ne demandent qu'à être simplifiées. Comment ? C'est une bonne question, je vous remercie de me l'avoir posée.
Je crois voir deux listes d'entiers l'une pour ce qui se multiplie au numérateur, l'autre pour ce qui se multiplie au dénominateur, éliminer les entiers communs aux deux listes, diviser ce qui tombe juste, puis diviser les produits de ce qui reste dans les 2 listes.
Côté clarté du code, on n'a rien gagné mais la précision du résultat est meilleure.
3°)Le dépassement de capacité des entiers n'est à ma connaissance géré par aucun langage de haut niveau, alors que c'est tout bête en assembleur. Il y a un bit "overflow" qui reste à 0 si tout va bien.
Un truc consiste à vérifier que fac(i)>fac(i-1), si c'est faux, on est sûr qu'il y a dépassement.
Ici fact(13)>fact(12), hélas fact(13)<13xfact(12).
Si quelqu'un a une meilleure idée, c'est le moment.

Encore bravo otodidacte. Tu as remarqué que si je me suis acharné sur ta fonction fact, je n'ai rien dit sur les autres ; "double" a la bonne idée d'afficher "inf" pour infini.

Amitiés

Commentaire de yann_lo_san le 11/12/2006 16:11:43

PGASSIE >> commentaire très instructif.
Voici un exemple bète pour gérer l'overflow des unsigned sur une multiplication (à adapter pour besoin)

unsigned short MultShortInt(unsigned short op1, unsigned short op2)
{
unsigned char ovf = 0x00;

__asm
{
mov ax,  op1
mul  op2
jc ERR
jmp  FIN
ERR:
mov ovf, 01H
FIN:
}

if( ovf )
Throw(OVERFLOW_EXCEPTION);

return(op1 * op2);
}

Commentaire de Amanobuo le 11/12/2006 23:16:32

As tu pense a le recompiler sous TIGCC ? ca pourrai etre tres utile !

Commentaire de pgassie le 13/12/2006 00:15:15

Après reflexion, je présente ce petit code :


#include <iostream>
#include<stdlib.h>
using namespace std;

const long FACT[]=
    {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600};

const unsigned long MAXULONG=-1; // idiot mais c'est l'astuce.
                                 // "warning" mais compile !  
const long MAXLONG = MAXULONG/2;

unsigned long multULong(unsigned long op1,unsigned long op2){
  if (MAXULONG/op2<op1) cout <<"\t\a>>> PANIQUE <<<"<< endl;
  return (op1*op2);
}

int main(int argc, char *argv[])
{
  for (int i=0;i<13;i++)cout << i << "! = " << FACT[i] << endl;
  cout << endl;

  cout << "Max des unsigned long : " <<MAXULONG << endl;
  cout << "Min des unsigned long : 0 (rappel)" << endl;
  cout << "Max des long : " << MAXLONG <<endl;
  cout << "Min des long : " << -MAXLONG-1 << endl;

  cout << endl << endl;
  cout << "OPERATIONS SURES" << endl << endl;
  cout << "1250 x 3000 = " << multULong(1250,3000) << endl;
  system("pause");
  cout << "9999999 x 9999 = " << multULong(9999999,999) << endl;
  system("pause");
  return 0;
}

Explications :
1°) Une fonction fact() (massivement récursive) pour des valeurs d'entrée possibles de 0 à 12 (voir message précédent), c'est de la confiture à des cochons.
Bon sang, mais c'est bien sûr, un tableau de constantes suffit ! Et c'est plus rapide...
2°) Pour le calcul de MAXULONG, torturer un peu le compilateur est plus simple que de faire le calcul à partir de sizeof().
3°) Les dépassements de capacité ne peuvent se produire qu'avec l'addition et la multiplication.
La division entière MAXULONG par un op2 de 1 à MAXULONG a un résultat entier entre MAXULONG et 1. (Le cas zéro est zappé pour la clarté de cette démo).
Si MAXULONG/op2<op1 alors op2xop1<MAXULONG
Rest à faire : la simplification de n! / (k!(n-k)!).Une idée ?


Merci à yann_lo_san. Ta fonction n'est pas bête du tout, c'est à çà que je pensais...
si je ne me trompe pas, il doit même être possible de récupérer le produit qui est dans AX.
PS. Sous Konqueror, le textarea pour l'email fait deux lignes de vingt caractères, pour se relire c'est le pied.
Excusez les fautes de frappe.
Merci

Commentaire de BruNews le 13/12/2006 02:05:45 administrateur CS

yann > pourquoi faire la multiplication 2 fois alors que c'est une opération couteuse en cycles ?
Tant qu'à le faire en asm, on y va complet et on gagne vraiment.
En __fastcall très rapide, 1 seul push, les 2 args vont en ecx et edx.
__declspec(naked) DWORD __fastcall bnMult(DWORD a, DWORD b, DWORD *pOvf)
{
  __asm {
    mov  eax, edx
    mul  ecx
    mov  ecx, [esp+4]
    mov  [ecx], edx
    ret  4
  }
}

DWORD res, ovf;
res = (128, 2987, &ovf);
if(ovf) PASBON;
On gagne surtout la gestion d'erreur qui ruinerait toute performance.

Commentaire de BruNews le 13/12/2006 02:10:17 administrateur CS

bien entendu il faut lire:
res = bnMult(128, 2987, &ovf);

Commentaire de yann_lo_san le 13/12/2006 16:12:17

BruNews >> vu !
(De l'asm bien formé...)

Commentaire de otodidact le 13/12/2006 23:21:05

J'avoue, j'ai eu du mal à tout comprendre. Après une relecture encore plus concentrée, car plus intéressée, j'ai tout pigé (ou presque, je me penche sur l'ASM dès que possible).

Effectivement la validation des valeurs entrées est absente mais présente dans le code original... mais surement pas de cette manière !!! ;)... question de niveau.

Ensuite accéder aux registres, j'en ignorais la faisabilité en C... question de niveau aussi !!! :)

Merci à vous. Mais qui est TIGCC, AMANOBUO ?!

Sinon j'ai pour but de l'intégrer dans une beeeellle interface graphique avec wxDevCpp, mais n'importe quel sample fournit avec wxwidget ne compile pas. Donc,... Au secours !

Commentaire de pulpfrissons le 04/04/2008 01:43:34

Bonjour,

Une modeste contribution à cette source.
Sur un plan informatique, je n'ai rien à dire... parce que je ne suis pas vraiment à la hauteur des intervenants et puis parce que cela me semble très correct.
Sur un plan mathématique en revanche, je me permets de souligner un gros risque signalé par l'auteur d'ailleurs. Essayez de calculer la factorielle de 125 par exemple : vous serez déçus ! Imaginez le résultat : 1 * 2 * 3 * 4 * 5 etc *125
Peu d'ordinateurs sont capables de calculer un tel chiffre. Et ce n'est pas nécessaire !!! Vous avez tout simplement oublié les logarithmes ! Vous vous souvenez ? Le log népérien ? e ? C'est drôlement pratique quand on doit manipuler des chiffres très importants ou au contraire très faibles !
Je vous livre le code suivant (VB, désolé) mais vous ignorerez l'aspect informatique pour vous concentrer sur les maths.

dProb = exp(-moyenne)
dLogProb = -moyenne
dLogProb = dLogProb + ln(moyenne) - log(x)

Quelques explications, en bon français sont sans doute nécessaires !
Je vais prendre un exemple concret, histoire de ne pas perdre trop de monde en route.
Imaginons que l'ampoule de votre voiture tombe en panne en moyenne 3 fois dans l'année. Dans l'exemple, 3 sera la moyenne affecté à la variable appelée moyenne.
Maintenant, si vous voulez savoir quelle est la probabilité qu'il n'y ait que 2 pannes (parce que vous n'avez que deux ampoules), vous affectez la valeur 2 à la variable x.
Le code ci-dessus retournera la probabilité en appliquant la loi de Poisson.
Attention :
1 - il s'agit de la probabilité individuelle, pas de la probabilité cumulée. Si vous avez besoin de la proba cumulée, vous n'avez qu'à faire des boucles.
2 - le code ne fonctionne évidemment pas pour x = 0

Pour info, sous réserve d'erreur de frappe, ce code fonctionne depuis des années dans un logiciel de calcul de rechanges (entre autres). Vous pouvez donc y aller, c'est du bon !
Vos commentaires sont les bienvenus !

Pascal WOHMANN

Commentaire de pulpfrissons le 04/04/2008 01:45:25

A vouloir être trop succint, j'ai commis une petite erreur puisqu'il faut réaliser une boucle...
Qui peut le plus, peut le moins, je vous invite donc à consulter ma contribution dans la zone VB où je donne le code complet de la fonction :
http://www.vbfrance.com/codes/LOI-POISSON_46282.aspx
Encore désolé pour cette coquille...

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Nombre aléatoire suivant une loi de probabilité définie [ par bubbless ] Bonjour &#224; tous !Je cherche actuellement &#224; g&#233;n&#233;rer des nombres al&#233;atoires suivant une loi pr&#233;d&#233;finie (en l'occurence probabilité [ par anikashow ] Bonjour, j ai trouver des difficultés pour ecrire un programme ou une fonction en c/c++ qui permet de remplir la table de la loi normale centrée redu la loi binomialpar la loi poisson [ par abdelkader1952 ] bonjour l approximation d une loi binomial par la loi poisson et normal mercilabed combinaison aléatoire [ par yopcoo ] Bonjour à tous, j'ai  un travail à faire pour l'école et je cherche à créer une fonction. Cette dernière doit pouvoir générer un vecteur de par exempl Combinaison de types managés/non managés non valide [ par TreCool0 ] Bonjour,Je travaille actuellement sur un projet en Visual C++ avec des WindowsForm sous Visual C++ 2008 Express. J'ai crée une DLL, avec un fichier de Détecter une combinaison de touches sur windows comme ctrl+alt+supp [ par ZMJUVENTINO ] Salut,je travaille avec les MFC sur VC++ et je veux détecter ,à partir de mon application ,une combinaison de touches clavier sur windows à n'importe Loi de newton. [ par ralekely ] Bonjour à tous!Je souhaite resoudre un problème, qui je dois avouer, est plus un problème physique qu'un problème de code.Voilà: Je souhaite modeliser [CS]BUG DANS LE SONDAGE [ par lectpe ] Bonjour, je veux juste signaler aux administrateurs de CodesSources que leur sondage sur la loi hadopi doit avoir un problème :à l'instant où j'écris


Nos sponsors


Sondage...

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,109 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales