public static function generalizedHypergeometric(int $p, int $q, ...$params)
{
$n = count($params);
if ($n !== $p + $q + 1) {
$expected_num_params = $p + $q + 1;
throw new Exception\BadParameterException("Number of parameters is incorrect. Expected {$expected_num_params}; got {$n}");
}
$a = array_slice($params, 0, $p);
$b = array_slice($params, $p, $q);
$z = $params[$n - 1];
$tol = 1.0E-8;
$n = 1;
$sum = 0;
$product = 1;
do {
$sum += $product;
$a_sum = array_product(Single::add($a, $n - 1));
$b_sum = array_product(Single::add($b, $n - 1));
$product *= $a_sum * $z / $b_sum / $n;
$n++;
} while ($product / $sum > $tol);
return $sum;
}