question about fortran continue statement in a for loop - fortran

I am analyzing a code in fortran and have a simple question.
I want to know what the "continue" statement at 100 and 200 in the code below does.
Does it increment the i and j counters? If so, wouldn't if( .not. flg ) then condition contain the flg value that is the "last value" of flg in the loop j = i+1 to N?
do 100 i = 1, N-1
flg = .false.
do 200 j = i+1, N
if( "my condition" ) flg = .true.
200 continue
if( .not. flg ) then
! do something here.
endif
100 continue

AFAIK, CONTINUE in fortran does nothing.
It's used only for convenience in DO loop semantics.
This is not like C.

Th CONTINUE statement simply marks the end of the loop indicated by its numeric statement number - it doesn't increment anything. It certainly has no effect on flg in your code. There's a simple explanation of its use here.

This is old Fortran, which used typically used labeled continue statements to mark do loops. Fortran 90 and later provides an "end do" statements.

I am answering after more than three years since the question was asked in Feb'2010 because I saw the question now only and find that the answers would have been more detailed and complete. Indeed the logical variable flg shall have "last value" of flg in the loop j = i+1 to N because the inner do loop designated by label 200 shall run from j = i+1 to N for each value of i (= 1, N-1,1). The condition "my condition" must plays important role in not making this inner loop trivial otherwise.

Related

C for loop syntax understanding

I am doing a program for tic-tac-toe and i have a line with
for ( count = 1; count < 10 && winner == 0; count++ );
I referred to other programs and came up with this.
And I'm not very sure of what the entire line means. I have searched up online but I dont understand the meaning of initialization statement ( count = 1 ) and the test expression. And also want to clarify, count++ means increase count right?
Let's have a look at the structure of a for loop:
for ( init-statement; condition; iteration_expression) statement;
From cppreference, a for loop does the following:
Executes init-statement once, then executes statement and iteration_expression repeatedly, until the value of condition becomes false. The test takes place before each iteration.
For your case:
init statement: at the beginning count is initialized to 1
condition: check if count is less than 10 and you don't have a winner yet
iteration_expression: cout++ increases count by 1
statement: you haven't provided that, but it will be executed until the condition is false.
Syntax of for loop is
for(initialization; condition; increment/decrement){
statement;
}
initialization:
Before we start looping, we will initialize the variable to certain value.
In this case, you are initializing 'count' variable to 1
Condition:
In condition part, To stop the loop at certain point you have to provide some conditions.
In this case, condition is 'count<10 && winner==0'. Note that, you are using And(&&) operation so, loop will stop only after both of the conditions are satisfied.
increment/decrement:
Based on the problem, you can choose to increment or decrement the loop variable('count'). In this case, count++ means you are incrementing the count by 1 after each iteration.
for (initialize;condition;increment/decrement)
for loop means
you initialize the variable
you apply a condition to stop the for loop
you execute a single time the loop body (if the condition satisfied)
then you increase or decrease the value of that variable and go to step 2

Control Flow - if condition in Julia

I'm using Julia to solve an integer program. My variables are of the form z[i,j], i in N and j in N and N=10and z[i,j] is a binary variable.
In the first half of the program, I have a set of solutions for which z[1,2]= 1 and z[1,3]=1 and all other variables are zero. Now, I need to pass these values to another set S in such a way that S={1,2,3}. I tried to code it in Julia, but I couldn't get it in the right way. The following is the what I've tried.Here, z_value is the way that I declare my variables z[i,j]. Can someone please help me to make it correct?
for i in N
for j in N
z_value = Pair(i,j)
if z_value == 1;
push!(S, Pair(i,j))
print(S)
end
end
end
Thanks, Michael and Stefan, I got required set S by rearranging the code as
for i in N
for j in N
if getvalue(z[i,j]) == 1
push!(S, i)
push!(S, j)
end
end
end
Thanks for your effort!!

Why does a row of output (in a while loop) makes an invariant false?

I'm trying to understand the while loop more deeply. I understad the basics which is that a while repeats the statement as long as the test condition is true.
In the book Accelerated C++ the authors state the following:
//the number of blanks surrounds the greeting
const int pad = 1;
//total number of rows to write
const int rows = pad * 2 + 3;
//we have written r rows so far
int r = 0;
//setting r to 0 makes the invariant true
while (r != rows){
//we can assume that the invariant is true here
//writing a row of output makes the invariant false
std::cout << std::endl;
//incrementing r makes the invariant true again
++r;
}
//we can conclude that the invariant is true here
I don't get it, why does writing a row of output the invariant false, and then true again at the increment. Did the authors of the book made an mistake?
Edit - The variant is just an intellectual tool to understand a while loop easier. In this example the variant is "r = number of rows in output".
-----------------------what's an invariant---------------
What is an invariant?
Essentially, you answered your own question in your comment:
They only said "Writing a row of output causes the invariant to become
false, because r is no longer the number of rows we have written.
However, incrementing r to account for the row that was written will
make the invariant true again."
Summary:
the invariant is "r = number of rows written to output"
printing an empty line invalidates this invariant (since r is unchanged, but the number of rows written to the output has incremented by 1)
after incrementing r by one, the invariant is true again
The author didn't make a mistake
He just might have forgotten to mention what the invariant is.
Invariant != Loop condition.
An invariant (in your case most probably "the program has printed r lines") is a condition considered when formally talking about correctness of code (it's usually only given as a comment somewhere); it's not the same as the loop condition (which would be "r != rows" in your case!
What is the invariant the author is talking about? (I'm sure it
is stated somewhere.) From the comments, I'd guess that it is
something along the lines: r == number of rows
output. So when you output a row (line), this
becomes false until you update r to reflect the row you just
output.
There are, of course, other invariants: that r != rows, for
example. In this case, the output will not invalidate the
invariant, but the ++r might. Of course, there's no code
after the ++r in the loop, so it doesn't matter, and many
people would write this loop:
for ( int r = 0; r != rows; ++ r ) {
std::cout << std::endl;
}
so that this second invariant is never violated "within the
loop".

Understanding shorthand C++ [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have this code in my C++ book, and I am unsure what this code means:
for ( ; counter < fooCnt &&
(toLower(array[counter].getFooTitle()).find(x) == string::npos)
; counter++);
This is all on one line, Is there another way this code could be written? I do not understand also why is there a ";" before a variable in the beginning of the for loop....
clause 1 in a for-loop is optional. It says to loop until array[counter].getFooTitle()).find(x) is not equal to string::npos or counter >= fooCnt
&& is the short-circuit AND operator. Go back to your truth tables if your forgot this part.
counter < fooCnt && (toLower(array[counter].getFooTitle()).find(x)==string::npos) is expression-2 and counter++ is expression-3
counter is incremented thusly.
in 6.8.5.3 of the C standard:
1774 The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows:
1775 The expression >expression-2 is the controlling expression that
is evaluated before each execution of the loop body.
1776 The expression expression-3 is evaluated as a void expression
after each execution of the loop body.
1777 If clause-1 is a declaration, the scope of any
identifiers it declares is the remainder of the declaration and the
entire loop, including the other two expressions;
1778 it is reached in the order of execution before the first
evaluation of the controlling expression.
1779 If clause-1 is an expression, it is evaluated as a void
expression before the first evaluation of the controlling
expression.134)
1780 Both clause-1 and expression-3 can be omitted.
1781 An omitted expression-2 is replaced by a nonzero constant.
By the way, a for-loop can also be thought of like a while loop.
You could write it like this
int counter = 0;
bool IsNotFound = (toLower(array[counter].getFooTitle()).find(x)==string::npos);
for(;counter < fooCnt && IsNotFound;counter++)
{
// do stuff
//update IsNotFound for next iteration
IsNotFound =(toLower(array[counter].getFooTitle()).find(x) == string::npos);
}
It will loop only if IsNotFound is true.
It's the same as
for ( counter = counter; counter < fooCnt; counter++ ) {
if (toLower(array[counter].getFooTitle()).find(x) != string::npos) break;
}
e.g. counter goes from its current value, increasing by 1, until fooCnt. But if any of the titles are found, it stops early.
I will try to explain this line. At first a for loop looks like this for(init part; condition part; part for the next step). So the first ; means that the init part was skipped. Normally after the for statment is code which gets executed but in this case it was skipped with the colon.
in the condition check is this code:
counter<fooCnt && (toLower(array[counter].getFooTitle()).find(x)==string::npos)
if the condition counter<fooCnt is true the folowing code will be executed:
toLower(array[counter].getFooTitle()).find(x)==string::npos
at least after every loop the counter is increaded.
counter++
Is there another way this code could be written?
It might be clearer as
while (counter < fooCnt &&
(toLower(array[counter].getFooTitle()).find(x)==string::npos))
{
++counter;
}
i.e. while we haven't reached the limit, and we haven't found x, move on to the next one. Equivalently, loop until we reach the limit or we find x.
I do not understand also why is there a ";" before a variable in the beginning of the for loop
The for statement has three clauses, as in
for (int i = 0; i < n; ++i)
The first declares and/or initialises variables to be used in the loop - it can be empty if, as here, you don't want any. The second is evaluated before each iteration to decide whether to continue - it can be empty if you always want to continue. The third is evaluated after each iteration - it can be empty if there's nothing to update between iterations.
Yeah that's pretty ugly. I would break it down a bit.
int i = 0;
for(; i < fooCnt; ++i) {
auto lowcase = toLower(array[i].getFooTitle());
if(lowcase.find(x) != string::npos) {
break;
}
}

Why doesn't this fortran code work?

Hey, I wrote this (fortran) with the aim of finding the minimum spanning tree of a bunch of points (syscount of them). I know for a fact that this approach works, since i wrote it in javascript earlier today. js is slow though, and i wanted to see how much faster fortran would be!!
only problem is it's not working, i'm getting an annoying error;
prims.f95:72.43:
if((check == 1) .and. (path(nodesin(j))(k) < minpath)) then
1
Error: Expected a right parenthesis in expression at (1)
What the hell is that about?! the 43rd character on the line is the "h" of "path"
nodesin(1) = 1
do i = 1,syscount-1
pathstart = -1
pathend = -1
minpath = 2000
do j = 1,i
do k = 1, syscount
check = 1
do l = 1, i
if(nodesin(l) == k) then
check = 0
end if
end do
if((check == 1) .and. (path(nodesin(j))(k) < minpath)) then
minpath = path(nodesin(j))(k)
pathstart = nodesin(j)
pathend = k
end if
end do
end do
nodesin(i+1) = pathend
minpaths(i)(1) = pathstart
minpaths(i)(2) = pathend
end do
Also, i'm fairly new to fortran, so i have a few other questions;
can i use && instead of .and. ?
is there a versions of the for(object in list){} loop found in many other languages?
is there a verion of the php function in_array ? i.e. bool in_array(needle,haystack), and if there is, is there a better way of doing it than:
check = false
Asize = size(array)
do i = 1, Asize
if(array(i) == needle) then
check = true
end if
end do
then to using the check variable to see if it's there?
(I haven't posted anything on stackoverflow before. please don't get angry if i've broken loads of etiquette things!)
It looks like you have defined path and minpaths as two-dimensional arrays. Multi-dimensional arrays are accessed differently in Fortran when compared to C-like languages. In Fortran you separate the indices by commas within one set of parentheses.
I'm guessing by the use of these variables they are integer arrays. Here is how you access elements of those arrays (since you didn't share your variable declarations I am making up the shape of these arrays):
integer :: path(n1, n2)
integer :: minpaths(n3, 2)
your if statement should be:
if((check == 1) .and. (path(nodesin(j), k) < minpath)) then
your access to minpaths should be:
minpaths(i, 1) = pathstart
minpaths(i, 2) = pathend
Also, if you are not using IMPLICIT NONE I recommend you consider it. Not using it is dangerous, and you are using variable names that are close to each other (minpath and minpaths). You could save hours of hair pulling debugging by using IMPLICIT NONE.
While .EQ. can be replaced with ==, there is still only .AND.
For your code block to check whether a "variable is there", you can use "where" and have much shorter code!
In Fortran >= 90 statements and functions can operate on arrays so that explicit loops don't have to be used as frequently.
There is no for (object in list), but using the where statement can do something very similar.
Many of the intrinsic functions that act on arrays also take masks as optional arguments to selectively operate.
I suggest reading a book to learn about these features. I like the one by Metcalf, Reid and Cohen. In the meantime, the second Wikipedia article may help: http://en.wikipedia.org/wiki/Fortran_95_language_features