Skip to content

Instantly share code, notes, and snippets.

@krishnanraman
Last active August 29, 2015 14:04
Show Gist options
  • Save krishnanraman/c91ae6bf1694339baa9c to your computer and use it in GitHub Desktop.
Save krishnanraman/c91ae6bf1694339baa9c to your computer and use it in GitHub Desktop.
Compute Euler's number using Iterative Map-Reduce via ExecutionContextJob
import com.twitter.scalding._
import com.twitter.scalding.ExecutionContext._
import com.twitter.algebird.monad._
class e(args:Args)extends ExecutionContextJob(args) {
def factorial(x:Int): Long = {assert (x<21); if (x==0) 1 else x*factorial(x-1) }
override def job: Reader[ExecutionContext, Nothing] = {
Execution.waitFor(Config.default, Local(false)) { implicit ec: ExecutionContext =>
for( i<- 1 to 20) {
TypedPipe.from(0 to i)
.map{ x => 1.0/factorial(x) }
.groupAll
.sum
.values
.write(TypedTsv[Double]("e-approx" + i))(flowDefFromContext, modeFromContext)
}
}
ReaderFn(ec=>{ println("exiting"); sys.exit(1)} )
}
}
Goal: Compute Euler's number using a Taylor series with iterative map-reduce.
Idea:
For the i-th iteration (i between 1 & 20), fill up a pipe so it looks like
--
1
2
3
4
...
i
--
Now map each x to 1/x!
So
1-> 1/1! = 1
2 -> 1/2! = 0.5
3 -> 1/3! = 0.1666
...
Now groupAll & sum
That gives us the Taylor series
e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! +....
where x = 1 implies
1 + 1 + 0.5 + 0.1666 + ... = e
$ ls e-approx*
e-approx1 e-approx11 e-approx13 e-approx15 e-approx17 e-approx19 e-approx20 e-approx4 e-approx6 e-approx8
e-approx10 e-approx12 e-approx14 e-approx16 e-approx18 e-approx2 e-approx3 e-approx5 e-approx7 e-approx9
So we have 20 files here, lets look into each:
$ grep "" e-approx*
e-approx1:2.0
e-approx10:2.7182818011463845
e-approx11:2.718281826198493
e-approx12:2.7182818282861687
e-approx13:2.7182818284467594
e-approx14:2.71828182845823
e-approx15:2.718281828458995
e-approx16:2.718281828459043
e-approx17:2.7182818284590455
e-approx18:2.7182818284590455
e-approx19:2.7182818284590455
e-approx2:2.5
e-approx20:2.7182818284590455
e-approx3:2.6666666666666665
e-approx4:2.708333333333333
e-approx5:2.7166666666666663
e-approx6:2.7180555555555554
e-approx7:2.7182539682539684
e-approx8:2.71827876984127
e-approx9:2.7182815255731922
Now lets look at what scala gives us:
scala> math.exp(1)
res1: Double = 2.7182818284590455
So it looks like we converged in about 17 steps to scala's equivalent double precision solution.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment