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

Dependencies:   mbed statis

statis.cpp

Committer:
greletj
Date:
2012-11-24
Revision:
5:0b3569945178
Parent:
4:ffc39af07ade
Child:
6:95195b0995dd

File content as of revision 5:0b3569945178:

/*****************************************************************************
 * 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
#include "mbed.h"
extern Serial pc;

#undef DEBUG

#include <debug.h>
#include <math.h>
#include <stdlib.h>             // cf. qsort(),fabs()

// ring
#include "include/ring.h"     // cf. statis.h

// statis

#include "include/bitmsk.h"     // cf. statis.h
#define _STATIS
#include "statis.h"
#undef  _STATIS

/*****************************************************************************
 * classe Mediane_item                                                       *
 *****************************************************************************/

/*****************************************************************************
 *****************************************************************************/
void 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 float 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( float a_maxi )
{
 moitie = ( maxi = fabs( a_maxi ) ) / 2;
}

/*****************************************************************************
 * classe Statis_data                                                        *
 *****************************************************************************/

/*****************************************************************************
 *****************************************************************************/
bool Statis_data::verifie( float &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 );
}

/*****************************************************************************
 *****************************************************************************/
bool 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 ) );
}

/*****************************************************************************
 *****************************************************************************/
bool 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 /= (float) n_elem;
 return( verifie( moy ) );
}

/*****************************************************************************
 *****************************************************************************/
bool Statis_data::ecart_type( void )
{
 float      somme_xi_carre = 0.0,
             somme_xi       = 0.0,
             x_bar          = 0.0;
 float *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 / (float) n_elem;
             ecart = sqrt( fabs( somme_xi_carre / (float) n_elem -
                                 x_bar * x_bar                      ) );
             return( true );
 }
}

/*****************************************************************************
 *****************************************************************************/
void Statis_data::calcule( void )
{
 DPRINTF( ("\r\nStatis::calcule:stat_on=%u,calculs=%x\r\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\r\n",
           med.valeur,moy,instant) );
 n_elem = 0;
}

/*****************************************************************************
 *****************************************************************************/
float Statis_data::put( float val )
{
 instant = val;
 if( stat_on ) ring.put( instant );
 else          n_elem = 1;
 return( instant );
}

/*****************************************************************************
 *****************************************************************************/
Statis_data::Statis_data( BITMSK calc,unsigned taille,
                          float b_inf /*= 0*/,float b_sup /*= 0*/ )
           : ring(        taille ),
             med()
{      
 moy             =
 ecart           =
 instant         = FLOAT_ERREUR;
 borne_inf       = b_inf;
 borne_sup       = b_sup;
 n_elem          = 0;
 
 stat_on = taille > 1 ? true : false;
 if( stat_on ) {
//   init_ring_d( &ring,taille );
   mediane_methode = ( ( calculs = calc ) & STAT_MED_NORM )
                         ? new Mediane
                         : ( calc & STAT_MED_CIRC ) ? new Mediane_circ( b_sup )
                                                    : NULL;
   if( mediane_methode )                                                 
     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;
 }
}