Created
May 17, 2014 17:38
-
-
Save johnnymo87/711e1d38e2e5707fda06 to your computer and use it in GitHub Desktop.
Finding fixed points
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 math.abs | |
object finding_fixed_points { | |
val tolerance = 0.0001 //> tolerance : Double = 1.0E-4 | |
def isCloseEnough(x: Double, y: Double) = | |
abs((x - y) / x) / x < tolerance //> isCloseEnough: (x: Double, y: Double)Boolean | |
def fixedPoint(f: Double => Double)(firstGuess: Double) = { | |
def iterate(guess: Double): Double = { | |
val next = f(guess) | |
if (isCloseEnough(guess, next)) next | |
else iterate(next) | |
} | |
iterate(firstGuess) | |
} //> fixedPoint: (f: Double => Double)(firstGuess: Double)Double | |
fixedPoint(x => 1 + x/2)(1) //> res0: Double = 1.999755859375 | |
def averageDamp(f: Double => Double)(x: Double) = (x + f(x))/2 | |
//> averageDamp: (f: Double => Double)(x: Double)Double | |
def sqrt(x: Double) = | |
fixedPoint(averageDamp(y => x / y))(1) //> sqrt: (x: Double)Double | |
sqrt(2) //> res1: Double = 1.4142135623746899 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The code above is from lecture 2.3 of Functional Programming Principles in Scala.
It blows my mind how composable functions are in Scala.
If I call
averageDamp
with two arguments, I get the expected return value -- a Double. But if I call it with only one argument (a function), I get backaverageDamp
's body mixed with that function. I can then use that to my advantage, injecting that combination of functions into my use of thefixedPoint
function insqrt
. (I needed this "average damping" functionality when implementingsqrt
withfixedPoint
because otherwise it would never converge, thrashing forever between 1 and 2.)