Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.twitter.algebird.statistics

import com.twitter.algebird.Monoid

/**
* @mean - Mean
* @sigma2 - Variance, where sqrt(sigma2) is the standard deviation
* aka Normal distribution
*/
case class GaussianDistribution(mean: Double, sigma2: Double) {
def stddev: Double = math.sqrt(sigma2)

def sample(r: java.util.Random): Double =
mean + r.nextGaussian() * stddev
}

object GaussianDistribution {
implicit val monoid: Monoid[GaussianDistribution] = GaussianDistributionMonoid
}

/**
* This monoid stems from the fact that if X and Y are independent random variables
* that are normally distributed, then their sum is also
* normally distributed, with its new mean equal to the sum of two means
* and variance equal to the sum of two variances.
* http://en.wikipedia.org/wiki/Sum_of_normally_distributed_random_variables
*/
object GaussianDistributionMonoid extends Monoid[GaussianDistribution] {
override def zero = new GaussianDistribution(0, 0)

override def plus(left: GaussianDistribution, right: GaussianDistribution): GaussianDistribution =
new GaussianDistribution(left.mean + right.mean, left.sigma2 + right.sigma2)

override def sumOption(its: TraversableOnce[GaussianDistribution]): Option[GaussianDistribution] =
if (its.isEmpty)
None
else {
var mean = 0.0
var sigma2 = 0.0
val it = its.toIterator
while (it.hasNext) {
val g = it.next
mean += g.mean
sigma2 += g.sigma2
}
Some(GaussianDistribution(mean, sigma2))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.twitter.algebird.statistics

import com.twitter.algebird.CheckProperties
import org.scalacheck.{ Arbitrary, Gen }
import org.scalatest._

class GaussianDistributionMonoidTests extends CheckProperties {
import com.twitter.algebird.BaseProperties._

implicit val gaussianGenerators = Arbitrary {
for (
mean <- Gen.choose(0, 10000);
sigma <- Gen.choose(0, 10000)
) yield (GaussianDistribution(mean, sigma))
}

property("GaussianDistributionMonoid is a Monoid") {
monoidLaws[GaussianDistribution]
}
}