Listing 1 Generates the data profiles of Figure 3 through Figure 8
/* ALPHABET.C Demonstrate the alpha-beta filter with a particular data profile, with and without gaussian noise, and with different alpha-beta values. The graphic features here assume the presence of a VGA monitor. This code was written for Borland C++, Version 3.1, coded for MS-DOS. */ #include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <alloc.h> #include <time.h> #include <math.h> #define PLOT1 120 /* range of x for first part of plot */ #define PLOT2 310 /* range of x for second part of plot */ #define PLOT3 430 /* range of x for third part of plot */ #define PLOTEND 640 /* end of x range */ #define STEADY_STATE1 120.0 /* first steady state y value */ #define STEADY_STATE2 400.0 /* second steady state y value */ #define STEADY_STATE3 70.0 /* third steady state y value */ #define STEADY_STATEBOT 480.0 /* bottom limit for steady state values */ #define ALPHA 0.25 /* arbitrary alpha value */ void alpha_beta(double *y,double *y_smoothed, double alpha,double beta); void profile(double *y); void gauss_noise(double *noise); void plot_it(double *y); void message(char *string1,char *string2, char *string3); void main(void) { int x,graphdriver=DETECT,graphmode,errorcode; double *y_pure,*y_noisy,*y_smoothed,*noise; double alpha,beta; /**********************************/ /* allocate memory for the arrays */ /**********************************/ if((y_pure = (double *)malloc(PLOTEND*sizeof(double)))== NULL) { printf("\a"); cprintf("Unable to allocate space for array "); cprintf("y_pure[]\n\r"); exit(1); } if((y_noisy = (double *)malloc(PLOTEND*sizeof(double)))== NULL) { printf("\a"); cprintf("Unable to allocate space for array "); cprintf("y_noisy[]\n\r"); exit(1); } if((y_smoothed = (double *)malloc(PLOTEND*sizeof(double)))== NULL) { printf("\a"); cprintf("Unable to allocate space for array "); cprintf("y_smoothed[]\n\r"); exit(1); } if((noise = (double *)malloc(PLOTEND*sizeof(double)))==NULL) { printf("\a"); cprintf("Unable to allocate space for array "); cprintf("noise[]\n\r"); exit(1); } /****************************/ /* initialize graphics mode */ /****************************/ registerbgidriver(EGAVGA_driver); initgraph(&graphdriver,&graphmode,""); errorcode=graphresult(); if(errorcode != grOk) { printf("\a"); cprintf("Graphics error: %s\n\r", grapherrormsg(errorcode)); exit(1); } /*************************************************/ /* generate the pure and corrupted data profiles */ /*************************************************/ /* generate the clean profile */ profile(y_pure); /* generate the noise */ gauss_noise(noise); /* corrupt the clean data with noise */ for(x=0;x<PLOTEND;++x) y_noisy[x] = y_pure[x] + noise[x]; /****************************************/ /* plot a pure profile with underdamped */ /* alpha-beta smoothing */ /****************************************/ /* plot the clean profile */ message("Clean data profile","",""); plot_it(y_pure); /* compute and plot the smoothed result over the clean profile */ alpha = ALPHA; /* arbitrary alpha value */ beta = alpha*alpha / (2.0 - alpha); /* standard, underdamped beta value */ alpha_beta(y_pure,y_smoothed,alpha,beta); message("","with", "Underdamped alpha-beta smoothing"); plot_it(y_smoothed); /* clear the screen and replot the smoothed result */ cleardevice(); message("Underdamped alpha-beta smoothing of clean \ profile","",""); plot_it(y_smoothed); /*****************************************/ /* plot a noisy profile with underdamped */ /* alpha-beta smoothing */ /*****************************************/ /* clear the screen and plot the profile */ cleardevice(); message("Noisy profile","",""); plot_it(y_noisy); /* compute and plot the smoothed result over the noisy profile */ alpha_beta(y_noisy,y_smoothed,alpha,beta); message("","with", "Underdamped alpha-beta smoothing"); plot_it(y_smoothed); /* clear the screen and replot the smoothed result */ cleardevice(); message("Underdamped alpha-beta smoothing of noisy \ profile","",""); plot_it(y_smoothed); /* plot the pure profile over the estimate based on the noisy version */ message("","with","Clean data profile"); plot_it(y_pure); /********************************************/ /* plot a pure profile with near-critically */ /* damped alpha-beta smoothing */ /********************************************/ /* clear the screen and plot the clean profile */ cleardevice(); message("Clean data profile","",""); plot_it(y_pure); /* compute and plot the smoothed result over the clean profile */ alpha = ALPHA; /* arbitrary alpha value */ beta = 0.8*(2.0 - alpha*alpha - 2.0*sqrt(1 - alpha*alpha))/(alpha*alpha); alpha_beta(y_pure,y_smoothed,alpha,beta); message("","with","Near-critically damped \ alpha-beta smoothing"); plot_it(y_smoothed); /*********************************************/ /* plot a noisy profile with near-critically */ /* damped alpha-beta smoothing */ /*********************************************/ /* clear the screen and plot the noisy profile */ cleardevice(); message("Noisy profile","",""); plot_it(y_noisy); /* compute and plot the smoothed response over the noisy profile */ beta = 0.8*(2.0 - alpha*alpha - 2.0*sqrt(1 - alpha*alpha))/(alpha*alpha); alpha_beta(y_noisy,y_smoothed,alpha,beta); message("Noisy profile","with", "Near-critically damped alpha-beta \ smoothing"); plot_it(y_smoothed); /* clear the screen and replot the smoothed result */ cleardevice(); message("Near-critically damped alpha-beta \ smoothing of noisy profile","",""); plot_it(y_smoothed); /* plot the pure profile over the estimate based on the noisy version */ message(""," with","Clean data profile"); plot_it(y_pure); /* prepare to exit */ closegraph(); } void alpha_beta(double *y,double *y_smoothed, double alpha,double beta) /* demonstrate the alpha-beta algorithm */ { int i; double s_est,v_est,s_pred,error; /* initialize the filter */ s_est = y[0]; v_est = 0.0; /* loop through all of the position measurements */ for(i=0;i<PLOTEND;++i) { /***********************************/ /* the alpha-beta filter algorithm */ /* (with T absorbed into v) */ /***********************************/ /* predict the new position */ s_pred = s_est + v_est; /* compute the measurement error */ error = y[i] - s_pred; /* estimate the true position and velocity */ s_est = s_pred + alpha*error; v_est = v_est + beta*error; /*****************************/ /* update the smoothed array */ /*****************************/ y_smoothed[i] = s_est; } } void profile(double *y) /* generate the profile to be studied */ { int i; /* first steady-state portion */ for(i=0;i<PLOT1;++i) y[i] = STEADY_STATE1; /* ramp from first steady state level to second steady state level */ for(i=PLOT1;i<PLOT2;++i) y[i] = (i-PLOT1) * (STEADY_STATE2-STEADY_STATE1) / (PLOT2-PLOT1) + STEADY_STATE1; /* second steady-state portion */ for(i-PLOT2;i<PLOT3;++i) y[i] = STEADY_STATE2; /* step to third steady-state portion */ for(i-PLOT3;i<PLOTEND;++i) y[i] = STEADY_STATE3; } void gauss_noise(double *noise) /* generate mean-zero gaussian noise using Box-Muller method */ { int i; double drand1,drand2,pi,sigma=10.0,mean=0.0; /* define pi */ pi = 4.0 * atan(1.0); /* seed the random number generator */ randomize(); /* generate gaussian noise using the Box-Muller method */ for(i=0;i<PLOTEND;++i) { /* compute two double random numbers */ drand1 = (double)rand)()/RAND_MAX; drand2 = (double)rand()/RAND_MAX; /* compute the noise term */ if(drand1 < 1e-10) drand1 = 1e-10; /* avoid division by zero */ noise[i] = sqrt(2.0*log(1.0/drand1)) * cos(2.0 * pi * drand2) * sigma + mean; } } void plot_it(double *y) /* plot one member of array y for each horizontal pixel position */ { int x,y_old; /* plot the profile */ y_old = (int)(y[0]+0.5); for(x=0;x<PLOTEND;++x) { line(x,y_old,x,(int)(y[x]+0.5)); y_old = (int)(y[x]+0.5); } /* wait for key press */ getch(); } void message(char *string1,char *string2, char *string3) /* print a message of three lines centered at bottom of screen */ { int midx,maxy; /* get screen parameters */ midx=getmaxx()/2; maxy=getmaxy(); /* print pieces of message, centered */ settextjustify(CENTER_TEXT,TOP_TEXT); outtextxy(midx,maxy-30,string1); outtextxy(midx,maxy-20,string2); outtextxy(midx,maxy-10,string3); } /* End of File */