I found a FORTRAN IV code for Fuzzy k means from the 1984 by Bell. I cannot post the article as it is in copyright.
But the following line does not flag an error in building the code.
1 READ(5.399,END=3)(Y(NS,J),J=1,ND) ! 00C83000
lt does throw an exception, but I would have thought at this very early command type the compiler should spot the error.
It does with standards checking:
t.f90(2): warning #6187: Fortran 2018 requires an INTEGER data type in this context. [5.399] READ(5.399,END=3)(Y(NS,J),J=1,ND)
In Fortran 66 (this code is actually F77, since END= is not in F66/FORTRAN IV), the unit is specified as being "an integer value". FORTRAN 77 says it is "an integer expression" - compilers with as long a lineage as Intel Fortran tend to give free conversion among numeric types in expressions.
If it were up to me, I would make this an unconditional error.
I am just entering and debugging the code at the moment, so I will post it in a few days.
The paper calls the code IBM Fortran IV. Although the paper is written in 1984.
They use a dimension title(20)
then use a format(20A4) to to read the title from unit 5. In Fortran IV or 77 how would the compiler know title(1) is an A4?
Also they are using the trick of writing the read format statements into the input data.
Line 15 is reading in the main vector elements,
Line 2 starts the count, it should be 0 not 1.
Line 19 should be Line 15
the end going to 3 should be a continue and not have to remember to decrement NS as you over counted. and why not add a vector length index to line 9 and do simple do loop.
Got to love the olden days, wooden ships, wooden legs and real beer.
EPS=.01 ! 00071000 NS=1 ! 000720CO LMAX=50 ! OOC73000 —00074000 !-------------------------------------------------------------- ! READ FEATURE VECTORS (Y(I.J)). 00075000 !-------------------------------------------------------------- READ(sRT,*) ICON,QQ,ND,KBEGIN,KCEASE ! 00076000 000770C0 2021 FORMAT(I1,F6.3,3I2) ! 00078000 WRITE(6,410) ! 00079000 410 FORMAT(///1H ,'*** *** BEGIN FUZZY C-MEANS OUTPUT *** ***') ! 00080000 WRITE(6,1459) (TITLE(III),III=1,20) ! 00081000 1459 FORMAT(10X,20A4///) ! 00082000 1 READ(sRT,*,END=3)(Y(NS,J),J=1,ND) ! 00C83000 399 FORMAT (2F1.0) ! 00084000 WRITE(6,12738)NS, (Y(NS,J),J=1,ND) ! 00C85000 12738 FORMAT(I4, 2(10X,10(F7.2,1X)/)) ! 00086000 NS=NS+1 ! 00087000 GO TO 1 ! 00C88000 3 NS=NS-1 ! 00089000 NDIM=ND ! 00090000 NSAMP=NS ! 00091000
I understand the good intentions that motivate your suggested changes, but they will not work without further changes.
Lines are being read from a data file, and the number of records in the file is not known in advance. The code is set up to end reading only when a READ fails because EOF occurs. The last READ fails, so NS has to be decremented after that happens.
You could read each record into temporary variables, followed by incrementing NS and copying the just-read data into the arrays.
In Modern Fortran, you would probably allocate the arrays to match the number of records. One way to do that would be to read the file once to count the records, allocate the arrays, rewind the file, and read again into the newly allocated arrays.
Fortran IV didn't have a character type, but it did allow a couple of ways to get character data into variables.
You could use DATA statements, or you could read data using the A format specifier.
In this case title is by default single precision real, which would generally be 4 bytes and so can hold 4 characters.
Double precision could store 8.
What you have is an OCR (or tired eyes) error. Instead of
1 READ(5.399,END=3)(Y(NS,J),J=1,ND) ! 00C83000
which the compiler interpreted as a read on Unit 5 of an unformatted file, what you probably should have (check the hardcopy that you scanned)
1 READ(5,399,END=3)(Y(NS,J),J=1,ND) ! 00C83000
which is a formatted read using Format 399.
No, you are correct, I had been checking the code and I missed that . instead of the ,. It is my error, I was just intrigued it did not get tagged by the compiler and generated an exception. Usually FORTRAN OCR is good with the sprint reader, but this one has had a lot of errors.
The interesting observation on the original code is the random number generator is commented out. They have used RANDU from IBM. I will need to look at it tomorrow.
RANDU is infamous and serves as a striking illustration of Marsaglia's Theorem , of which a colloquial statement is "Random Numbers Fall Mainly in the Planes". Nevertheless, I think that commenting out the invocation of RANDU is an over-reaction, because there is nothing random about the sequence 0.7731, 0.7731/2, ..., 0.7731/2(n-1) , ... that is left behind.
You may have to search the surrounding text in the book/report for an explanation.
Random number generators are the bane of my life, there is really no such thing as a pure random number generator, maybe the digits in PI. No matter how you look at them there are flaws, the problem is to find the one with the least offensive flaws, as @mecej4 so rightly points out. The relevant section of the paper is attached.
So my first question is what random number generator should I use with this Fortran program from the Intel Suite. My recent use of one of the Intel RNG showed clear patterns in the output when plotted on a 1 by 1 square, for my purposes, solving a multidimensional K MEANS proble, as the input data sets are so large eventually the random points fill in, the quality is ok, if I was using it on the FLIB problem from SciAm it would be a waste of my time, the Intel RNG it is not of high enough quality. Interestingly the BASIC language RNG from MS Basic is really quite sound.
The format statements in the program for the title output used A4, so when did this come into the language. I know nothing of IBM Fortran so I have no idea what its state of development was and which one they would have been using at UTAH Uni in 1980 to 1984 when the code was likely developed.
It is clear they are not the world's best coders, but I have a few spare minutes as I debug and run a long program (average run time 3 hours) and I am interested in the fuzzy k means, even if only to compare to k means, which has proved quite useful for classification of multidimensional data. I thought you lot might be interested as well.
"A" format for reading and writing character data to and from variables and arrays seems to be a relatively
early feature. It was certainly available for the 1960's vintage IBM 1620 with it's Fortran II compiler. That was the
first computer I worked with, although this was 1975 when I was in high school. It was a cast-me-down from a local university.