def calculate(f: Int => Int, sumProd:(Int, Int)=>Int, n: Int, a:Int, b:Int):Int =
if (a>b) n
else sumProd(f(a), calculate(f, sumProd, n, a+1, b))
This scala function can in a chosen number area (a to b) do chosen calculations with them:
example calling:
calculate(x=>2*x, (x,y)=>x+y, 0, 2 , 4)
this calculates: 2*2 + 2*3 + 2*4 = 18
Which folding(right- or left folding) is this function using? And how to see that?
further example callings for the function:
calculate(x=>2+x, (x,y)=>x*y,1, 2 , 4)
calculate(x=>2+x, (a,b)=>a+b,0, 1, 5)
calculate(x=>2*x, (a,b)=>a+b,0, 1, 5)
What you have is equivalent to, in pseudocode,
calculate(f, sumProd, n, a, b)
=
fold-right( sumProd, n, map(f, [a .. b]))
where [a .. b] denotes a list of numbers from a to b, inclusive, increasing by the step of 1. In other words, it is the same as
=
sumProd( f(a),
sumProd( f(a2),
sumProd( f(a3),
...
sumProd( f(b), n) ... )))
Related
I want to write a function in scala calcMod(a, b, c) where a should serve as a predicate and b and c taking the range of numbers (e.g. 3(incl.)...9(excl.)) which have to be evaluated and return a list of numbers in this range for which the predicate holds.
For example the function-call calcMod(k => k % 2 == 0, 3, 9) should evaluate in Return(4, 6, 8)
The fact that I have mod 2 == 0 makes it clear that even numbers will always be returned. I want to solve this with linear recursion.
def calcMod(a: Int => Boolean, b: Int, c: Int): List[Int] = ?
Below function will go from b until c, then apply filter with the function we got in argument.
def calcMod(a: Int => Boolean, b: Int, c: Int): List[Int] = (b until c filter a).toList
I want to do k-fold cross validation. Essentially we are given a bunch of data allData. Suppose we partition our input into "k" cluster and put it in groups.
The desired output is a trainAndTestDataList: List[(Iterable[T], Iterable[T])], where the Listis of size "k". The "i"th element of the trainAndTestDataList is a tuple like (A, B), where A should be the "i"th element of groups and B should be all elements of groups except the "i"th one, concatenated.
Any ideas on implementing this efficiently?
val allData: Iterable[T] = ... // we get the data from somewhere
val groupSize = Math.ceil(allData.size / k).toInt
val groups = allData.grouped(groupSize).toList
val trainAndTestDataList = ... // fill out this part
One thing to keep in mind is that allData can be very long, however "k" is very small (say 5). So it is very crucial to keep all the data vectors as Iterator (and not List, Seq, etc).
Update: Here is how I did (and I am not happy about it):
val trainAndTestDataList = {
(0 until k).map{ fold =>
val (a,b) = groups.zipWithIndex.partition{case (g, idx) => idx == fold}
(a.unzip._1.flatten.toIterable, b.unzip._1.flatten.toIterable)
}
}
Reasons I don't like it:
much twisted especially after partition where I do an unzip, then ._1 and flatten. I think one should be able to do a better job.
Although a is a Iterable[T], the output of a.unzip._1.flatten. is a List[T], I think. This is no good, since the number of the element in this list might be very large.
You could try that operation
implicit class TeeSplitOp[T](data: Iterable[T]) {
def teeSplit(count: Int): Stream[(Iterable[T], Iterable[T])] = {
val size = data.size
def piece(i: Int) = i * size / count
Stream.range(0, size - 1) map { i =>
val (prefix, rest) = data.splitAt(piece(i))
val (test, postfix) = rest.splitAt(piece(i + 1) - piece(i))
val train = prefix ++ postfix
(test, train)
}
}
}
This split will be as lazy as splitAt and ++ are within your collection type.
You can try it with
1 to 10 teeSplit 3 force
I believe this should work. It also takes care of the randomization (don't neglect this!) in a reasonably efficient manner, i.e. O(n) instead of O(n log(n)) required for the more naive approach using a random shuffle/permutation of the data.
import scala.util.Random
def testTrainDataList[T](
data: Seq[T],
k: Int,
seed: Long = System.currentTimeMillis()
): Seq[(Iterable[T], Iterable[T])] = {
def createKeys(n: Int, k: Int) = {
val groupSize = n/k
val rem = n % k
val cumCounts = Array.tabulate(k){ i =>
if (i < rem) (i + 1)*(groupSize + 1) else (i + 1)*groupSize + rem
}
val rng = new Random(seed)
for (count <- n to 1 by -1) yield {
val j = rng.nextInt(count)
val i = cumCounts.iterator.zipWithIndex.find(_._1 > j).map(_._2).get
for (s <- i until k) cumCounts(s) -= 1
}
}
val keys = createKeys(data.length, k)
for (i <- 0 until k) yield {
val testIterable = new Iterable[T] {
def iterator = (keys.iterator zip data.iterator).filter(_._1 == i).map(_._2)
}
val trainIterable = new Iterable[T] {
def iterator = (keys.iterator zip data.iterator).filter(_._1 != i).map(_._2)
}
(testIterator, trainIterator)
}
}
Note the way I define testIterable and trainIterable. This makes your test/train sets lazy and non-memoized, which I gathered is what you wanted.
Example usage:
val data = 'a' to 'z'
for (((testData, trainData), index) <- testTrainDataList(data, 4).zipWithIndex) {
println(s"index = $index")
println("test: " + testData.mkString(", "))
println("train: " + trainData.mkString(", "))
}
//index = 0
//test: i, l, o, q, v, w, y
//train: a, b, c, d, e, f, g, h, j, k, m, n, p, r, s, t, u, x, z
//
//index = 1
//test: a, d, e, h, n, r, z
//train: b, c, f, g, i, j, k, l, m, o, p, q, s, t, u, v, w, x, y
//
//index = 2
//test: b, c, m, t, u, x
//train: a, d, e, f, g, h, i, j, k, l, n, o, p, q, r, s, v, w, y, z
//
//index = 3
//test: f, g, j, k, p, s
//train: a, b, c, d, e, h, i, l, m, n, o, q, r, t, u, v, w, x, y, z
Just started programming in the Nim language (which I really like so far). As a learning exercise I am writing a small matrix library. I have a bunch more code, but I'll just show the part that's relevant to this question.
type
Matrix*[T; nrows, ncols: static[int]] = array[0 .. (nrows * ncols - 1), T]
# Get the index in the flattened array corresponding
# to row r and column c in the matrix
proc index(mat: Matrix, r, c: int): int =
result = r * mat.ncols + c
# Return the element at r, c
proc `[]`(mat: Matrix, r, c: int): Matrix.T =
result = mat[mat.index(r, c)]
# Set the element at r, c
proc `[]=`(mat: var Matrix, r, c: int, val: Matrix.T) =
mat[mat.index(r, c)] = val
# Add a value to every element in the matrix
proc `+=`(mat: var Matrix, val: Matrix.T) =
for i in 0 .. mat.high:
mat[i] += val
# Add a value to element at r, c
proc `[]+=`(mat: var Matrix, r, c: int, val: Matrix.T) =
mat[mat.index(r, c)] += val
# A test case
var mat: Matrix[float, 3, 4] # matrix with 3 rows and 4 columns
mat[1, 3] = 7.0
mat += 1.0
# add 8.0 to entry 1, 3 in matrix
`[]+=`(mat, 1, 3, 8.0) # works fine
All this works fine, but I'd like to be able to replace the last line with something like
mat[1, 3] += 4.0
This won't work (wasn't expecting it to either). If I try it, I get
Error: for a 'var' type a variable needs to be passed
How would I create an addition assignment operator that has this behavior? I'm guessing I need something other than a proc to accomplish this.
There are two ways you can do this:
Overload [] for var Matrix and return a var T (This requires the current devel branch of Nim):
proc `[]`(mat: Matrix, r, c: int): Matrix.T =
result = mat[mat.index(r, c)]
proc `[]`(mat: var Matrix, r, c: int): var Matrix.T =
result = mat[mat.index(r, c)]
Make [] a template instead:
template `[]`(mat: Matrix, r, c: int): expr =
mat[mat.index(r, c)]
This causes a problem when mat is not a value, but something more complex:
proc x: Matrix[float, 2, 2] =
echo "x()"
var y = x()[1, 0]
This prints x() twice.
I'm newbie with Scala, I'm having issue with currying and can't understand of how below code answer is 144. Hope you guys can help me here.
Thanks
def product (f: Int => Int)(a: Int, b: Int) : Int =
if(a>b) 1
else f(a) * product(f)(a + 1, b)
product(x => x * x)(3, 4) //answer = 144
Here is nothing related with currying. You could rewrite your product method like this:
def product(f: Int => Int, a: Int, b: Int) : Int =
if(a>b) 1
else f(a) * product(f, a + 1, b)
val f = (x: Int) => x*x
product(f, 3, 4) // still 144
You could replace product(f, a, b) with f(a) * product(f, a+1, b) (in case a <= b) or with 1, you could also replace f(a) with a*a:
product(f, 3, 4) ==
9 * product(f, 4, 4) ==
9 * ( 16 * product(f, 5, 4) ) ==
9 * ( 16 * 1 ) ==
144
First argument of this method is a function that maps integer to integer, ie. in given example, it squares the number passed to it.
Function 'product' then uses that function (passed as first parameter), and applies it to first argument ('a') and multiplies that result to recursive call to 'product' with same 'f', but with first argument incremented.
As you can notice, parameter named 'b' doesn't play any computational role, other than limit to number of executions of function 'product'.
So, to resolve that call of 'product', we begin with 'a = 3, b = 4'.
First, as 'a' is less than or equal to 'b', we go to else branch where we square (apply 'f') first parameter 'a' (which gives 9), and then multiply that with 'product(f)(4, 4)'.
We also go to else branch here and there we square 4 (as value of 'a' in this execution of 'product') to get 16 and multiply it with 'product(f)(5, 4)'.
Here, 'a' is greater than 'b', so we end 'product' with value 1.
As we propagate that back, we get 1 * 16 * 9 which, in turn equals 144.
I'm taking a functional programming languages course and I'm having difficulty understanding recursion within the context of 'functions as arguments'
fun n_times(f , n , x) =
if n=0
then x
else f (n_times(f , n - 1 , x))
fun double x = x+x;
val x1 = n_times(double , 4 , 7);
the value of x1 = 112
This doubles 'x' 'n' times so 7 doubled 4 times = 112
I can understand simpler recursion patterns such as adding numbers in a list, or 'power of' functions but I fail to understand how this function 'n_times' evaluates by calling itself ? Can provide an explanation of how this function works ?
I've tagged with scala as I'm taking this course to improve my understanding of scala (along with functional programming) and I think this is a common pattern so may be able to provide advice ?
If n is 0, x is returned.
Otherwise, f (n_times(f , n - 1 , x)) is returned.
What does n_times do? It takes the result of calling f with x, n times, or equivalently: calls f with the result of n_times(f, n - 1, x) (calling f n-1 times on x).
Note by calling f i mean for example:
calling f 3 times: f(f(f(x)))
calling f 2 times: f(f(x))
Just expand by hand. I'm going to call n_times nx to save space.
The core operation is
nx(f, n, x) -> f( nx(f, n-1, x))
terminating with
nx(f, 0, x) -> x
So, of course,
nx(f, 1, x) -> f( nx(f, 0, x) ) -> f( x )
nx(f, 2, x) -> f( nx(f, 1, x) ) -> f( f( x ) )
...
nx(f, n, x) -> f( nx(f,n-1,x) ) -> f( f( ... f( x ) ... ) )
Function n_times has a base case when n = 0 and an inductive case otherwise. You recurse on the inductive case until terminating on the base case.
Here is an illustrative trace:
n_times(double, 4, 7)
~> double (n_times(double, 3, 7)) (* n = 4 > 0, inductive case *)
~> double (double (n_times(double, 2, 7))) (* n = 3 > 0, inductive case *)
~> double (double (double (n_times(double, 1, 7)))) (* n = 2 > 0, inductive case *)
~> double (double (double (double (n_times(double, 0, 7))))) (* n = 1 > 0, inductive case *)
~> double (double (double (double 7))) (* n = 0, base case *)
~> double (double (double 14))
~> double (double 28)
~> double 56
~> 112
It is the same recursion thinking what you know already, just mixed with another concept: higher order functions.
n_times gets a function (f) as a parameter, so n_times is a higher order function, which in turn is capable to apply this f function in his body. In effect that is his job, apply f n times to x.
So how you apply f n times to x? Well, if you applied n-1 times
n_times(f , n - 1 , x)
, then you apply once more.
f (n_times(f , n - 1 , x))
You have to stop the recursion, as usual, that is the n=0 case with x.