let kl_up q p = 
  if p <= q then 0.
  else if q = 0. then log (1. /. (1. -. p))
  else if q = 1. then log (1. /. p)
  else
    let ret = q *. log (q /. p) +. (1. -. q) *. log ( (1. -. q) /. (1. -. p)) in
    ret

let kl_down q p = 
  if p >= q then 0.
  else if q = 0. then log (1. /. (1. -. p))
  else if q = 1. then log (1. /. p)
  else
    let ret = q *. log (q /. p) +. (1. -. q) *. log ( (1. -. q) /. (1. -. p)) in
    ret

let relative_entropy_upper size examples errors p =
  let p_hat = float errors /. float examples in
  min (~-. (float examples) *. kl_up p_hat p +. size) 0.

let relative_entropy_lower size examples errors p =
  let p_hat = float errors /. float examples in
  min (~-. (float examples) *. kl_down p_hat p +. size) 0.

