# Getting started with loops

## Overview

Teaching: 60 min
Exercises: 30 min
Questions
• How do I get run the same piece of code repeatedly?

Objectives
• First objective.

To compute the current temperature of an element of `temp`, we need to add all the surrounding elements in `past_temp`, and divide the result by 4. And, essentially, we need to repeat this process for all the elements of `temp`, or, in other words, we need to iterate over the elements of `temp`. When it comes to iterate over a given number of elements, the for-loop is what we want to use. The for-loop has the following general syntax:

``````for index in iterand do
{instructions}
``````

The iterand is a function or statement that expresses an iteration; it could be the range 1..15, for example. index is a variable that exists only in the context of the for-loop, and that will be taking the different values yielded by the iterand. The code flows as follows: index takes the first value yielded by the iterand, and keeps it until all the instructions inside the curly brackets are executed one by one; then, index takes the second value yielded by the iterand, and keeps it until all the instructions are executed again. This pattern is repeated until index takes all the different values expressed by the iterand.

This for loop, for example

``````//calculate the new current temperatures (temp) using the past temperatures (past_temp)
for i in 1..rows do
{
//do this for every row
}
``````

will allow us to iterate over the rows of `temp`. Now, for each row we also need to iterate over all the columns in order to access every single element of `temp`. This can be done with nested for loops like this

``````//calculate the new current temperatures (temp) using the past temperatures (past_temp)
for i in 1..rows do
{
//do this for every row
for j in 1..cols do
{
//and this for every column in the row i
}
}
``````

Now, inside the inner loop, we can use the indices `i` and `j` to perform the required computations as follows:

``````//calculate the new current temperatures (temp) using the past temperatures (past_temp)
for i in 1..rows do
{
//do this for every row
for j in 1..cols do
{
//and this for every column in the row i
temp[i,j]=(past_temp[i-1,j]+past_temp[i+1,j]+past_temp[i,j-1]+past_temp[i,j+1])/4;
}
}
past_temp=temp;
``````

Note that at the end of the outer for-loop, when all the elements in `temp` are already calculated, we update `past_temp` with the values of `temp`; this way everything is set up for the next iteration of the main while statement.

Now let’s compile and execute our code again:

``````>> chpl base_solution.chpl -o base_solution
>> ./base_solution
``````
``````The simulation will consider a matrix of 100 by 100 elements,
it will run up to 500 iterations, or until the largest difference
in temperature between iterations is less than 0.0001.
You are interested in the evolution of the temperature at the
position (50,50) of the matrix...

and here we go...
Temperature at iteration 0: 25.0
Temperature at iteration 20: 25.0
Temperature at iteration 40: 25.0
Temperature at iteration 60: 25.0
Temperature at iteration 80: 25.0
Temperature at iteration 100: 25.0
Temperature at iteration 120: 25.0
Temperature at iteration 140: 25.0
Temperature at iteration 160: 25.0
Temperature at iteration 180: 25.0
Temperature at iteration 200: 25.0
Temperature at iteration 220: 24.9999
Temperature at iteration 240: 24.9996
Temperature at iteration 260: 24.9991
Temperature at iteration 280: 24.9981
Temperature at iteration 300: 24.9963
Temperature at iteration 320: 24.9935
Temperature at iteration 340: 24.9893
Temperature at iteration 360: 24.9833
Temperature at iteration 380: 24.9752
Temperature at iteration 400: 24.9644
Temperature at iteration 420: 24.9507
Temperature at iteration 440: 24.9337
Temperature at iteration 460: 24.913
Temperature at iteration 480: 24.8883
Temperature at iteration 500: 24.8595
``````

As we can see, the temperature in the middle of the plate (position 50,50) is slowly decreasing as the plate is cooling down.

## Exercise 1

What would be the temperature at the top right corner of the plate? The border of the plate is in contact with the boundary conditions, which are set to zero, so we expect the temperature at these points to decrease faster. Modify the code to see the temperature at the top right corner.

## Solution

To see the evolution of the temperature at the top right corner of the plate, we just need to modify `x` and `y`. This corner correspond to the first row (`x=1`) and the last column (`y=cols`) of the plate.

``````>> chpl base_solution.chpl -o base_solution
>> ./base_solution
``````
``````The simulation will consider a matrix of 100 by 100 elements,
it will run up to 500 iterations, or until the largest difference
in temperature between iterations is less than 0.0001.
You are interested in the evolution of the temperature at the position (1,100) of the matrix...

and here we go...
Temperature at iteration 0: 25.0
Temperature at iteration 20: 1.48171
Temperature at iteration 40: 0.767179
...
Temperature at iteration 460: 0.068973
Temperature at iteration 480: 0.0661081
Temperature at iteration 500: 0.0634717
``````

## Exercise 2

Now let’s have some more interesting boundary conditions. Suppose that the plate is heated by a source of 80 degrees located at the bottom right corner, and that the temperature on the rest of the border decreases linearly as one gets farther form the corner (see the image below). Utilise for loops to setup the described boundary conditions. Compile and run your code to see how the temperature is changing now.

## Solution

To get the linear distribution, the 80 degrees must be divided by the number of rows or columns in our plate. So, the following couple of for loops will give us what we want;

``````//this setup the boundary conditions
for i in 1..rows do
{
past_temp[i,cols+1]=i*80.0/rows;
temp[i,cols+1]=i*80.0/rows;
}
for j in 1..cols do
{
past_temp[rows+1,j]=j*80.0/cols;
temp[rows+1,j]=j*80.0/cols;
}
``````

Note that the boundary conditions must be set in both arrays, `past_temp` and `temp`, otherwise, they will be set to zero again after the first iteration. Also note that 80 degrees are written as a real numbe r 80.0. The division of integers in Chapel returns an integer, then, as `rows` and `cols` are integers, we must have 80 as real so that the quotient is not truncated.

``````>> chpl base_solution.chpl -o base_solution
>> ./base_solution
``````
``````
The simulation will consider a matrix of 100 by 100 elements, it will run
up to 500 iterations, or until the largest difference in temperature
between iterations is less than 0.0001. You are interested in the evolution
of the temperature at the position (1,100) of the matrix...

and here we go...
Temperature at iteration 0: 25.0
Temperature at iteration 20: 2.0859
Temperature at iteration 40: 1.42663
...
Temperature at iteration 460: 0.826941
Temperature at iteration 480: 0.824959
Temperature at iteration 500: 0.823152
``````

## Exercise 3

So far, `curdif` has been always equal to `mindif`, which means that our main while loop will always run the 500 iterations. So let’s update `curdif` after each iteration. Use what we have studied so far to write the required piece of code.

## Solution

The idea is simple, after each iteration of the while loop, we must compare all elements of `temp` and `past_temp`, find the greatest difference, and update `curdif` with that value. The next nested for loops do the job:

``````//update curdif, the greatest difference between temp and past_temp
curdif=0;
for i in 1..rows do
{
for j in 1..cols do
{
tt=abs(temp[i,j]-past_temp[i,j]);
if tt>curdif then curdif=tt;
}
}
``````

Clearly there is no need to keep the difference at every single position in the array, we just need to update `curdif` if we find a greater one.

``````>> chpl base_solution.chpl -o base_solution
>> ./base_solution
``````
``````The simulation will consider a matrix of 100 by 100 elements,
it will run up to 500 iterations, or until the largest difference
in temperature between iterations is less than 0.0001.
You are interested in the evolution of the temperature at the
position (1,100) of the matrix...

and here we go...
Temperature at iteration 0: 25.0
Temperature at iteration 20: 2.0859
Temperature at iteration 40: 1.42663
...
Temperature at iteration 460: 0.826941
Temperature at iteration 480: 0.824959
Temperature at iteration 500: 0.823152
``````

Now, after Exercise 3 we should have a working program to simulate our heat transfer equation. Let’s just print some additional useful information,

``````//print final information
writeln('\nFinal temperature at the desired position after ',c,' iterations is: ',temp[x,y]);
writeln('The difference in temperatures between the last two iterations was: ',curdif,'\n');
``````

and compile and execute our final code,

``````>> chpl base_solution.chpl -o base_solution
>> ./base_solution
``````
``````The simulation will consider a matrix of 100 by 100 elements,
it will run up to 500 iterations, or until the largest difference
in temperature between iterations is less than 0.0001.
You are interested in the evolution of the temperature at the
position (1,100) of the matrix...

and here we go...
Temperature at iteration 0: 25.0
Temperature at iteration 20: 2.0859
Temperature at iteration 40: 1.42663
Temperature at iteration 60: 1.20229
Temperature at iteration 80: 1.09044
Temperature at iteration 100: 1.02391
Temperature at iteration 120: 0.980011
Temperature at iteration 140: 0.949004
Temperature at iteration 160: 0.926011
Temperature at iteration 180: 0.908328
Temperature at iteration 200: 0.894339
Temperature at iteration 220: 0.88302
Temperature at iteration 240: 0.873688
Temperature at iteration 260: 0.865876
Temperature at iteration 280: 0.85925
Temperature at iteration 300: 0.853567
Temperature at iteration 320: 0.848644
Temperature at iteration 340: 0.844343
Temperature at iteration 360: 0.840559
Temperature at iteration 380: 0.837205
Temperature at iteration 400: 0.834216
Temperature at iteration 420: 0.831537
Temperature at iteration 440: 0.829124
Temperature at iteration 460: 0.826941
Temperature at iteration 480: 0.824959
Temperature at iteration 500: 0.823152

Final temperature at the desired position after 500 iterations is: 0.823152
The greatest difference in temperatures between the last two iterations was: 0.0258874
``````

## Key Points

• Use `for` statement to organise a loop.