For loop in Scala - way of evaluation - scala

I want to print integer numbers from 1 to a random integer number (e.g. to a random integer number < 10 like in the following case). I can use e.g. one from the following ways:
1)
val randomNumber=r.nextInt(10)
for (i <- 0 to randomNumber) {println(i)}
2)
for (i <- 0 to r.nextInt(10)) {println(i)}
My question is the following. Is there a difference between 1) and 2) in the sense of computation? It is clear that a random number r.nextInt(10) is computed only once and after that it is assigned to
the variable randomNumber in the first case but what about the second case? Is the part r.nextInt(10) computed only once at the beginnig of the loop or it is computed for each iteration of the loop? If yes then the first variant is better from computation point of view? I know that this proposed example is an easy example but there can be much more complex for loops where the optimization can be very helpful. If the expression r.nextInt(10) in the second case is computed only once what about expressions which are e.g. functions of variable i, something like for (i <- 0 to fce(i)) {println(i)}? I guess that Fce(i) should be evaluated in every iteration of loop.
Thanks for help.
Andrew

No, there are no differences between 1) and 2).
The bound for the for loop will be evaluated once, and then the for loop will repeat this now fixed number of times.
Things would have been very different comparing those two pieces of code :
val randomNumber=r.nextInt(10)
for (i <- 0 to 10) {println(randomNumber)}
and
for (i <- 0 to 10) {println(r.nextInt(10))}
The first for loop will print 10 times the same value, the second will print 10 random values.
But you could still rewrite the second as
def randomNumber=r.nextInt(10)
for (i <- 0 to 10) {println(randomNumber)}
The change from a val to a function will cause a reevaluation every time the loop is executed.
Now, about
for (i <- 0 to function(i)) {doSomething()}
This doesn't compile. The variable i is only available in the scope between the {} of the for loop, and hence not for computing the loop bounds.
I hope this clarifies things a bit !

The two versions do the same thing, and to see why you need to realise that for in Scala works very differently from how it works in other languages like C/C++.
In Scala, for is just a bit of syntax that makes it easier to chain map/foreach, flatMap, and withFilter methods together. It makes functional code appear more like imperative code, but it is still executed in a functional way.
So your second chunk of code
for (i <- 0 to r.nextInt(10)) {println(i)}
is changed by the compiler into something like
(0 to r.nextInt(10)).foreach{ i => println(i) }
Looking at it this way, you can see that the range is computed first (using a single call to nextInt) and then foreach is called on that range. Therefore nextInt is called the same number of times as in your first chunk of code.

Related

Write a recursive function to find the smallest element in a vector(MATLAB)

Write a recursive function to find the smallest element in a vector.
We can not use loops but can use if statements.
Using RECURSION is a must.
I Could Not think of any solution, the main problem was if I define a function then I have to give it some value and if I do so then whenever recursion occur it will again reset the value of that variable.
function miminimumis=minimumval(k)
aa=k(1);
k=k(k<k(1));
if length(k)==0
miminimumis=aa;
else
% this line gives the recursion
miminimumis=minimumval(k);
end
end
here we create a new array which consists of elements only smaller than the first element. if this array is empty then it means that first element is min, if not we do the same for the new array unless we reach an empty array. the recursion is provided by using the same function in the definition of the function.
Solutions which in the worst case reduce the problem size by 1 will cause the recursive stack to have O(length(array)) growth. An example of this would be when you filter the array to yield values less than the first element when the array is in descending order. This will inevitably lead to stack overflow for sufficiently large arrays. To avoid this, you want to use a recursion which splits the problem of size n into two subproblems of size n/2, yielding O(log(length(array))).
I'm not a Matlab user/programmer, so I'll express the algorithm in pseudo-code. The following assumes that arrays are 1-based and that there is a built-in function min(a,b) which yields the minimum of two scalars, a and b. (If not, it's easy to replace min() with if/else logic.)
function min_element(ary) {
if length(ary) == 1 {
return ary[1]
}
split ary into first_half, second_half which differ in length by no more than 1
return min( min_element(first_half), min_element(second_half) )
}
This could alternatively be written using two additional arguments for the lo_index and hi_index to search between. Calculate the midpoint as the integer average of the low and high indices, and make the two recursive calls min_element(ary, lo_index, mid) and min_element(ary, mid+1, hi_index). The base condition is when lo_index == hi_index, in which case you return that element. This should be faster, since it uses simple integer arithmetic and avoids creating sub-arrays for the subproblems. It has the trade-off of being slightly less friendly to the end user, who has to start the process by calling min_element(ary, 1, length(ary)).
If the stack limit is 500, you'll be limited to arrays of length < 500 using linear stack growth algorithms. With the divide-and-conquer algorithm described above, you won't get stack overflow unless you have an array of length ~2500, much bigger than any array you could actually create.

Swift compiler optimization of 'for' loops

I have a 'for' loop similar to this:
for i in 0...n - 1 {
// do stuff, n is not changed
}
Back in the day, when I coded in FORTRAN, I was taught that this was a very inefficient way to code large 'for' loops.
Does the Swift compiler recognize the non-changing limit and pre-calculate n - 1?
I think the answer is yes.
1...n - 1 represents a Range object. It is a literal of Range. Therefore, when compilation reaches the loop and sees the literal, it thinks
It seems like that you want to create a new Range<Int> object! Here you go! Hmm... So I guess i is of type Int...
and so on.
This means that n - 1 is evaluated when you create the object. And it stays that way, not evaluating it a second time. This code proves it by not printing only one hello:
var n = 10
for i in 1...n - 1 {
n = 2
print("Hello")
}
So yeah.
Note:
It's better to use 1..<n instead of 1...n - 1 in this case, they are the same.
Apple actually recommends you to use this approach instead of the C-style for loop.
The C-style for loop will be removed in Swift 3

How to extend the range of a variable in idl

I'd like to use k to calculate the times of the for loop executed. It would be billions of times and I tried long64, then after some time k became negative. Is there any other way to do this?
Sorry I think I made a wrong description. My code is a 3-layer for nest block and each of them is calculating 2*256^3 numbers, once the value is equal to 0, I'd like to make k+=k. In the end I set print, 'k=', k and when idl was running, I found k ran from positive to negative. I used a cluster to do the computation so it didn't take quite a long time.
My guess is that you are not really using a long64 for k. The type for the loop variable in a for loop comes from the start value. For example, in this case:
k = 0LL
for k = 0, n - 1 do ...
k is a int (16-bit) because 0 is a int. You probably want something like:
for k = 0LL, n - 1LL do begin ...

if greater than matlab

I have a matrix of two columns and six rows, and want to build a second one with the following code:
for i=2
if F(:,i)<50
G(:,i) = 1
end
end
But nothing happens...
The idea was that if a value in the second column in F was less than 50, then the corresponding value in G would be 1.
Sorry for probably basic question, but no idea why this doesn't work. If I change to evaluate whether the F value ~= 50, then everything works as it should.
Thanks for any help.
Your if statement is only executed once - not once per element. While F(:,i)<50 returns an array of values, the if is either true or false; consequently, the next line is only executed once (either on all elements in G(:,i), or none of them).
For example, see this piece of code:
if(1 < [0 1 2]), disp('true'); end
It will produce no output, even though it is true for the third element. On the other hand,
if(1 < [2 3 4]), disp('true'); end
does produce output...
In general, the following:
1 < [0 1 2]
produces
0 0 1
Not sure why you say it doesn't work for < but it does work for ~=. Maybe there are no elements equal to 50, so it only "seems" to work?
In general, there is a better way to do what you want, with a single line:
G(F(:,2)<50,2)=1
This uses "logical indexing", and is much faster than looping. It will consider each element of F(:,2), and modify the corresponding element in G.
One final comment: it is not great practice to use the variable i since it has a built in value of sqrt(-1). If you have code anywhere that relies on it having that value, then accidentally overwriting it with any other value would break that. It's not the problem with your code today - but why set yourself up for a problem in the future.

Why fractional iteration step compiles into different JavaScript than integer step

I was wondering about slightly different JavaScript which ranges comprehensions in CoffeeScript compiles into. Is there any reason why following differencies in generated JavaScript?
Iterating a range by integer step
numbers = (i for i in [start..end] by 2)
compiles into:
for (i = start; i <= end; i += 2) {
_results.push(i);
}
But when iterating by fractional step
numbers = (i for i in [start..end] by 1/2)
generates bit more complicated JavaScript:
for (i = start, _ref = 1 / 2; start <= end ? i <= end : i >= end; i += _ref) {
_results.push(i);
}
So why this additional start <= end condition?
You'll get similarly elaborate code if you just do numbers = (i for i in [start..end]). This is because CoffeeScript doesn't know which direction the range goes when the beginning or ending is a variable. The compiler has a special optimization where it will output simpler code if a constant step is provided, but unfortunately 1/2 is counted as an expression rather than a constant.
Coffeescript doesn't know completely what the expression 1/2 evaluates to. It could be Math.random() - .5 and it would depend on the particular running of the script.
Therefore, it's impossible for Coffeescript to know if the step is negative or positive, so it just keys the condition based on the relative positioning of start and end rather than on the sign of the constant step.
This is constant vs. expression, rather than integer vs. fraction. When the step is a constant (such as 2), CoffeeScript knows whether step is positive at compile time and outputs the correct code for that. When the step is an expression (such as 1/2), it needs to determine whether it is positive at runtime.
Unfortunately, CoffeeScript appears to recognize fractional number as expressions regardless of how they are written (0.5 or 1/2), so there's no simple way to avoid this problem.