example code using statis library for temperature measurement with LM35 and LM335

Dependencies:   mbed statis

Revision:
3:0e06300940cd
Child:
4:ffc39af07ade
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/statis.cpp	Thu Nov 22 14:47:20 2012 +0000
@@ -0,0 +1,272 @@
+/*****************************************************************************
+ * Statis.c                                                                  *
+ *                                                                           *
+ *    Module de calcul statistique utilisees par le logiciel THERMO          *
+ *       Ce module dans la version 1.0 calcule : la mediane                  *
+ *                                               la moyenne                  *
+ *                                               l'ecart type                *
+ *    Les fonctions prennent toutes comme argumemts un tableau FAR list[]    *
+ *    et les n_elem sur lequel est realise le calcul.                        *
+ *                                                                           *
+ *                      Jacques Grelet      Mars 1992                        *
+ *                      Bruno Buisson       Aout 92                          *
+ *                                          Septembre 1992                   *
+ *                                          Septembre 1994                   *
+ *****************************************************************************/
+#define DEBUG
+#undef DEBUG
+
+#include <debug.h>
+#include <sys.h>
+#include <math.h>
+#include <stdlib.h>             // cf. qsort(),fabs()
+
+// ring
+#include <ring.h>     // cf. statis.h
+
+// statis
+#include <bitmsk.h>     // cf. statis.h
+#define _STATIS
+#include <statis.h>
+#undef  _STATIS
+
+/*****************************************************************************
+ * classe Mediane_item                                                       *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *****************************************************************************/
+procedure Mediane_item::raz( void )
+{
+ valeur = FLOAT_ERREUR;
+ indice = 0;
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+Mediane_item::Mediane_item( void )
+{
+ raz();
+}
+
+/*****************************************************************************
+ * fonction utilitaire de qsort(),donc pas membre de classe                  *
+ * si a < b retourne -1                                                      *
+ * si a = b           0                                                      *
+ * si a > b           1                                                      *
+ *****************************************************************************/
+static int compare( const void *a,const void *b )
+{
+ register double c = ((Mediane_item *)a)->valeur - ((Mediane_item *)b)->valeur;
+
+ return( ( c == 0.0 ) ? 0 : ( ( c > 0.0 ) ? 1 : -1 ) );
+}
+
+/*****************************************************************************
+ * classe Mediane                                                            *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * n_elem est forcement impair (protege par Statis_data::mediane())          *
+ *****************************************************************************/
+Mediane_item &Mediane::mediane( Mediane_item list[],int n_elem )
+{
+ switch( n_elem ) {
+   case  1 : return( list[ 0 ] );
+   default : qsort( (Mediane_item *)list,n_elem,sizeof( list[ 0 ] ),compare );
+             return( list[ ( n_elem - 1 ) / 2 ] );
+ }
+}
+
+/*****************************************************************************
+ * classe Mediane_circ                                                       *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * n_elem est forcement impair (protege par Statis_data::mediane())          *
+ *****************************************************************************/
+Mediane_item &Mediane_circ::mediane( Mediane_item list[],int n_elem )
+{
+ int           delta_nord,
+               delta_sud,
+               borne_25,
+               borne_75;
+ Mediane_item *result;
+
+ if( n_elem == 1 ) return( list[ 0 ] );
+ qsort( (Mediane_item *)list,n_elem,sizeof( list[ 0 ] ),compare );
+ borne_25   =     n_elem / 4;           // 25%
+ borne_75   = 3 * n_elem / 4;           // 75%
+ delta_nord = int( list[ borne_75 ].valeur - list[ borne_25 ].valeur );
+ delta_sud  = abs( delta_nord - (int)(int)maxi );
+ if( delta_sud < delta_nord ) {         // si plus de 50% de valeurs dans
+   for( unsigned i = 0; i < n_elem; i++ )   // le nord, on change de repere
+   if( list[ i ].valeur > moitie && list[ i ].valeur < maxi )   //  180/360
+     list[ i ].valeur -= maxi;                  // -180/180
+   qsort( (Mediane_item *)list,n_elem,sizeof( list[ 0 ] ),compare );
+ }
+ result = &list[ ( n_elem - 1 ) / 2 ];
+ if( result->valeur < 0 ) result->valeur += maxi;
+ return( *result );
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+Mediane_circ::Mediane_circ( double a_maxi )
+{
+ moitie = ( maxi = fabs( a_maxi ) ) / 2;
+}
+
+/*****************************************************************************
+ * classe Statis_data                                                        *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *****************************************************************************/
+booleen Statis_data::verifie( double &val )
+{
+ if( ( borne_inf == borne_sup ) || ( val >= borne_inf && val <= borne_sup ) )
+   return( TRUE );
+ val = FLOAT_ERREUR;
+ return( FALSE );
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+Mediane_item *Statis_data::cons_liste( void )
+{
+ for( unsigned i = 0; i < n_elem; i++ ) {
+   mediane_liste[ i ].indice = i;
+   mediane_liste[ i ].valeur = ring.list[ i ];
+ }
+ return( mediane_liste );
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+booleen Statis_data::mediane( void )
+{
+ if( !mediane_methode || n_elem == 0 ) {
+   med.raz();
+   return( FALSE );
+ }
+ med = mediane_methode->mediane( cons_liste(),
+                                 ( n_elem % 2 == 0 ) ? n_elem - 1 : n_elem );
+ return( verifie( med.valeur ) );
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+booleen Statis_data::moyenne( void )
+{
+ if( n_elem == 0 ) {
+   moy = FLOAT_ERREUR;
+   return( FALSE );
+ }
+ moy = 0;
+ for( unsigned i = 0; i < n_elem; moy += ring.list[ i++ ] );
+ moy /= (double) n_elem;
+ return( verifie( moy ) );
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+booleen Statis_data::ecart_type( void )
+{
+ double      somme_xi_carre = 0.0,
+             somme_xi       = 0.0,
+             x_bar          = 0.0;
+ double *ptxi;
+ unsigned    i;
+
+ switch( n_elem ) {
+   case  0 :
+   case  1 :
+   case  2 : ecart = FLOAT_ERREUR;
+             return( FALSE );
+   default : for( i = 0,ptxi = ring.list; i < n_elem;
+                  i++,ptxi++ ) {
+               somme_xi       += *ptxi;
+               somme_xi_carre += *ptxi * *ptxi;
+             }
+             x_bar = somme_xi / (double) n_elem;
+             ecart = sqrt( fabs( somme_xi_carre / (double) n_elem -
+                                 x_bar * x_bar                      ) );
+             return( TRUE );
+ }
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+procedure Statis_data::calcule( void )
+{
+ DPRINTF( ("Statis::calcule:stat_on=%u,calculs=%x\n",stat_on,calculs) );
+ if( stat_on ) {
+   n_elem = ring.store();
+   DPRINTF( ("n_elem=%u.",n_elem) );
+   if( calculs & STAT_MED     ) mediane();
+   if( calculs & STAT_MOYENNE ) {
+     moyenne();
+     if( calculs & STAT_ECART_TYPE ) ecart_type();
+   }
+ }
+ else {
+   ecart      = 0;
+   moy        =
+   med.valeur = ( n_elem > 0 ) ? instant : FLOAT_ERREUR;
+   med.indice = 0;
+ }
+ DPRINTF( ("med=%5.4g,moy=%5.4g,instant=%5.4g\n",
+           med.valeur,moy,instant) );
+ n_elem = 0;
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+double Statis_data::put( double val )
+{
+ instant = val;
+ if( stat_on ) ring.put( instant );
+ else          n_elem = 1;
+ return( instant );
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+Statis_data::Statis_data( BITMSK calc,unsigned taille,
+                          double b_inf /*= 0*/,double b_sup /*= 0*/ )
+           : ring(        taille ),
+             med()
+{      
+ moy             =
+ ecart           =
+ instant         = FLOAT_ERREUR;
+ borne_inf       = b_inf;
+ borne_sup       = b_sup;
+ n_elem          = 0;
+ if( stat_on = ( taille > 1 ) ) {
+//   init_ring_d( &ring,taille );
+   if( mediane_methode = ( ( calculs = calc ) & STAT_MED_NORM )
+                         ? new Mediane
+                         : ( calc & STAT_MED_CIRC ) ? new Mediane_circ( b_sup )
+                                                    : NULL )
+     mediane_liste = new Mediane_item[ taille ];
+   else
+     mediane_liste = NULL;
+ }
+ else {
+   mediane_methode = NULL;
+   mediane_liste   = NULL;
+ }
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+Statis_data::~Statis_data()
+{
+ if( stat_on ) {
+//   term_ring_d( &ring );
+   if( mediane_methode ) delete mediane_methode;
+   if( mediane_liste   ) delete [] mediane_liste;
+ }
+}