Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.


Valued Contributor II

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. 

0 Kudos
13 Replies
Black Belt Retired Employee

It does with standards checking:

t.f90(2): warning #6187: Fortran 2018 requires an INTEGER data type in this context.   [5.399]

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.

Valued Contributor II

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. 

Valued Contributor II

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


Black Belt

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.



Black Belt

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. 

Valued Contributor II

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.  



Black Belt

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.

Valued Contributor II

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.

Valued Contributor II


REAL (KIND=dp) :: Y(500,2),U(20,500),W(20.500)	                                    !   00059000

This also does not throw an error until you use W and then it complains about the number of indices being wrong.  Is there no check on integers being used as the index.  

Valued Contributor II

@mecej4  said You may have to search the surrounding text in the book/report for an explanation.


No I will just replace it. 

Valued Contributor II

here is the code, it has not been fully debugged as I try and work out what all the elements do -- I know rtm.