0

I'm trying to convert Fortran 77 code to C++. I'm using gfortran compiler via cygwin. I've successfully converted most of the code but I couldn't run this subroutine due to its dependency on Random(). According to the book I'm reading, the subroutine is

SUBROUTINE GAUSS(X,SIG)
    IMPLICIT REAL*8(A-H)
    IMPLICIT REAL*8(O-Z)
    INTEGER SUM
    SUM=0
    DO 14 J=1,6
    C THE NEXT STATEMENT PRODUCES A UNIF. DISTRIBUTED NUMBER FROM -32768 TO +32768
    IRAN=Random()
    SUM=SUM+IRAN
    14 CONTINUE
    X=SUM/65536
    X=1.414*X*SIG
    RETURN
END

At the top of the code, there are the following

C THE FIRST THREE STATEMENTS INVOKE THE ABSOFT RANDOM NUMBER GENERATOR ON THE MACINTOSH
GLOBAL DEFINE
INCLUDE 'quickdraw.inc'
END

Using this line

gfortran -std=legacy Listing_4_3.f90 -o test

I got this error

/tmp/ccQ2l529.o:Listing_4_3.f90:(.text+0x1b): undefined reference to `random_'
collect2: error: ld returned 1 exit status

How to make this code run?

CroCo
  • 5,531
  • 9
  • 56
  • 88
  • You need to provide a function `random`. If the comment is to be believed it shouldn't be too hard to write one. – francescalus Nov 18 '17 at 07:35
  • @francescalus I don’t know Fortran. Does this function included inside “quickdraw.inc”? – CroCo Nov 18 '17 at 07:39
  • You can use `rand` instead of Random. But you need to adjust the code https://gcc.gnu.org/onlinedocs/gfortran/RAND.html#RAND – matzeri Nov 18 '17 at 07:51
  • It's possible it's defined in there - do you have the source of it? If you put `implicit none` in the [appropriate place](https://stackoverflow.com/q/24337413/3157076), replacing those other `implicit` statements you will at least get a more helpful compile-time error (rather than link-time). – francescalus Nov 18 '17 at 08:09
  • I'd very much suggest not following the advice to use the non-standard function `rand`. Using `random_number` and mapping to integers of the desired range is [not tricky](https://stackoverflow.com/q/23057213/3157076). – francescalus Nov 18 '17 at 08:10
  • @francescalus it seems Absoft is a commercial Fortran compiler. May be the author wants to perform an efficient Gaussian experiment. – CroCo Nov 18 '17 at 08:17
  • Absoft is a commercial compiler. Whether `random` or `quickdraw.inc` were components of that (compilers may offer intrinsic extensions beyond the requirements of the standard) I don't know. Others here may. – francescalus Nov 18 '17 at 08:24
  • @CroCo You wanted to say **in**efficient I hope. There are much better ways to generate Gaussian random numbers. Let it be here, but for your final (C++?) code use something reasonable. You can choose even from the C++ standard. Something that generates Gaussian random numbers directly. – Vladimir F Героям слава Nov 18 '17 at 09:31
  • @VladimirF, I don't know but why an author chooses a commercial compiler while there are several efficient ones for free. Regarding the C++, I have no problem generating efficient random numbers. This subroutine is part of kalman filtering algorithms, so my goal is to convert it and compare the results. – CroCo Nov 18 '17 at 09:51
  • I was not commenting the compiler, I was comment the method which is INefficient. BTW the code is old, there were not too many free compilers back then (only g77 or f2c). It is simple to run this one, just call diferent random numbers procedure as others already said. – Vladimir F Героям слава Nov 18 '17 at 10:29

1 Answers1

1

Ignoring the fact that this method for Gaussian distribution is very inefficient, you can easily generate numbers from -0.5 to 0.5 with

call random_number(rran)
rran = rran - 0.5

so

SUBROUTINE GAUSS(X,SIG)
    IMPLICIT REAL*8(A-H)
    IMPLICIT REAL*8(O-Z)
    REAL*8 SUM, RRAN
    INTEGER J
    SUM=0
    DO J=1,6 
      CALL RANDOM_NUMBER(RRAN)   
      RRAN = RRAN - 0.5
      SUM=SUM+RRAN
    END DO
    X = 1.414*SUM*SIG
END

The code still contains some ugly stuff, but as you are converting it to a different language anyway...


If your point is to exactly replicate in new code the problems this method has, you can use this. Otherwise use a better method for Gaussian random numbers and don't be surprised it will be somewhat different, because the method in this subroutine is not only inefficient, but also inexact. Result from good methods WILL be different.