Grelet Jacques
/
Ni-MH_V3
example code using statis library for temperature measurement with LM35 and LM335
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; } }