Created
August 5, 2009 17:58
-
-
Save tjennings/162860 to your computer and use it in GitHub Desktop.
This file contains 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
//Gives us the :: syntax for streams. From http://www.codecommit.com/blog/scala/infinite-lists-for-the-finitely-patient. | |
class RichStream[A](str: =>Stream[A]) { | |
def ::(hd: A) = Stream.cons(hd, str) | |
} | |
implicit def streamToRichStream[A](str: =>Stream[A]) = new RichStream(str) | |
object M { //Gives us a shorthand for declaring BigDecimals that Scala lacks | |
def apply(i:Int) = BigDecimal(i) | |
} | |
//Hack to work around poor bigdecimal support | |
val mc = new java.math.MathContext(300,java.math.RoundingMode.HALF_UP) | |
def divide(a:BigDecimal, b:BigDecimal) = { | |
new BigDecimal(a.bigDecimal.divide(b.bigDecimal, mc)) | |
} | |
def piSummands(n: BigDecimal): Stream[BigDecimal] = { | |
divide(M(1), n) :: piSummands(n + M(2)).map(_ * -1) | |
} | |
def scaleStream(stream:Stream[BigDecimal], factor:Int) = { | |
stream map {_ * factor} | |
} | |
def addStreams(s1:Stream[BigDecimal], s2:Stream[BigDecimal]) = { | |
s1 zip(s2) map {z => z._1 + z._2} | |
} | |
def partialSums(s:Stream[BigDecimal]):Stream[BigDecimal] = { | |
s.head :: addStreams(s.tail, partialSums(s)) | |
} | |
def piStream = scaleStream(partialSums(piSummands(1)), 4) | |
def square(s:BigDecimal) = s * s | |
def eulerTransform(s:Stream[BigDecimal]):Stream[BigDecimal] = { | |
val s0 = s(0) | |
val s1 = s(1) | |
val s2 = s(2) | |
val head = s2 - divide((square(s2 - s1)), ((s0 + (M(-2) * s1) + s2))) | |
head :: eulerTransform(s.tail) | |
} | |
type Transform = (Stream[BigDecimal]) => Stream[BigDecimal] | |
def makeTableau(transform: Transform, s:Stream[BigDecimal]):Stream[Stream[BigDecimal]] = { | |
s :: makeTableau(transform, transform(s)) | |
} | |
def acceleratedSequence(transform:Transform, s:Stream[BigDecimal]) = { | |
makeTableau(transform, s) map {_.head} | |
} | |
val set = acceleratedSequence(eulerTransform, piStream) | |
println(set.take(150).last) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment