Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00015 final class MathUtils extends StaticFactory
00016 {
00020 public static function fisherYatesShuffle(&$elts)
00021 {
00022 $num = count($elts);
00023
00024 for ($i = $num - 1; $i > 0; --$i) {
00025 $j = mt_rand(0, $i);
00026
00027 $tmp = $elts[$i];
00028 $elts[$i] = $elts[$j];
00029 $elts[$j] = $tmp;
00030 }
00031 }
00032
00033 public static function makeCartesianProduct(
00034 $arrays, $generateHash = false
00035 )
00036 {
00037 $result = array();
00038
00039 $size = (sizeof($arrays) > 0) ? 1 : 0;
00040
00041 foreach ($arrays as $array)
00042 $size *= sizeof($array);
00043
00044 $keys = array_keys($arrays);
00045
00046 foreach ($keys as $key)
00047 $tmpArrays[] = $arrays[$key];
00048
00049 for ($i = 0; $i < $size; $i++) {
00050 $result[$i] = array();
00051
00052 for ($j = 0; $j < sizeof($tmpArrays); $j++) {
00053 $result[$i][$keys[$j]] = current($tmpArrays[$j]);
00054 }
00055
00056 if ($generateHash)
00057 $result[$i]['hash'] = md5(implode('_', $result[$i]));
00058
00059 for ($j = (sizeof($tmpArrays) - 1); $j >= 0; $j--) {
00060 if (next($tmpArrays[$j])) {
00061 break;
00062 } else
00063 reset($tmpArrays[$j]);
00064 }
00065 }
00066
00067 return $result;
00068 }
00069
00070 public static function applyFunctorToCartesianProduct(
00071 $arrays, TupleFunctor $functor
00072 )
00073 {
00074 $result = array();
00075
00076 $size = (sizeof($arrays) > 0) ? 1 : 0;
00077
00078 foreach ($arrays as $array)
00079 $size *= sizeof($array);
00080
00081 $keys = array_keys($arrays);
00082
00083 foreach ($keys as $key)
00084 $tmpArrays[] = $arrays[$key];
00085
00086 for ($i = 0; $i < $size; $i++) {
00087 $result[$i] = array();
00088
00089 for ($j = 0; $j < sizeof($tmpArrays); $j++) {
00090 $result[$i][$keys[$j]] = current($tmpArrays[$j]);
00091 }
00092
00093 $functor->apply($result[$i]);
00094
00095 unset($result[$i]);
00096
00097 for ($j = (sizeof($tmpArrays) - 1); $j >= 0; $j--) {
00098 if (next($tmpArrays[$j])) {
00099 break;
00100 } else
00101 reset($tmpArrays[$j]);
00102 }
00103 }
00104 }
00105
00106 public static function randFloat($min, $max)
00107 {
00108 return ($min + lcg_value() * (abs($max - $min)));
00109 }
00110
00111 public static function alignByBase($value, $base, $ceil = false)
00112 {
00113 $function = $ceil ? 'ceil' : 'floor';
00114
00115 return $function($value / $base) * $base;
00116 }
00117
00123 public static function randomNormalStd()
00124 {
00125 do {
00126 $x = rand() / getrandmax() * 2 - 1;
00127 $y = rand() / getrandmax() * 2 - 1;
00128
00129 $r = ($x * $x) + ($y * $y);
00130
00131 } while (($r > 1) || ($x + $y == 0));
00132
00133 $z = $x * sqrt(-2 * log($r) / $r);
00134
00135 return $z;
00136 }
00137
00138 public static function getStandardDeviation(array $list)
00139 {
00140 return self::getStandardDeviationP($list, count($list) - 1);
00141 }
00142
00143 public static function getStandardDeviationP(array $list, $size = null)
00144 {
00145 $tempSum = 0;
00146
00147 if (!$size)
00148 $size = count($list);
00149
00150 Assert::isPositiveInteger($size);
00151
00152 $averageValue = self::getAverage($list, $size);
00153
00154 for ($i = 0; $i < $size; $i++)
00155 $tempSum += pow($list[$i] - $averageValue, 2);
00156
00157 return sqrt($tempSum / $size);
00158 }
00159
00160 public static function getAbsoluteDeviation(array $list)
00161 {
00162 $value = 0;
00163
00164 $averageValue = self::getAverage($list);
00165
00166 foreach ($list as $elt)
00167 $value += abs($elt - $averageValue);
00168
00169 return $value / count($list);
00170 }
00171
00172 public static function getMeanDeviation($elt, $averageValue)
00173 {
00174 return $elt - $averageValue;
00175 }
00176
00177 public static function getAverage(array $list, $size = null)
00178 {
00179 if (!$size)
00180 $size = count($list);
00181
00182 Assert::isPositiveInteger($size);
00183
00184 $tempSum = 0;
00185
00186 for ($i = 0; $i < $size; $i++)
00187 $tempSum += $list[$i];
00188
00189 return $tempSum / $size;
00190 }
00191
00192 public static function getCovariance(array $list1, array $list2)
00193 {
00194 $list1Size = count($list1);
00195 $list2Size = count($list2);
00196
00197 Assert::isEqual($list1Size, $list2Size, 'Array sizes should be equals!');
00198
00199 $list1AverageValue = self::getAverage($list1);
00200 $list2AverageValue = self::getAverage($list2);
00201
00202 $tempSum = 0;
00203
00204 for ($i = 0; $i < $list1Size; $i++) {
00205 $elt1Dev = self::getMeanDeviation($list1[$i], $list1AverageValue);
00206 $elt2Dev = self::getMeanDeviation($list2[$i], $list2AverageValue);
00207
00208 $tempSum += $elt1Dev * $elt2Dev;
00209 }
00210
00211 return $tempSum / ($list1Size - 1);
00212 }
00213
00214 public static function getPearsonProductMomentCorrelation(array $list1, array $list2)
00215 {
00216 return
00217 self::getCovariance($list1, $list2)
00218 / (
00219 self::getStandardDeviation($list1)
00220 * self::getStandardDeviation($list2)
00221 );
00222 }
00223
00224 public static function getMmult(array $list1, array $list2)
00225 {
00226 $list1Size = count($list1);
00227 $list2Size = count($list2);
00228
00229 $result = array();
00230
00231 for ($i = 0; $i < $list1Size; $i++) {
00232 for ($j = 0; $j < $list2Size; $j++) {
00233 $x = 0;
00234
00235 for ($k = 0; $k < $list2Size; $k++) {
00236 if (isset($list1[$i][$k]))
00237 $l1 = $list1[$i][$k];
00238 else
00239 $l1 = 0;
00240
00241 if (isset($list2[$k][$j]))
00242 $l2 = $list2[$k][$j];
00243 else
00244 $l2 = 0;
00245
00246 $x += $l1 * $l2;
00247 }
00248
00249 $result[$i][$j] = $x;
00250 }
00251 }
00252
00253 return $result;
00254 }
00255 }
00256 ?>