Created
January 27, 2013 00:12
-
-
Save mepcotterell/4645416 to your computer and use it in GitHub Desktop.
Stream-based Linear Congruential Generator in Scala
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
/** | |
* Linear Congruential Generator | |
* | |
* This implementation allows you to grab an individual number by its index. It | |
* also provides a stats object for displaying statistics about the lcg. | |
* | |
* @see http://en.wikipedia.org/wiki/Linear_congruential_generator | |
* @author Michael E. Cotterell <[email protected]> | |
* @param a the multiplier | |
* @param c the increment | |
* @param m the modulus | |
* @param seed start value | |
*/ | |
case class LCG (a: Long, c: Long, m: Long, seed: Long) { | |
import scala.language.postfixOps | |
private val ref = this | |
private val m_inverse = 1.0 / m.toDouble | |
private var i: Int = 1 | |
private lazy val stream: Stream[Long] = 0L #:: seed #:: stream.zip(stream.tail).map({ case (e, last) => (a * last + c) % m }) | |
def gen: Double = stream({i += 1; i}).toDouble * m_inverse | |
def get (idx: Int): Double = stream(idx + 2) * m_inverse | |
def length: Int = i - 1 | |
object stats { | |
lazy val samples: Array[Double] = stream.take(10000 + 2).drop(2).toArray.map( e => e * m_inverse ) | |
lazy val ms: Double = samples.map( e => e * e ).sum / samples.length | |
lazy val mean: Double = samples.sum / samples.length | |
lazy val variance: Double = ms - mean * mean | |
override def toString: String = "%s.stats(samples = %5d, mean = %3.3f, variance = %3.3f)".format(ref, samples.length, mean, variance) | |
} // test | |
} // LCG |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment