note 53600 modified in function.rand by danbrown
| From: | danbrown@php.net | Date: | Wed, 05 Nov 2008 15:38:12 +0000 |
| Subject: | note 53600 modified in function.rand by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-146172@lists.php.net to get a copy of this message | ||
Lately I needed some random numbers with a gaussian (normal) distribution, not evenly distributed as
the numbers generated by rand(). After googling a while, I found out that there is no perfect
algrorithm that creates such numbers out of evenly distruted random numbers but a few methods that
have similar effect. The following function implements all three algorithms I found- The the last
two methods create numbers where you can find a lower and upper boundary and the first one will
create a number from time to time (such as one in every 10000) that may be very far from the average
value. Have fun testing and using it.
<?php
function gauss($algorithm = "polar") {
$randmax = 9999;
switch($algorithm) {
//polar-methode by marsaglia
case "polar":
$v = 2;
while ($v > 1) {
$u1 = rand(0, $randmax) / $randmax;
$u2 = rand(0, $randmax) / $randmax;
$v = (2 * $u1 - 1) * (2 * $u1 - 1) + (2 * $u2 - 1) * (2 * $u2 - 1);
}
return (2* $u1 - 1) * (( -2 * log($v) / $v) ^ 0.5);
// box-muller-method
case "boxmuller":
do {
$u1 = rand(0, $randmax) / $randmax;
$u2 = rand(0, $randmax) / $randmax;
$x = sqrt(-2 * log($u1)) * cos(2 * pi() * $u2);
} while (strval($x) == "1.#INF" or strval($x) == "-1.#INF");
// the check has to be done cause sometimes (1:10000)
// values such as "1.#INF" occur and i dont know why
return $x;
// twelve random numbers
case "zwoelfer":
$sum = 0;
for ($i = 0; $i < 12; $i++) {
$sum += rand(0, $randmax) / $randmax;
}
return $sum;
}
}
?>
--was--
Lately I needed some random numbers with a gaussian (normal) distribution, not evenly distributed as
the numbers generated by rand(). After googling a while, I found out that there is no perfect
algrorithm that creates such numbers out of evenly distruted random numbers but a few methods that
have similar effect. The following function implements all three algorithms I found- The the last
two methods create numbers where you can find a lower and upper boundary and the first one will
create a number from time to time (such as one in every 10000) that may be very far from the average
value. Have fun testing and using it.
function gauss($algorithm = "polar") {
$randmax = 9999;
switch($algorithm) {
//polar-methode by marsaglia
case "polar":
$v = 2;
while ($v > 1) {
$u1 = rand(0, $randmax) / $randmax;
$u2 = rand(0, $randmax) / $randmax;
$v = (2 * $u1 - 1) * (2 * $u1 - 1) + (2 * $u2 - 1) * (2 * $u2 - 1);
}
return (2* $u1 - 1) * (( -2 * log($v) / $v) ^ 0.5);
// box-muller-method
case "boxmuller":
do {
$u1 = rand(0, $randmax) / $randmax;
$u2 = rand(0, $randmax) / $randmax;
$x = sqrt(-2 * log($u1)) * cos(2 * pi() * $u2);
} while (strval($x) == "1.#INF" or strval($x) == "-1.#INF");
// the check has to be done cause sometimes (1:10000)
// values such as "1.#INF" occur and i dont know why
return $x;
// twelve random numbers
case "zwoelfer":
$sum = 0;
for ($i = 0; $i < 12; $i++) {
$sum += rand(0, $randmax) / $randmax;
}
return $sum;
}
}
http://php.net/manual/en/function.rand.php