Created
February 6, 2013 18:56
-
-
Save mariusae/4724851 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import scala.util.Random | |
| class Kalman(N: Int) { | |
| private[this] val mbuf = new Array[Double](N) | |
| private[this] val ebuf = new Array[Double](N) | |
| private[this] var estimate: Double = _ | |
| private[this] var n = 0L | |
| private[this] var weight: Double = 0.9 | |
| def measure(m: Double, e: Double) { | |
| val i = (n%N).toInt | |
| mbuf(i) = m | |
| ebuf(i) = e | |
| if (n == 0) | |
| estimate = m | |
| estimate += weight*(m-estimate) | |
| if (mvar + evar == 0) | |
| weight = 1D | |
| else | |
| weight = mvar / (mvar + evar) | |
| n += 1 | |
| } | |
| private[this] def mvar = variance( | |
| if (n < N) mbuf take n.toInt | |
| else mbuf | |
| ) | |
| private[this] def evar = variance( | |
| if (n < N) ebuf take n.toInt | |
| else ebuf | |
| ) | |
| def currentEstimate = estimate | |
| def variance(samples: Array[Double]): Double = { | |
| if (samples.size == 1) | |
| return 0D | |
| val sum = samples.sum | |
| val mean = sum / samples.size | |
| val diff = (samples map { x => (x-mean)*(x-mean) }).sum | |
| diff/(samples.size-1) | |
| } | |
| override def toString = | |
| "Kalman<estimate=%f, weight=%f, mvar=%f, evar=%f>".format(estimate, weight, mvar, evar) | |
| } | |
| class KalmanError(N: Int, range: Double) extends Kalman(N) { | |
| require(range >= 0D && range <1D) | |
| private[this] val rng = new Random | |
| def measure(m: Double) { | |
| measure(m, rng.nextGaussian()*range*m) | |
| } | |
| } | |
| /* | |
| scala $% < /Users/marius/Desktop/admixer.gclog | |
| */ | |
| case class Gclog(s0u: Double, s1u: Double, eu: Double) | |
| val ents = scala.io.Source.stdin.getLines().drop(1) map(_.split(" ").filter(_ != "") map(_.toDouble)) collect { | |
| case Array(s0c, s1c, s0u, s1u, ec, eu, oc, ou, pc, pu, ygc, ygct, fgc, fgct, gct) => | |
| Gclog(s0u, s1u, eu) | |
| } | |
| val k = new KalmanError(50, .5) | |
| for (List(Gclog(_, _, a), Gclog(_, _, b)) <- ents.toList.sliding(2) if (a < b)) { | |
| val rate = (b-a)*4D | |
| k.measure(rate) | |
| println("%.0f %.0f".format(rate, k.currentEstimate)) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment