# MathUtils.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2009 by Denis M. Gabaidulin                             *
    00004  *                                                                         *
    00005  *   This program is free software; you can redistribute it and/or modify  *
    00006  *   it under the terms of the GNU Lesser General Public License as        *
    00007  *   published by the Free Software Foundation; either version 3 of the    *
    00008  *   License, or (at your option) any later version.                       *
    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 ?>