/**
  * Verify the input arguments are valid for correct use of the bisection
  * method. If the tolerance is less than zero, an Exception will be thrown.
  * If f($a) and f($b) have the same sign, we cannot use the intermediate
  * value theorem to guarantee a root is between $a and $b. This exposes the
  * risk of an endless loop, so we throw an Exception. If $a = $b, then clearly
  * we cannot run our loop as $a and $b will themselves be the midpoint, so we
  * throw an Exception.
  *
  * @param Callable $function f(x) callback function
  * @param number   $a        The start of the interval which contains a root
  * @param number   $b        The end of the interval which contains a root
  * @param number   $tol      Tolerance; How close to the actual solution we would like.
  *
  * @throws Exception if $tol (the tolerance) is negative
  * @throws Exception if $a = $b
  * @throws Exception if f($a) and f($b) share the same sign
  */
 private static function validate(callable $function, $a, $b, $tol)
 {
     Validation::tolerance($tol);
     Validation::interval($a, $b);
     $f⟮a⟯ = $function($a);
     $f⟮b⟯ = $function($b);
     if (Special::sgn($f⟮a⟯) === Special::sgn($f⟮b⟯)) {
         throw new Exception\BadDataException('Input function has the same sign at the start and end of the interval. Choose start and end points such that the function evaluated at those points has a different sign (one positive, one negative).');
     }
 }
 /**
  * Verify the input arguments are valid for correct use of fixed point
  * iteration. If the tolerance is less than zero, an Exception will be thrown.
  * If $a = $b, then clearly we cannot run our loop as [$a, $b] will not be
  * an interval, so we throw an Exception. If $a > $b, we simply reverse them
  * as if the user input $b = $a and $a = $b so the new $a < $b.
  *
  * @param number   $a        The start of the interval which contains a root
  * @param number   $b        The end of the interval which contains a root
  * @param number   $p        The initial guess of our root
  * @param number   $tol      Tolerance; How close to the actual solution we would like.
  *
  * @throws Exception if $tol (the tolerance) is negative
  * @throws Exception if $a = $b
  * @throws Exception if either $p > $a or $p < $b return false
  */
 private static function validate($a, $b, $p, $tol)
 {
     Validation::tolerance($tol);
     Validation::interval($a, $b);
     if ($a > $b) {
         list($a, $b) = [$b, $a];
     }
     if ($p < $a || $p > $b) {
         throw new Exception\OutOfBoundsException("Initial guess {$p} must be in [{$a}, {$b}].");
     }
 }