fortran read statement not stopping - arrays

program not stopping to read "ar". help please. even after allocating that it has definite number of elements. what may be the reason? is there something a could have missed?
program summer_a39
implicit none
integer:: n, i, l, k
integer, allocatable, dimension(:)::ar
print*, 'Enter size of array:'
read*, n
allocate (ar(n))
print*, 'Enter values:'
read*, ar
l=1
3 do i=l,n-1
if (l==n) then
goto 4
end if
if (ar(i)<=ar(i+1)) then
goto 1
else
goto 2
end if
end do
1 do i=l,n-1
do while (ar(i)<=ar(i+1))
k=k+1
end do
l=k
end do
print*, 'Increases to', l
goto 3
2 do i=l,n
do while (ar(i)>=ar(i+1))
k=k+1
end do
l=k
end do
print*, 'Decreases to', l
goto 3
4 print*, 'The End'
deallocate(ar)
end program

Uhm... Wow... Well...
That code makes no sense at all.
I hate to say it, but you still have a lot of learning and understanding to do.
First of all: STOP USING GOTO. It breaks the code flow and makes reading it a mess.1)
Secondly: Even without checking, I'm confident that the read statement is not the reason your program hangs. It hangs between the various loops.
Even without the goto statements, this snippet alone is a surefire way to get the program to hang:
do while (ar(i)>=ar(i+1))
k=k+1
end do
This loop keeps repeating for as long as ar(i) is larger or equal to ar(i+1) -- but in the body of the loop, neither value changes (only k, but k is not part of the condition). So if the condition is true once, it will stay true forever, and the loop will never ever terminate.
Then you keep jumping back to the beginning of a loop. Each time you do that, the loop starts again from scratch. Again, you never come to a conclusion.
I contemplated showing how to use subroutines to do what I think you want to do, but I thought better of it. You need a lot more time to understand what's going on, and I suggest you find some dedicated resources that teach programming.
It doesn't have to be Fortran specific, any tutorial for any procedural language will help you understand program flow, which is what you need to analyse this mess.
1) a good programmer might know when to use goto. You are not a good programmer yet.

After your comments to my previous answer, I got a better idea of your situation.
Here's what I understand so far:
You have an exercise for a Fortran training/lessons/etc.
The exercise is to create a program that takes as input an array of arbitrary length, and then prints out the final values of each monotonic sequence in that array. So for example, if the input were 4 3 7 2 1 4 6 3 5 10, then the output should be something like:
Starts with 4
Decreases to 3
Increases to 7
Decreases to 1
Increases to 6
Decreases to 3
Increases to 10
The end
Part of the exercise is that you should make use of the GOTO command.
So here's my updated answer:
This is not a homework service, we won't solve the issue for you. Then again, you didn't ask for that, so that's okay.
Your issue is not the read*, ar command. You can test this out easily by just adding a print*, ar right below it, it will print.
Your issue is that there is an infinite loop inside your code (actually, there are several), some because you use DO WHILE loops where the condition never changes in the iteration, some because you jump out of one loop to the beginning of another, which resets the initial conditions.
Here are some hints for your exercise:
Create a single variable for the index of the array that you're currently looking at.
Create two loops, one for increasing this index as long as the next value in the array is larger, and one as long as the next value is smaller. Check that you don't increase the index beyond the range of the array.
Do not jump from inside of any loop
Do not jump into the middle any loop.
At the end of either loop, think about what you learned about the array, and were to jump to from there.
Make sure that you know that the algorithm will eventually stop.
And finally, there's no harm in using lots of print* statements during debugging to make you understand what the program is actually doing.

Related

what happens if the for loop starts and ends at the same value?

say I have pseudo code that says :
for 1 to 1 do 'something'
would the for loop iterate through once and do 'something' and then fail, or would the loop fail straight away and the 'something' never get executed?
The question is analyse the complexity in relation to n, of this pseudo code:
for i := 1 to 1 do
for j := n - n^2 to n^2 - 1 do
k = 0;
As a pseudo code, for 1 to 1 should actually execute once, simply going by the notion that intuitively, for 1 to 2 in pseudo code should execute twice.
If you could share the context where you observed this or the algorithm itself, then perhaps, we could help more. Else this might turn out to be an XY Problem.
Edit:
As per the updates, in my opinion, the first loop simply exists to see if the reader really understands the notion of complexity. And it should be safe to assume, the first loop executes only once.

Subscripts going out of range in an array

Here the subscripts of the array are out of range.
int a[10], i;
for (i = 1; i <= 10; i++)
a[i] = 0;
printf("India");
The output is an infinte loop and printf statment doesnt get executed. here's what written in K N King:
When i reaches 10. the program stores 0 into a [10] . But a [10] doesn’t exist.
so 0 goes into memory immediately after a [9] . If the variable i happens to follow
a [9] in memory—as might be the case—then i will be reset to O. causing the
loop to start over.
Can anyone explain it ?
The idea that this will form an infinite loop is based on an assumption about how the variables will be laid out in memory. In particular, it assumes that because i is defined immediately after a, that it will also be allocated in memory immediately after a.
That's certainly not guaranteed, but it equally certainly could happen. If it does, then the write to a[10] may actually overwrite i. Since it's writing 0 into the nonexistent a[10], doing so actually writes 0 into i. Then when the condition in the loop checks that i <= 10, that's true, so the loop continues -- and each time i gets to 10, it's immediately overwritten with 0 before the loop condition is evaluated, so the loop re-starts from the beginning.
As far as either the C or C++ standard cares, it's just undefined behavior--when the code writes past the end of the array anything can happen. It might do what somebody expects, or might might do something entirely different and unrelated that doesn't seem to make sense at all. The compiler is free to emit code that does pretty much anything in such a circumstance (or it could, for example, diagnose it as an error, and emit no code at all).
To give some idea of what conforming behavior could be: early versions of gcc had code to detect a specific case of implementation-defined behavior (pretty much like undefined behavior, except the implementation has to document what it does). In this case, the documented behavior was fairly complex. The compiler would attempt to do each of the following in order (and stop at the first one that succeeded):
run nethack (a game)
run rogue (another game)
start emacs, and have it execute a towers of hanoi simulation
print out "You are in a maze of twisty little passages, all alike".
I could be getting the order of those a bit wrong (this was a long time ago), but you get the idea. The result had nothing to do with anything a reasonable person would be likely to expect.

What is the iteration error in the loop?

loop
if rising_edge (CLOCK) then
fcounter := fcounter+1;
end if;
A<=fcounter(6); --fa=fclock/2^6
if rising_edge (A) then
counter_A:= counter_A+1;
end if;
CIKIS<=A; --40 consecutive "1" consignment to DIN for STARTUP RESET
exit when counter_A=101000; --40
end loop;
ISE gives "ERROR:Xst:1312 - Loop has iterated 64 times. Use "set -loop_iteration_limit XX" to iterate more." What does that mean and what should i do to get rid of it?
Unbounded loops are not generally synthesizable outside of generating constants. The error is telling you that the loop has iterated beyond the preset limit that guards against infinite loops. Increasing the limit will not fix anything because what you have described doesn't map naturally to hardware with the current crop of synthesis tools.
You need to restructure your logic to inhibit that block of code with an enable that is deactivated when the counter reaches its terminal value rather than use a loop.
Synthesizable constructs can't have compile time unbounded loops like this, they are only to be used in testbench code. The reason is that when they expand into hardware, something like this would require infinite resources (which you don't have). You seem to be trying to write this like a piece of software. When using a HDL, you need to be thinking of how it translates into hardware (assuming you plan to synthesize). Instead you might look at using a process where all activity happens inside an "if rising_edge(clock)", and use signals to explicitly use flip flops as opposed to variables which could go either way. It isn't entirely clear to me if you're trying to count when your fcounter rolls over 40 times (what you currently do) or when your fcounter exceeds 0111111 for 40 clock cycles, but you can use a signal indicating the state for either case instead of an exit statement, and an if/elsif statement on that signal to do something else when you don't want to have process counting. Sorry for the poor formatting, short on time.

Write array to file by columns

Is there a way to write columns to a file one by one? For example, I would like to write:
write(1,*) 1
write(1,*) 2
And then write (possibly in another subroutine)
write(1,*) 3
write(1,*) 4
in such a way that will produce an output file in the format:
1 3
2 4
without combining the arrays (e.g.)
write(1,*) 1,3
write(1,*) 2,4
I'm thinking that there may be a way to move the "pointer" (of file location) back to the beginning and add spaces or something, but I really have no idea if this is possible. Any help is greatly appreciated!
So far, this is my attempt to make a subroutine to make this work:
subroutine writeArrayToNthColumn(arr,u,n)
implicit none
real(dpn),dimension(:),intent(in),target :: arr
real(dpn),dimension(:),pointer :: parr
integer,intent(in) :: u,n
integer :: i,s
s = size(arr)
allocate(parr(s))
parr = arr
rewind(u)
if (n.eq.1) then
do i=1,s
write(u,'(1F20.10)') parr(i)
enddo
else
do i=1,s
write(u,'(1F40.10)') parr(i)
enddo
endif
end subroutine
But upon calling the subroutine a second time, the first column is deleted..
The comments above from George, and High Performance Mark are exactly right. I'm posting this as an answer, because it has source code, but it should be considered an extended comment, whose only purpose is to demonstrate how right they are.
You can do this, in a sense, although under no circumstances should you do so. Moving around within a file - a so called seek - is an incredibly expensive operation. On a local hard drive, this can take 10-20 milliseconds or so per operation (eg, in this case, per entry); if you are using a large shared system it can be much larger than that.
Moving things around in memory, however, is much less expensive. A well-tuned transpose function will do most of the moving around in cache, with operation that take a few nanoseconds; the data will get batched into and from main memory in fewer operations which each take ~100ns or so. Even a seek on a modern SSD will take something like dozens of microseconds.
In other words, there is no situation in which doing the transpose in your file I/O will be less than hundreds of times slower than doing the transpose in memory (and then back if needed). You still have to do the file/IO in the end, but if you are writing out in one batch, this is much faster.
So let's try some examples in Fortran, since that's the language of this question. Fortran, sensibly, makes this somewhat harder by making it difficult to access file locations directly, and even to explicitly output in carriage returns; I've used direct-access IO here and hard-coded in a non-portable way of doing the carriage returns.
Here's doing the transpose in your I/O:
program badiotxt
implicit none
integer, parameter :: asize = 200
integer, dimension(asize, asize) :: a
integer :: i, j
integer :: record
forall (i=1:asize, j=1:asize)
a(i,j) = (i-1)*asize+j
end forall
open(unit=7,file="bad.txt", status="new", access="direct", &
form="formatted", action="write", recl=10)
do j=1,asize
do i=1,asize-1
record=(j-1)*asize+i
write(7, rec=record, fmt="(2X,I7,1X)") a(i,j)
enddo
enddo
i = asize
do j=1,asize
record=(j-1)*asize+i
write(7, rec=record, fmt="(1X,I7,A1,A1)") a(i,j), char(13), char(10)
enddo
close(7)
end program badiotxt
and here's one done by transposing the array:
program goodiotxt
implicit none
integer, parameter :: asize = 200
integer, dimension(asize, asize) :: a
integer :: i, j
integer :: record
forall (i=1:asize, j=1:asize)
a(i,j) = (i-1)*asize+j
end forall
open(unit=7,file="good.txt", status="new", &
form="formatted", action="write")
a = transpose(a)
do i=1,asize
write(7,fmt="(1X,200(2X,I7))") (a(i,j), j=1,asize)
enddo
a = transpose(a)
close(7)
end program goodiotxt
Note that the good version is cleaner code, and that these are not large arrays by any stretch. The resulting times are:
Transpose in memory: 0.05s
Transpose on disk: 1.70s
Slowdown: 34x
I've a bit more time now than when I first commented on this question. This is, however, an extended comment rather than a full-blown answer.
Even IF (that's a big if) I had to write a data file column-by-column I wouldn't use direct access IO as #Jonathan Dursi's answer proposes. That (direct access IO) is for situations where it is difficult to predict, at the time the code is written, the ordering of writes to a file. In OP's case the ordering of writes seems to be entirely predictable.
I would:
Write column 1, element-by-element, to a file.
2.1 Open a second file for writing, and the first file for reading.
2.2 Read the first line from the first file, write it to the second file and append the first element of the next column.
2.3 Repeat 2.2 until I got to the end of the column/file.
2.4 Close the second file (which now contains columns 1 and 2) and the first file.
3.1 Open the second file for reading, and perform a destructive open on the first file for writing.
... by now you should have got the picture.

Nested Loop / Loop Control tutorial [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I'm looking for a good tutorial on writing and designing loops. I understand the basics of loops but nested loops give me a lot of trouble. To give you and idea, the following pattern below was kind of difficult for me to figure out.
1
12
123
1234
12345
123456
Loops
A loop is a construct that enables a set of instructions to be executed more than once.
There are several loop constructions:
zero or more
These loops have the check at the begining of an iteration and as such will be executed 0 or more times. A while loop is an example.
one or more
These loops have the check at the end of the iteration and as such will be executed at least once. A do while loop is an example.
Loops with counters
These loops have a counter that counts from a certain number to an other number. The number can be used inside the loop (for example to access a field of an array).
Loops with an iterator
These loops use an iterator to loop through a certain structure.
Endless loops
These loops have no end. But of course nothing is forever, so the loop often contains a hidden mechanism.
Nested loops
If you understand single loops, nested loops can be difficult. But you need to focus on one loop at a time.
Lets take your example:
1
12
123
1234
12345
123456
Ok, lets first look at the lines.
The first line has a single 1
The second line counts from 1 to 2
The third line counts from 1 to 3
...
Generally: the n th line counts from 1 to n.
Great, no we have the individual line. But let's now look at all lines.
the first has n=1
the second has n=2
the third has n=3
...
Hm, so we can use the loop counter of the outer loop as the n in the inner loop:
for n = 1 to 6
s = ''
for i = 1 to n // use the loopcounter of the outer loop
s = s + char(i)
end for
out s
end for
Check out:
http://mathbits.com/mathbits/compsci/looping/nested.htm
http://tldp.org/LDP/abs/html/nestedloops.html
http://www.actionscript.org/resources/articles/5/1/The-power-of-nested-loops/Page1.html
In general (language-neutral) terms, the basic logic is quite straightforward. Where it can get more complex is if an inner loop terminates early & the manner of the break. It may cause the outer loop to move to the next value, or it may completely exit the outer loop as well.
The best way to learn this is to try out different cases to see how they behave, and read up on the ways to exit from loops.
How about these:
Nested Loops
The Power of Nested Loops
or on YouTube "SQL Joins, nested loops and all that in less than 6 minutes" at http://www.youtube.com/watch?v=SmDZaH855qE
I don't remember seeing any "loop design" centred tutorials when I was learning to program.
You will get a grasp of loops if you just start tackling on different problems and algorithms. Look for matrix problems, you will need nested loops there for instance...
I'm unaware of any tutorials on this subject, but I suggest you try Google. Also, the fact that you were able to figure out your example probably means that you don't need a tutorial as much as you need practice. Nested loops are somewhat mind-warping when you first encounter them. You might also want to look for references/tutorials pertaining to recursion, which is a related concept. Remember, practice makes perfect!
Check out the MIT Course Material. Also consider getting a Safari subscription, a cheap way of getting some good learning books.
This MIT course points to Loops on the python wiki.
I found that working it out on paper, listing the variables helps in learning how this works.
declare
s varchar2(10);
begin
for n in 1..5 loop
s:='';
for i in 1..n loop
s:=s||(i);
end loop;
dbms_output.put_line(s);
end loop;
end;

Resources