case class ApproxGaussian(
   val μ /*mean*/: Double, val σ /*standard deviation*/: Double
 ) ) {
    private val distrib =  breeze.stats.distributions.
     Gaussian(μ, σ)
   
   /*
    We want to normalize so that the results is within 0,1
    In this class we exploit the fact that 97%
     of the values are within  [μ-3σ,μ+3σ]
     we so map this interval map to 0 and compress the remaining values to [0,1]
    */
    /* Resolving :
    a * (μ - 3σ) + b = 0
     a * (μ + 3σ) + b = 1
    */
   val a = 1 / (6 * σ)
   val b = 0.5 - (μ / (6 * σ))
    def draw  = {
     val comp = a * distrib.draw - b
     if (comp < 0 || 1 < comp) {
       println(s"Ha! $comp")
       Math.max(1,Math.min(0,comp))
     } else {
       comp
     }
   } ensuring {v => v >= 0 && v <= 1}
   
 }
  case class FiniteGaussian(
   val μ /*mean*/: Double, val σ /*standard deviation*/: Double
 )(
   nbElems : Int
 ) {
   /*
    We want to normalize so that the results is within 0,1
    In this class we generate the set of elements and take its max and min in order to normalize
    */
   private val distrib =
     Gaussian(μ, σ).sample(nbElems)
    val max = distrib.max
   val min = distrib.min
    /* Resolving
    a * max + b = 1
    a * min + b = 0
    */
   val a = 1 / (max - min)
   val b = -min / (max - min)
    /* */
    val distribIt = distrib.iterator
    def draw  = (a * distribIt.next - b) ensuring {v => v >= 0 && v <= 1}
   
 }