Home > Archive > Fortran > May 2005 > Help.. subroutines etc..
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Help.. subroutines etc..
|
|
| mysticorion@gmail.com 2005-05-19, 8:58 pm |
| C
C askisi 3
C
Program lol
DIMENSION X(100)
DIMENSION Y(100)
READ (*,*) N,(X(I),I=1,N)
READ (*,*) M,(Y(I),I=1,M)
Subroutine sort(A,Z,temp,i,j,min)
i=1
j=1
DO 10 i=1,(A-1)
min = i
DO 20 j=i+1,A
if (Z(min).gt.Z(j)) then
min = j
end if
temp = Z(i)
Z(i) = x(min)
Z(min) = temp
20 continue
10 continue
end
call sort(N,X,temp,i,j,min)
call sort(M,Y,temp,i,j,min)
C sugxoneush
DO 30 j=1,(M+N)
DO 40 i=1,N
B(i) = X(i)
40 exit
B(j+N) = Y(j)
30 continue
T=M+N
C taksinomisi
N1=N-1
DO 15 I=1,N1
AMIN=B(I)
M=I+1
DO 25 K=M,N
IF (AMIN.LE.X(K)) GO TO 25
Z=AMIN
AMIN=B(K)
B(K)=Z
25 CONTINUE
15 B(I)=AMIN
C ektupwsh timwn
write (*,*) (B(I),I=1,M+N)
stop
end
I've written this prog. and i cant find where i ve done mistake! Can
anybody help ? It uses sort selection... then merging and sorting...
| |
|
| at the very least you have to define sort to be recursive
recursive subroutine sort(.....
and an IMPLICIT NONE wouldn't harm either
Joost
| |
| Richard E Maine 2005-05-19, 8:58 pm |
| In article <1116531194.081235.228120@z14g2000cwz.googlegroups.com>,
mysticorion@gmail.com wrote:
> I've written this prog. and i cant find where i ve done mistake! Can
> anybody help ? It uses sort selection... then merging and sorting...
One of the standard universal pieces of advice when asking for help: Say
what your problem is. Don't just post a bunch of code and ask what is
wrong. Presumably you tried the code and had a problem. So tell people
exactly what you did and what the problem was. Otherwise, you are
forcing them to do extra work to deduce what your problem was before
they can work on solving it. Asking someone to do unnecessary extra work
lowers the odds of them bothering to do part you really need from them.
You probably got some kind of compiler error message. Even if you didn't
understand the message, the people most likely to help you probably
will. I bet that the compiler was more helpful than just saying "You
made a mistake. Fix it." Pass on that help.
Off the top of my head, I do see one problem here.
Your subroutine is sitting in the middle of the main program. You can't
do that. A subroutine has to go in one of two places. Either
1. Put the subroutine separately, after the main program. That's
completely after it, namely after the "end" statement.
2. If you are using a compiler capable of at least f90, you can make the
subroutine an internal one. You didn't say anything about the compiler
you are using (another good thing to mention, I might add), but the code
looks like f77 style, so maybe your compiler won't do f90. On the other
hand, you could be using f77 style with an f90 compiler; that works
fine, so I can't tell for sure. Anyway, in f90 or later, to make the
subroutine internal, put a "contains" statement right before the "end"
in the main program and then put the subroutine after that "contains".
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| epc8@juno.com 2005-05-19, 8:58 pm |
| mysticorion@gmail.com wrote:
> C
> C askisi 3
> C
> Program lol
> DIMENSION X(100)
> DIMENSION Y(100)
> READ (*,*) N,(X(I),I=1,N)
> READ (*,*) M,(Y(I),I=1,M)
> Subroutine sort(A,Z,temp,i,j,min)
> i=1
> j=1
> DO 10 i=1,(A-1)
> min = i
> DO 20 j=i+1,A
> if (Z(min).gt.Z(j)) then
> min = j
> end if
> temp = Z(i)
> Z(i) = x(min)
> Z(min) = temp
> 20 continue
> 10 continue
> end
>
> call sort(N,X,temp,i,j,min)
> call sort(M,Y,temp,i,j,min)
> C sugxoneush
> DO 30 j=1,(M+N)
> DO 40 i=1,N
> B(i) = X(i)
> 40 exit
> B(j+N) = Y(j)
> 30 continue
> T=M+N
> C taksinomisi
> N1=N-1
> DO 15 I=1,N1
> AMIN=B(I)
> M=I+1
> DO 25 K=M,N
> IF (AMIN.LE.X(K)) GO TO 25
> Z=AMIN
> AMIN=B(K)
> B(K)=Z
> 25 CONTINUE
> 15 B(I)=AMIN
> C ektupwsh timwn
> write (*,*) (B(I),I=1,M+N)
> stop
> end
>
> I've written this prog. and i cant find where i ve done mistake! Can
> anybody help ? It uses sort selection... then merging and sorting...
1. As Richard Maine has indicated, you need to move your subroutine
after the main program.
2. You are not using i,j,temp and min outside of the subroutine, so
they don't need to be in the argument list.
3. In subroutine sort, i and j are initialized by the DO loops, you
don't need to set each to 1.
4. The type of A is undeclared, so it defaults to REAL. I don't know if
this causes a problem, but I would normally make this argument of type
INTEGER.
5. B is not DIMENSIONED anywhere.
6. You are mixing DO loops which allow expressions to define the limits
of the loop and DO loops which use new variables instead of
expressions. I think expressions have been allowed in the limits for DO
loops for many years.
7. If you are going to write SORT as a subroutine, why not write MERGE
as a subroutine too? Better yet, find a decent textbook with a well
documented set of subroutines. (This program is obviously a composite
of code from several places.)
7a. If you ever do get it working, consider a different method of
sorting your data. Unless you know what you are doing, writing your own
sort routine will give you a program that is very slow on large data
sets.
8. Find a compiler like Watfor or Salford and use its diagnostics.
9. Sit down and bench check the code. Run through some small example
data sets as if you were the computer and see what happens.
I hope this helps.
| |
| Richard Maine 2005-05-20, 4:00 am |
| "epc8@juno.com" <epc8@juno.com> writes:
> 6. You are mixing DO loops which allow expressions to define the limits
> of the loop and DO loops which use new variables instead of
> expressions. I think expressions have been allowed in the limits for DO
> loops for many years.
Yes. That was "new" to f77. I didn't actually look at the code very
carefully (the subroutine in the middle just jumped right out at me),
but now that you mention it, some of the DO loops look more like f66
style than the f77 style that I mentioned. Those temporary variables
just for DO loop limits are "classic" f66.
--
Richard Maine
email: my last name at domain
domain: summertriangle dot net
| |
| epc8@juno.com 2005-05-20, 4:00 am |
|
epc8@juno.com wrote:
> mysticorion@gmail.com wrote:
Can[color=darkred]
sorting...[color=darkred]
>
[my previous suggestions snipped]
I've re-considered a bit as some of what I suggested was minor given
the program as a whole.
After moving subroutine sort to the end of the source file, other
problems remain. A is of the wrong type - it must be INTEGER and Z is
not dimensioned so you need to insert
integer A
dimension Z(A)
at the top of the subroutine.
Also you must change X(min) to Z(min).
B is an array but it is not dimensioned, so you need DIMENSION B(200)
at the top of the program.
EXIT makes no sense where it is - you must change EXIT to CONTINUE.
Once you make this change, it is obvious that the bounds on the DO 30
loop is wrong. It should be 1 to M not (M+N) - without correction J
goes out of bounds on the Y array.
Also it is obvious that the DO 30 and DO 40 loops can be separated.
Once this is done, the program compiles and runs using G77 (2.95 MinGW
on XP) but of course it gives incorrect results!
| |
| Ron Shepard 2005-05-20, 4:00 am |
| In article <1116531194.081235.228120@z14g2000cwz.googlegroups.com>,
mysticorion@gmail.com wrote:
> DO 40 i=1,N
> B(i) = X(i)
> 40 exit
Among the things that have already been mentioned, I think the above
loop is equivalent to the statement
B(1) = X(1)
(i.e. it exits after the first iteration) which is probably not what
was intended.
$.02 -Ron Shepard
| |
| epc8@juno.com 2005-05-20, 4:00 am |
| Ron Shepard wrote:
> In article <1116531194.081235.228120@z14g2000cwz.googlegroups.com>,
> mysticorion@gmail.com wrote:
>
>
> Among the things that have already been mentioned, I think the above
> loop is equivalent to the statement
>
> B(1) = X(1)
>
> (i.e. it exits after the first iteration) which is probably not what
> was intended.
>
> $.02 -Ron Shepard
Untangling the DO 30 and DO 40 loops helps as does changing the EXIT to
CONTINUE.
Note also that X(K) should be changed to B(K) in the the DO 25 loop.
The heart of the program reduces to these two fragments:
c this just re-sorts the contents of X
do 15 i=1,n-1
amin=b(i)
do 25 k=i+1,n
if (amin.le.b(k)) go to 25
z=amin
amin=b(k)
b(k)=z
25 continue
15 b(i)=amin
subroutine sort(a,z)
integer a
dimension z(a)
do 10 i=1,a-1
min = i
do 20 j=i+1,a
if (z(min).gt.z(j)) then
min = j
end if
temp = z(i)
z(i) = z(min)
z(min) = temp
20 continue
10 continue
end
So when all is said and done, a working version of this program
actually reads in X and Y, sorts X, sorts Y, copies X followed by Y to
B, re-sorts the first part of B, then outputs B - definitely not a
sort/merge at all.
| |
| mysticorion@gmail.com 2005-05-20, 3:59 pm |
| Many thanks to everybody ! Sorry for not being sto specific in my
previous post. My english doesnt help me at all.. I made the
corrections you suggested and I ran the program :) I have only one more
question ! In the end of it i have to print all the items ! 10 items
einai each line ! how can i do this ?? The corrected program is:
C
C askisi 3
C
Program lol
DIMENSION X(100)
DIMENSION Y(100)
DIMENSION B(200)
READ (*,*) N,(X(I),I=1,N)
READ (*,*) M,(Y(I),I=1,M)
call sort(N,X)
call sort(M,Y)
C MERGINS ARRAYS
DO 30 j=1,M
DO 40 i=1,N
B(i) = X(i)
40 continue
B(j+N) = Y(j)
30 continue
C SORTING
do 15 i=1,n-1
amin=b(i)
do 25 k=i+1,n
if (amin.le.b(k)) go to 25
z=amin
amin=b(k)
b(k)=z
25 continue
15 b(i)=amin
C PRINTING
write(*,*) (B(I),I=1,M+N)
stop
end
subroutine sort(a,z)
integer a
dimension z(a)
do 10 i=1,a-1
min = i
do 20 j=i+1,a
if (z(min).gt.z(j)) then
min = j
end if
temp = z(i)
z(i) = z(min)
z(min) = temp
20 continue
10 continue
end
| |
|
| To print it nice, you can make something like:
do 100 i = 1, n !maybe n+m in your case
write(*,"(X,F8.3)",ADVANCE='NO') B(i)
if (mod(i,10) .eq. 0) write(*,*)
100 continue
if (mod(n,10) .gt. 0) write(*,*) !again, n+m instead n in your case.
| |
| epc8@juno.com 2005-05-20, 8:57 pm |
| mysticorion@gmail.com wrote:
> Many thanks to everybody ! Sorry for not being sto specific in my
> previous post. My english doesnt help me at all.. I made the
> corrections you suggested and I ran the program :) I have only one
more
> question ! In the end of it i have to print all the items ! 10 items
> einai each line ! how can i do this ?? The corrected program is:
>
> C
> C askisi 3
> C
> Program lol
> DIMENSION X(100)
> DIMENSION Y(100)
> DIMENSION B(200)
> READ (*,*) N,(X(I),I=1,N)
> READ (*,*) M,(Y(I),I=1,M)
> call sort(N,X)
> call sort(M,Y)
> C MERGINS ARRAYS
> DO 30 j=1,M
> DO 40 i=1,N
> B(i) = X(i)
> 40 continue
> B(j+N) = Y(j)
> 30 continue
> C SORTING
> do 15 i=1,n-1
> amin=b(i)
> do 25 k=i+1,n
> if (amin.le.b(k)) go to 25
> z=amin
> amin=b(k)
> b(k)=z
> 25 continue
> 15 b(i)=amin
> C PRINTING
> write(*,*) (B(I),I=1,M+N)
> stop
> end
> subroutine sort(a,z)
> integer a
> dimension z(a)
> do 10 i=1,a-1
> min = i
> do 20 j=i+1,a
> if (z(min).gt.z(j)) then
> min = j
> end if
> temp = z(i)
> z(i) = z(min)
> z(min) = temp
> 20 continue
> 10 continue
> end
Before you worry about the output format, are you sure the program is
correct?
Here is a sample run:
C:\g77>g77 -o foo.exe foo.f
C:\g77>foo
2 2 1
3 4 0 3
1. 2. 3. 0. 4.
C:\g77>
There are two bugs left in the program and one error that slows the
program down for no good reason.
First, subroutine sort does not work correctly. As you can see, array X
is sorted properly but array Y is not. One way to fix this is to move
the three lines that swap z(i) and z(min) out of the inner loop.
Putting them between lines 20 and 10 gives:
C:\g77>g77 -o foo1.exe foo1.f
C:\g77>foo1
2 2 1
3 4 0 3
1. 2. 0. 3. 4.
C:\g77>
At this point, subroutine sort looks like a selection sort. At the end
of each pass, the minimum value is put on the bottom.
But the entire array is not sorted. Maybe you need to extend the limits
on the DO 15 and DO 25 loops, but why bother? You already have a
subroutine that sorts an array. (I hope it is correct now.)
Why not replace the lines between
C SORTING
and
C PRINTING with
call sort(M+N,B)
?
With these corrections made, the program gives
C:\g77>g77 -o foo2.exe foo2.f
C:\g77>foo2
2 2 1
3 4 0 3
0. 1. 2. 3. 4.
C:\g77>
Now I am more confident that the program is correct.
Again, there is one final change that I would make before worrying
about the output format. The DO 40 loop is inside the DO 30 loop. That
means that each time j is changed, all of array X is copied to the
first part of array B. Note that there is no overlap between the data
accessed by each loop, so we can separate them. This has two positive
effects. First, the program runs a bit faster. Since you are using a
selection sort, you probably do not care too much about execution
speed. Second, the program becomes easier to understand. It's now
obvious what you are doing.
So the last change would be to replace the lines between
C MERGINS ARRAYS
and
C SORTING
with
DO 40 i=1,N
B(i) = X(i)
40 continue
DO 30 j=1,M
B(j+N) = Y(j)
30 continue
The final program gives the same output:
C:\g77>g77 -o foo3.exe foo3.f
C:\g77>foo3
2 2 1
3 4 0 3
0. 1. 2. 3. 4.
C:\g77>
Good luck!
Elliot
| |
|
| Well, a good merging could help more. Why sort X, and Y, and then merge
them, and sort again? Doing the correct marge, you wouldn't need to
sort again. You should marge something like this:
k = 1
m = 1
do 30 i = 1, N+1
do 40 j = k, M
if (i > N .or. X(i) > Y(j)) then
B(m) = Y(j)
m = m + 1
else
k = j
exit
endif
40 continue
if (i > N) exit
B(m) = X(i)
m = m + 1
30 continue
This would be fine if you make a subroutine with this procedure. (Test
it, I just write it here online, no time to test it myself :) )
|
|
|
|
|