🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: es.comp.os.linux.programacion
Article #6648

Re: rand con distribución normal

#6648
From: J.A. Gutierrez
Date: Mon, 02 Jun 2003 17:08
120 lines
3627 bytes
Siew <siew@mx4.redestb.es> wrote:
: Hola a todos,
: �existe alg�n m�todo entre las librer�as de C incluidas en Linux que 
: permita obtener n�mero aleatorios, como el m�todo rand(), pero siguiendo 
: una distribuci�n normal? En el caso de que no existiera, �d�nde podr�a 
: encontrar informaci�n sobre como programarla?

/*
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <math.h>

#define	sqr(a)	((a)*(a))
double f ( double x, double m, double s2 );

double	coso[1024];

int main( int argc, char *argv[] )
{
	int		i, n;
	double	s2, m, x, sum, med;
	struct timeval  tp;
	int plot;


	m = (double) atof( argv[1] );
	s2 = (double) atof( argv[2] );
	n = (int) atoi( argv[3] );
	plot = (int) atoi( argv[4] );

#if defined _POSIX_VERSION || defined _HPUX_SOURCE
	gettimeofday(&tp, NULL);
#else
	gettimeofday(&tp);
#endif

	srand48((long)tp.tv_usec);
	for( i = 0; (i<n) && (i<sizeof(coso)/sizeof(double)); )
	{
		x = (drand48() -0.5) *  1000.0;
		if ( drand48() < f(x, m, s2) )
			coso[i++] = x;
	}
	n = i;

	for( sum = 0, i=0; i<n ; i++ )
		sum += coso[i];
	med = sum / (double)n;

	if (plot)
	{
		for( i=0; i<n ; i++ )
			printf("%d %g\n",i, coso[i]);
	}

	fprintf( stderr, "m: %g\t", med);

	for( sum = 0.0, i=0; i<n ; i++ )
		sum += sqr (coso[i] - med);

	fprintf( stderr, "s: %g %d\n", sum / (double) n, n);
	
	return 0;
}

/**************************************************************************/

/*                            (x - m)^2
 *              1          - -----------
 * f(x) = -------------- e     2 s2
 *        s (2 M_PI)^0.5
 */
double f ( double x, double m, double s2 )
{
	x -= m;
	x *= x;
	x /= (2.0 * s2);
	x = exp(-x) / sqrt( 2.0 * M_PI * s2 );
	return x;
}

/*
 *    / x
 *    |       f(t)     dt
 *   / -inf       0,1
 */
double F ( double x )
{
	double t;

	t = 1.0 / (1 + 0.2316419 * x);

	return(
		1 - f(x, 0.0, 1.0) * (
		(((
		    1.330274429 * t
		  - 1.821255978) *
		t + 1.78147937) *
		t - 0.356563782) *
		t + 0.31938153) * t
		);
}

double u ( double x, double min, double max )
{
	if (( x <= min ) || ( x >= max )) return 0;
	else
		return ( 1 / ( max - min ) );
}

-- 
PGP and other useless info at      \
http://www.cps.unizar.es/~spd/      \
finger://daphne.cps.unizar.es/spd    \       Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/          \                         (Virgilio)   
Technical Details
Message-ID: <bbg0ar$oqr$1@news.unizar.es>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!xmission!news-out.spamkiller.net!propagator2-maxim!news-in.spamkiller.net!newsf01.ono.com!bashful.rediris.es!news.unizar.es!not-for-mail
References: <bbagm4$74dct$1@ID-97854.news.dfncis.de>

Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII
X-Google-Thread: f86c8,e99d2124789f3a80
X-Google-Attributes: gidf86c8,public
X-Google-ArrivalTime: 2003-06-02 10:08:25 PST
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!xmission!news-out.spamkiller.net!propagator2-maxim!news-in.spamkiller.net!newsf01.ono.com!bashful.rediris.es!news.unizar.es!not-for-mail
From: "J.A. Gutierrez" <spd@daphne.cps.unizar.es>
Newsgroups: es.comp.os.linux.programacion
Subject: Re: rand con distribución normal
Date: 2 Jun 2003 17:08:43 GMT
Organization: Rank
Lines: 120
Message-ID: <bbg0ar$oqr$1@news.unizar.es>
References: <bbagm4$74dct$1@ID-97854.news.dfncis.de>
NNTP-Posting-Host: daphne.cps.unizar.es
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: news.unizar.es 1054573723 25435 155.210.152.20 (2 Jun 2003 17:08:43 GMT)
X-Complaints-To: usenet@news.unizar.es
NNTP-Posting-Date: 2 Jun 2003 17:08:43 GMT
User-Agent: tin/1.4.7-20030322 ("Suggestions") (UNIX) (IRIX/6.2 (IP22))