00001 /****************************************************************************** 00002 * __ _ _ _ _ _ _____ * 00003 * | \ / | | | | | | | | | | ___| * 00004 * | \/ | | | | | | | | | | |_ * 00005 * | | | | | | | | | | | _| * 00006 * | |\/| | | | | |__ | |__ | | | |__ * 00007 * |_| |_| |_| |____| |____| |_| |____| * 00008 * __________________________________________________________________________ * 00009 * Multifunctional Library For Image Processing * 00010 * * 00011 * * 00012 * * 00013 * (c) Copyright 2007 by Humbert Florent * 00014 * * 00015 * This program is free software; you can redistribute it and/or modify * 00016 * it under the terms of the GNU General Public License as published by * 00017 * the Free Software Foundation; only version 2 of the License. * 00018 * * 00019 * This program is distributed in the hope that it will be useful, * 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00022 * GNU General Public License for more details. * 00023 * * 00024 * You should have received a copy of the GNU General Public License * 00025 * along with this program; if not, write to the Free Software * 00026 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 00027 * 02111-1307, USA. * 00028 ******************************************************************************/ 00029 00032 #include "GaussianRandomizer.hpp" 00033 00034 #include <ctime> 00035 #include <cstdlib> 00036 #include <cmath> 00037 00038 using namespace Millie; 00039 00040 GaussianRandomizer::GaussianRandomizer(float sigma, float mean) 00041 { 00042 if(sigma<0) 00043 throw Millie::IllegalArgument("GaussianRandomizer"); 00044 00045 _sigma = sigma; 00046 _mean = mean; 00047 _haveNextGaussian = false; 00048 _nextGaussian = 0.0f; 00049 } 00050 00051 00052 float GaussianRandomizer::get() 00053 { 00054 /* 00055 * Le code est inspiré du code source Java de la classe Random 00056 */ 00057 00058 if (_haveNextGaussian) 00059 { 00060 _haveNextGaussian = false; 00061 return _nextGaussian; 00062 } 00063 else 00064 { 00065 float v1, v2, s; 00066 do 00067 { 00068 v1 = 2 * (rand()/(RAND_MAX+1.0f)) - 1; /*entre -1 et 1*/ 00069 v2 = 2 * (rand()/(RAND_MAX+1.0f)) - 1; /*entre -1 et 1*/ 00070 s = v1 * v1 + v2 * v2; 00071 } 00072 while (s >= 1 || s == 0); 00073 float multiplier = sqrt(-2 * log(s)/s); 00074 _nextGaussian = v2 * multiplier * _sigma + _mean; 00075 _haveNextGaussian = true; 00076 return v1 * multiplier * _sigma + _mean; 00077 } 00078 } 00079 00080 // float u1 = rand()/(RAND_MAX+1.0f); /*u1>0 et <1 strictement*/ 00081 // float u2 = rand()/(RAND_MAX+1.0f); 00082 00083 /*box muller*/ 00084 //return (sqrt(-2.0f * log(u1)) * cos( 2.0f * M_PI * u2) * _sigma + _mean); 00085 00086