robomath.c

00001 /*
00002  * @(#)robomath.c       07/08/13
00003  * 
00004  * Description  : useful matemathic functions.
00005  *
00006  * Copyright    : (c) 2007 DCE Eurobot Dragon Team
00007  *                CTU FEE - Department of Control Engineering
00008  * License      : GNU GPL v.2
00009  */
00010 
00011 #include <stdlib.h>
00012 #include <math.h>
00013 #include "robomath.h"
00014 
00018 /* Random function with Gaussian Probability Distribution */
00019 double gaussrand()
00020 {
00021         static double V2, fac;
00022         static int phase = 0;
00023         double S, Z, U1, U2, V1;
00024         
00025         if (phase)
00026                 Z = V2 * fac;
00027         else {
00028                 do {
00029                         U1 = drand48();
00030                         U2 = drand48();
00031                         
00032                         V1 = 2 * U1 - 1;
00033                         V2 = 2 * U2 - 1;
00034                         S = V1 * V1 + V2 * V2;
00035                 } while(S >= 1);
00036                 
00037                 fac = sqrt (-2 * log(S) / S);
00038                 Z = V1 * fac;
00039         }
00040         phase = 1 - phase;
00041         
00042         return Z;
00043 }
00044 
00045 /* Uniform random */
00046 float urand()
00047 {
00048         return ((float)rand()/RAND_MAX);
00049 }
00050 
00051 /* Another random function with Gaussian Probability Distribution. This 
00052  * Gaussian routine is stolen from Numerical Recipes and is their 
00053  * copyright. */
00054 double gaussian_random(void)
00055 {
00056         static int next_gaussian = 0;
00057         static double saved_gaussian_value;
00058         double fac, rsq, v1, v2;
00059         
00060         if (next_gaussian == 0) {
00061                 do {
00062                         v1 = 2.0*urand()-1.0;
00063                         v2 = 2.0*urand()-1.0;
00064                         rsq = v1*v1+v2*v2;
00065                 } while (rsq >= 1.0 || rsq == 0.0);
00066                 fac = sqrt(-2.0*log(rsq)/rsq);
00067                 saved_gaussian_value = v1*fac;
00068                 next_gaussian = 1;
00069                 return (v2*fac);
00070         } else {
00071                 next_gaussian = 0;
00072                 return saved_gaussian_value;
00073         }
00074 }
00075 
00082 double evaluate_gaussian(double val, double sigma)
00083 {
00084         return (1.0/(sqrt(2.0*M_PI) * sigma) *
00085                 exp(-0.5 * (val*val / (sigma*sigma))));
00086 }
00087 
00088 /* Random generator with exponential distribution */
00089 float exprand(float lambda)
00090 {
00091         float u,x;
00092         
00093         u = urand();
00094         x = (-1/lambda)*log(u);
00095         
00096         return(x);
00097 }
00098 
00099 /* Using to test random functions */
00100 int testrand(int n)
00101 {
00102         float lambda = 2.0;
00103         int i;
00104         
00105         printf("\n==============================\n");
00106         printf("gaussrand():\n");
00107         for (i=0; i<n; i++)
00108                 printf("%f ", gaussrand());
00109 
00110         printf("\n==============================\n");
00111         printf("gaussian_rand():\n");
00112         for (i=0; i<n; i++)
00113                 printf("%f ", gaussrand());
00114 
00115         printf("\n==============================\n");
00116         printf("exprand():\n");
00117         for (i=0; i<n; i++)
00118                 printf(" %2.4f ", exprand(lambda));
00119         
00120         return 0;
00121 }

Generated on Thu Sep 13 11:28:28 2007 for DCE-Eurobot by  doxygen 1.5.3