Skip to content

Instantly share code, notes, and snippets.

@jsaund
Last active October 11, 2015 02:08
Show Gist options
  • Save jsaund/88a156fffa1789f0afb0 to your computer and use it in GitHub Desktop.
Save jsaund/88a156fffa1789f0afb0 to your computer and use it in GitHub Desktop.
A collection of statistical operations performed in Scala using functional principles.
object Stats {
def simpleMovingAverage1(xs: List[Dobule], w: Int): List[Double] = {
xs sliding w map (_.sum) map (_ / w) toList
}
def simpleMovingAverage2(xs: List[Double], w: Int): List[Double] = {
def movingSum(xs: List[Double], w: Int): List[Double] = w match {
case 0 => throw new IllegalArgumentException("Window size must be greater than 0")
case 1 => xs
case 2 => xs sliding 2 map (_.sum) toList
case odd if odd % 2 == 1 => xs zip movingSum(xs drop 1, odd - 1) map Function.tupled(_ + _)
case even =>
val half = even / 2
val partialResult = movingSum(xs, half)
partialResult zip movingSum(xs drop 2, half) map Function.tupled(_ + _)
}
movingSum(xs, w) map (_ / w)
}
def simpleMovingAverage3(xs: List[Double], w: Int): List[Double] = {
val first = (xs take w).sum / w
val subtract = xs map (_ / w)
val add = subtract drop w
val addAndSubtract = add zip subtract map Function.tupled(_ - _)
addAndSubtract.foldLeft(first :: Nil){ (res, add) => res.head + add :: res }.reverse
}
def standardDeviation(xs: List[Double]): Double = {
val mean = xs.sum / xs.length
val variance = xs.foldLeft(0.0){ case (v, x) => v + (x - mean) * (x - mean) } / xs.length
Math.sqrt(variance)
}
def standardDeviation2(xs: List[Double]): Double = {
val acc = xs.foldLeft((0.0, 0.0)){ case ((sum, sumOfSquares), x) => (sum + x, sumOfSquares + x * x) }
val variance = acc._2 / xs.length - (acc._1 / xs.length) * (acc._1 / xs.length)
Math.sqrt(variance)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment