The following code works but I don't quite understand how the arguments are mapped to the parameter lists. Please be aware Im new to Scala.
import Math.abs
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double) =
abs((x - y) / x) / x < tolerance
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)
}
def averageDamp(f: Double => Double)(x: Double) = (x + f(x)) / 2
def sqrt(x: Double) =
fixedPoint(averageDamp(y => x / y))(1.0)
sqrt(2.0)
The body of the sqrt function above is fixedPoint(averageDamp(y => x / y))(1.0)
where
(y => x / y) maps to (f: Double => Double) of the averageDamp function and
(1.0) maps to (firstGuess: Double) of the fixedPoint function but
looks like nothing maps to (x: Double) of the averageDamp function.
Thank you in advance.
This is called currying. What's really happening is that averageDamp(y => x / y) is being interpreted as a function: Double => Double, because once you set the first parameter list to a particular set of values, you obtain a function that takes the second parameter list.
For example, consider the following code:
def multiply(x: Double)(y: Double) = x * y
val multiplyByFive: Double => Double = multiply(5)
println(multiplyByFive(2)) // 10
println(multiplyByFive(6)) // 30
As you see, the fact of applying multiply with only one parameter list out of two creates a new function of the second parameter list (here (y: Double)) that has a fixed set of values for the first parameter list (here (5)).
Another equivalent way to write this, which perhaps will be more explicit for you, is the following :
val multiplyByFive: Double => Double = multiply(5)(_)
Here we explicitly apply the function with two parameters lists, but using a wildcard for the second, which is a way to tell to the compiler to create a function that replaces the underscore by a parameter of the function.
Related
Hi I'm newbie in scala.
when I write the below code, Even I didn't declared variable y, but it is allowed.
object exercise {
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
//some code
}
def sqrt(x: Double) = fixedPoint(y => x / y)(1) //No error. weird...
}
I don't understand how does it works?
I didn't declared variable y
Actually, you did.
This ...
y => ...
... translates into, "Here's a function that takes a single argument. I'm going to call that argument y."
When you declare f: Double => Double, it means that function f will take Double as input parameter and will return Double as output. So, when you pass y => x / y function, y here is of type Double and x/y(output) is of type double.
It is not giving any compiler error because compiler can infer the type based on type of function fixedPoint expects.
Suggest you have a look for How to use function literals (anonymous functions) in Scala.
In the post, it use a simple example (i: Int) => i % 2 == 0 to act as a function literals, and pass it to the function filter. And see follows:
Because the Scala compiler can infer from the expression that i is an Int, the Int declaration can be dropped off: val evens = x.filter(i => i % 2 == 0)
Then, this is exactly the situation in your post for y => x / y, the Double was dropped off in your code as scala compiler can infer from the expression.
Before I answer this question let me modify your code as:
object exercise {
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
f(firstGuess) //call the function in f with the curried parameter
}
def sqrt(x: Double) = fixedPoint(y => x / y)(1) //No error. weird...
}
I have added a line to call function f (which takes Double and returns Double) with firstGuess parameter.
f(firstGuess) //call the function in f with the curried parameter
Let's see what what sqrt function is all about
def sqrt(x: Double) = fixedPoint(y => x / y)(1)
It takes a x and invokes fixedPoint with y => x/y and 1
now your y is firstGuess parameter (as per modified code) and x is the sqrt parameter.
I am trying to learn Scala using SICP, but I am having a hard time with type definitions of functions and got stuck at SICP. Here a generalized expression is build to find the square root of a number (through fixed-point search or Newton's method) where instead of:
def sqrt_damp(x: Double) =
fixed_point(average_damp(y => x / y))(1)
def sqrt_newton(x: Double) =
fixed_point(newton_method(y => square(y) - x))(1)
Based on the functions:
def square(x: Double) = x * x
def average(x: Double, y: Double) = (x + y) / 2
def abs(x: Double) = if (x < 0) -x else x
val tolerance = 0.00001
def fixed_point(f: Double => Double)(first_guess: Double) = {
def close_enough(v1: Double, v2: Double): Boolean = abs(v1 - v2) < tolerance
def attempt(guess: Double): Double = {
val next = f(guess)
if (close_enough(guess, next)) next else attempt(next)
}
attempt(first_guess)
}
def average_damp(f: Double => Double): Double => Double =
x => average(x, f(x))
val dx = 0.00001
def deriv(g: Double => Double): Double => Double =
x => (g(x + dx) - g(x)) / dx
def newton_transform(g: Double => Double): Double => Double =
x => x - g(x) / deriv(g)(x)
def newton_method(g: Double => Double)(guess: Double): Double =
fixed_point(newton_transform(g))(guess)
The square functions can be generalized in the form:
(define (fixed-point-of-transform g transform guess)
(fixed-point (transform g) guess))
Which I attempted to express as follows in Scala:
def fixed_point_of_transform(g: Double => Double, transform: Double => Double)(guess: Double): Double =
fixed_point(transform(g))(guess)
Yet the above does not compile and generates the error
type mismatch; found : Double => Double required: Double
Edit, the following works:
def fixed_point_of_transform(g: Double => Double, transform: (Double => Double) => (Double => Double))(guess: Double): Double =
fixed_point(transform(g))(guess)
So now the previous functions can be defined as:
def sqrt_damp(x: Double) =
fixed_point_of_transform(y => x / y, average_damp)(1)
def sqrt_newton(x: Double) =
fixed_point_of_transform(y => square(y) - x, newton_method)(1)
transform takes a Double and returns a Double. You cannot apply it to g, because g is a a function Double => Double. You can apply it to g(x), where x: Double. I think this is what you want: fixed_point((x: Double) => transform(g(x)))(guess)
While working through the coursera class on scala I ran into the code below (from another question asked here by Sudipta Deb.)
package src.com.sudipta.week2.coursera
import scala.math.abs
import scala.annotation.tailrec
object FixedPoint {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
val tolerance = 0.0001 //> tolerance : Double = 1.0E-4
def isCloseEnough(x: Double, y: Double): Boolean = {
abs((x - y) / x) / x < tolerance
} //> isCloseEnough: (x: Double, y: Double)Boolean
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
#tailrec
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
def myFixedPoint = fixedPoint(x => 1 + x / 2)(1)//> myFixedPoint: => Double
myFixedPoint //> res0: Double = 1.999755859375
def squareRoot(x: Double) = fixedPoint(y => (y + x / y) / 2)(1)
//> squareRoot: (x: Double)Double
squareRoot(2) //> res1: Double = 1.4142135623746899
def calculateAverate(f: Double => Double)(x: Double) = (x + f(x)) / 2
//> calculateAverate: (f: Double => Double)(x: Double)Double
def myNewSquareRoot(x: Double): Double = fixedPoint(calculateAverate(y => x / y))(1)
//> myNewSquareRoot: (x: Double)Double
myNewSquareRoot(2) //> res2: Double = 1.4142135623746899
}
My puzzlement concerns the isCloseEnough function.
I understand that for guesses which are large numbers, the difference between a guess and
the large value that the function returns could potentially be very big all the time, so we may never converge.
Conversely, if the guess is small, and if what f(x) produces is small then we will likely converge too quickly.
So dividing through by the guess like this:
def isCloseEnough(x: Double, y: Double): Boolean = {
abs((x - y) / x) / x < tolerance
}
makes perfect sense. (here is 'x' is the guess, and y is f_of_x.)
My question is why do why does the solution given divide by the guess TWICE ?
Wouldn't that undo all the benefits of dividing through by the guess the first time ?
As an example... let's say that my current guess and the value actually returned by the
function given my current x is as shown below:
import math.abs
var guess=.0000008f
var f_of_x=.00000079999f
And lets' say my tolerance is
var tolerance=.0001
These numbers look pretty close, and indeed, if i divide through by x ONCE, i see that the result
is less than my tolerance.
( abs(guess - f_of_x) / guess)
res3: Float = 1.2505552E-5
However, if i divide through by x TWICE the result is much greater than my tolerance, which would suggest
we need to keep iterating.. which seems wrong since guess and observed f(x) are so close.
scala> ( abs(guess - f_of_x) / guess) / guess
res11: Float = 15.632331
Thanks in advance for any help you can provide.
You are completely right, it does not make sense. Further, the second division is outside of the absolute value rendering the inequality true for any negative x.
Perhaps someone got confused with testing for quadratic convergence.
please find below a piece of code from Coursera online course (lecture 2.3) on functional programming in Scala.
package week2
import math.abs
object lecture2_3_next {
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double): Boolean = abs((x - y) / x) / x < tolerance
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
sqrt(2)
}
A few points blocked me while I'm trying to understand this piece of code.
I'd like your help to understanding this code.
The 2 points that annoying me are :
- when you call averageDamp, there are 2 parameters 'x' and 'y' in the function passed (eg. averageDamp(y => x / y)) but you never specify the 'y' parameter in the definition of the averageDamp function (eg. def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2). Where and how do the scala compiler evaluate the 'y' parameter.
- second point may be related to the first, I don't know in fact. When I call the averageDamp function, I pass only the function 'f' parameter (eg. y => x / y) but I don't pass the second parameter of the function which is 'x' (eg. (x: Double) second parameter). How the scala compiler is evaluating the 'x' parameter in this case to render the result of the averageDamp call.
I think I missed something about the evaluation or substitution model of scala and functional programming.
Thank's for your help and happy new year !
Hervé
1) You don't pass an x and an y parameter as f, you pass a function. The function is defined as y => x / y, where y is just a placeholder for the argument of this function, while x is a fixed value in this context, as it is given as argument for the sqrt method (in the example x is 2). Instead of the fancy lambda-syntax, you could write as well
def sqrt(x: Double): Double = fixedPoint(averageDamp(
new Function1[Double,Double] {
def apply(y:Double):Double = x / y
}
))(1)
Nothing magic about this, just an abbreviation.
2) When you have a second parameter list, and don't use it when calling the method, you do something called "currying", and you get back a partial function. Consider
def add(x:Int)(y:Int) = x + y
If you call it as add(2)(3), everything is "normal", and you get back 5. But if you call add(2), the second argument is still "missing", and you get back a function expecting this missing second argument, so you have something like y => 2 + y
The x is not a parameter of the (anonymous) function, it is a parameter of the function sqrt. For the anonymous function it is a bound closure.
To make it more obvious, let's rewrite it and use a named instead of an anonymous function:
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
will can be rewritten as this:
def sqrt(x: Double): Double = {
def funcForSqrt(y: Double) : Double = x / y // Note that x is not a parameter of funcForSqrt
// Use the function fundForSqrt as a parameter of averageDamp
fixedPoint(averageDamp(funcForSqrt))(1)
}
I have this function to compute the distance between two n-dimensional points using Pythagoras' theorem.
def computeDistance(neighbour: Point) = math.sqrt(coordinates.zip(neighbour.coordinates).map {
case (c1: Int, c2: Int) => math.pow(c1 - c2, 2)
}.sum)
The Point class (simplified) looks like:
class Point(val coordinates: List[Int])
I'm struggling to refactor the method so it's a little easier to read, can anybody help please?
Here's another way that makes the following three assumptions:
The length of the list is the number of dimensions for the point
Each List is correctly ordered, i.e. List(x, y) or List(x, y, z). We do not know how to handle List(x, z, y)
All lists are of equal length
def computeDistance(other: Point): Double = sqrt(
coordinates.zip(other.coordinates)
.flatMap(i => List(pow(i._2 - i._1, 2)))
.fold(0.0)(_ + _)
)
The obvious disadvantage here is that we don't have any safety around list length. The quick fix for this is to simply have the function return an Option[Double] like so:
def computeDistance(other: Point): Option[Double] = {
if(other.coordinates.length != coordinates.length) {
return None
}
return Some(sqrt(coordinates.zip(other.coordinates)
.flatMap(i => List(pow(i._2 - i._1, 2)))
.fold(0.0)(_ + _)
))
I'd be curious if there is a type safe way to ensure equal list length.
EDIT
It was politely pointed out to me that flatMap(x => List(foo(x))) is equivalent to map(foo) , which I forgot to refactor when I was originally playing w/ this. Slightly cleaner version w/ Map instead of flatMap :
def computeDistance(other: Point): Double = sqrt(
coordinates.zip(other.coordinates)
.map(i => pow(i._2 - i._1, 2))
.fold(0.0)(_ + _)
)
Most of your problem is that you're trying to do math with really long variable names. It's almost always painful. There's a reason why mathematicians use single letters. And assign temporary variables.
Try this:
class Point(val coordinates: List[Int]) { def c = coordinates }
import math._
def d(p: Point) = {
val delta = for ((a,b) <- (c zip p.c)) yield pow(a-b, dims)
sqrt(delta.sum)
}
Consider type aliases and case classes, like this,
type Coord = List[Int]
case class Point(val c: Coord) {
def distTo(p: Point) = {
val z = (c zip p.c).par
val pw = z.aggregate(0.0) ( (a,v) => a + math.pow( v._1-v._2, 2 ), _ + _ )
math.sqrt(pw)
}
}
so that for any two points, for instance,
val p = Point( (1 to 5).toList )
val q = Point( (2 to 6).toList )
we have that
p distTo q
res: Double = 2.23606797749979
Note method distTo uses aggregate on a parallelised collection of tuples, and combines the partial results by the last argument (summation). For high dimensional points this may prove more efficient than the sequential counterpart.
For simplicity of use, consider also implicit classes, as suggested in a comment above,
implicit class RichPoint(val c: Coord) extends AnyVal {
def distTo(d: Coord) = Point(c) distTo Point(d)
}
Hence
List(1,2,3,4,5) distTo List(2,3,4,5,6)
res: Double = 2.23606797749979