<?php
// math.inc.php

// moyenne arithmétique
function array_average($arr) { return array_sum($arr)/count($arr); }
 
// variance
function array_variance($arr) {
         
$sum_Xi_minus_average=0;
         
$average=array_average($arr);
         foreach(
$arr as $elem) {
                
$sum_Xi_minus_average+=pow(($elem-$average),2);
         }
         return 
$variance=$sum_Xi_minus_average/count($arr);
}
// déviation-standard = écart-type
function array_stdev($arr) { return sqrt(array_variance($arr)); }
// idem sous un autre nom de fonction
function array_stddev($arr) { return sqrt(array_variance($arr)); }

 
// quantile
function array_quantile($arr,$quantile) {
         if (
$quantile<|| $quantile>1) die("Error: parameter 'quantile' must be in the interval [0;1]");
         if (!
is_array($arr) || empty($arr)) die("Error:parameter 'arr' must be an array");
         
$a=array_values($arr); // to do not affect the parameter $arr
         
sort($a);              // when sorted !
         
if (count($arr)%2==0) { // odd
                
$index=count($a)*$quantile;
                
$ret=$a[$index];
         } else { 
// par
                
$index_min=floor((count($a))*$quantile);
                
$index_max=ceil((count($a))*$quantile);
                
$ret=($a[$index_min]+$a[$index_max])*$quantile;
         }
         
//Test
         //print $ret;
         
return $ret;
}
// alias de quantile
function array_percentile($arr,$percentile) { return array_quantile($arr,$percentile); }
// below are functions depending on array_quantiles
// remarquable values for array_quantile :
// mediane: 1/2 or 0.5
// third: 1/3 or 0.33333
// quarter: 1/4 or 0.25
// three-quarter: 3/4
function array_mediane($arr) { return array_quantile($arr,1/2); }
function 
array_half($arr) { return array_quantile($arr,1/2); }
function 
array_third($arr) { return array_quantile($arr,1/3); }
function 
array_quartile($arr) { return array_quantile($arr,1/4); }
function 
array_quarter($arr) { return array_quantile($arr,1/4); }
function 
array_three_quarter($arr) { return array_quantile($arr,3/4); }
function 
array_decile($arr) { return array_quantile($arr,1/10); }
function 
array_centile($arr) { return array_quantile($arr,1/100); }
// percentage
function array_percent($arr) {
         if(
0==($sum=array_sum($arr))) return false;
         foreach(
$arr as $key=>$elem) { $a[$key]=$elem/$sum; }
         return 
$a;
}
function 
parity($val) { // parity test returns odd and even
         
if (!is_integer($val)) die("Error : parameter must be an integer");
         return (
$val%2==true false);
// remain ("modulo") of the division of an integer by 2 is 0 or not
// compare an array value to its follower
function array_cmpval($val){ { if (current($val)==next($val)) return true; } return false; }
function 
cmpval($a,$b){
 if (
$a>$b) return 1;
 if (
$a==$b) return 0;
 if (
$a<$b) return -1;
}
// mode : caractère(s) observé avec la plus grande fréquence
// si plusieurs ont la fréquence maximum, les renvoi tous
// TODO : modifier car plusieurs caractères peuvent avoir la plus grande
// fréquence
function array_mode($arr) {
         
$a=array_values_count($arr);
         
asort($a);
         
end($a);
         return array(
key($a)=>current($a));
}

// modes : caractère(s) observé(s) avec la plus grande fréquence
// si plusieurs ont la fréquence maximum, les renvoi tous
function array_modes($arr) {
         
$a=array_values_count($arr);
         
asort($a);
         
end($a);
         return array(
key($a)=>current($a));
}

function 
array_values_count($arr,$sort=0) {
         
$a=array();
         foreach(
$arr as $elem) {
                      if (!
is_string($elem) && !is_integer($elem)) {
                              @
array_push($a,(string)$elem);
                              
// @ is here to avoid the Notice messages
                              // "conversion" from array to string
                      
} else array_push($a,$elem);
         }
         
$a=array_count_values($a);
         if (
$sort==1) { asort($a);       // 1:sorted on values
         
} elseif ($sort==2) { arsort($a);  // 2:reverse sorted on values
         
} elseif ($sort==3) { ksort($a);  // 3:sorted on keys
         
} elseif ($sort==4) { krsort($a);  // 4:reverse sorted on keys
         
}
         return 
$a;
}


// ************************************
// Below are not finished functions ***
// ************************************
function variance_observed_percent($p,$n){ return $p*(1-$p)/$n; }
function 
stdev_observed_percent($p,$n){ return sqrt($p*(1-$p)/$n); }
function 
ecart_reduit($e,$p,$n) { return $e/stdev_observed_percent($p,$n); }
//effectifs théoriques ou effectifs calculés
function condition_np($p,$n) { return $n*$p; }
function 
condition_nq($p,$n) { return $n*(1-$p); }
function 
normal_law($x) { return $y=((1/sqrt(2*pi()))*exp(-(pow($x,2)/2))); }

?>