function c4_uniform_01 ( seed ) !*****************************************************************************80 ! !! C4_UNIFORM_01 returns a unit pseudorandom C4. ! ! Discussion: ! ! A C4 is a complex ( kind = 4 ) value. ! ! The angle should be uniformly distributed between 0 and 2 * PI, ! the square root of the radius uniformly distributed between 0 and 1. ! ! This results in a uniform distribution of values in the unit circle. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, complex ( kind = 4 ) C4_UNIFORM_01, a pseudorandom complex value. ! implicit none complex ( kind = 4 ) c4_uniform_01 integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 4 ), parameter :: pi = 3.1415926E+00 real ( kind = 4 ) r integer ( kind = 4 ) seed real ( kind = 4 ) theta if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C4_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = sqrt ( real ( seed, kind = 4 ) * 4.656612875E-10 ) k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if theta = 2.0E+00 * pi * ( real ( seed, kind = 4 ) * 4.656612875E-10 ) c4_uniform_01 = r * cmplx ( cos ( theta ), sin ( theta ), kind = 4 ) return end subroutine c4mat_uniform_01 ( m, n, seed, c ) !*****************************************************************************80 ! !! C4MAT_UNIFORM_01 returns a unit pseudorandom C4MAT. ! ! Discussion: ! ! A C4MAT is a matrix of complex ( kind = 4 ) values. ! ! The angles should be uniformly distributed between 0 and 2 * PI, ! the square roots of the radius uniformly distributed between 0 and 1. ! ! This results in a uniform distribution of values in the unit circle. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns ! in the matrix. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, complex ( kind = 4 ) C(M,N), the pseudorandom complex matrix. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n complex ( kind = 4 ) c(m,n) integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) j real ( kind = 4 ) r integer ( kind = 4 ) k real ( kind = 4 ), parameter :: pi = 3.1415926E+00 integer ( kind = 4 ) seed real ( kind = 4 ) theta if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C4MAT_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = sqrt ( real ( seed, kind = 4 ) * 4.656612875E-10 ) k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if theta = 2.0D+00 * pi * ( real ( seed, kind = 4 ) * 4.656612875E-10 ) c(i,j) = r * cmplx ( cos ( theta ), sin ( theta ), kind = 4 ) end do end do return end subroutine c4mat_uniform_write ( m, n, seed_init, seed, r, file_out_name ) !*****************************************************************************80 ! !! C4MAT_UNIFORM_WRITE writes a uniform pseudorandom C4MAT to a file. ! ! Discussion: ! ! A C4MAT is a matrix of complex ( kind = 4 ) values. ! ! The initial lines of the file are comments, which begin with a ! '#' character. ! ! Thereafter, each line of the file contains the M-dimensional ! components of the next entry of the sequence. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, the spatial dimension. ! ! Input, integer ( kind = 4 ) N, the number of points. ! ! Input, integer ( kind = 4 ) SEED_INIT, the initial seed value. ! ! Input, integer ( kind = 4 ) SEED, the current seed value. ! ! Input, complex ( kind = 4 ) R(M,N), the points. ! ! Input, character ( len = * ) FILE_OUT_NAME, the name of ! the output file. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n character ( len = * ) file_out_name integer ( kind = 4 ) file_out_unit logical, parameter :: header = .false. integer ( kind = 4 ) ios integer ( kind = 4 ) j complex ( kind = 4 ) r(m,n) integer ( kind = 4 ) seed integer ( kind = 4 ) seed_init character ( len = 40 ) string call get_unit ( file_out_unit ) open ( unit = file_out_unit, file = file_out_name, status = 'replace', & iostat = ios ) if ( ios /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C4MAT_UNIFORM_WRITE - Fatal error!' write ( *, '(a)' ) ' Could not open the output file.' stop end if if ( header ) then call timestring ( string ) write ( file_out_unit, '(a)' ) '# ' // trim ( file_out_name ) write ( file_out_unit, '(a)' ) '# created by C4MAT_UNIFORM_WRITE.F90.' write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a)' ) '# File generated on ' & // trim ( string ) write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a,i8)' ) '# Spatial dimension M = ', m write ( file_out_unit, '(a,i8)' ) '# Number of points N = ', n write ( file_out_unit, '(a,i12)' ) '# Initial seed = ', seed_init write ( file_out_unit, '(a,i12)' ) '# Current seed = ', seed write ( file_out_unit, '(a,g14.6)' ) '# EPSILON (unit roundoff) = ', & epsilon ( abs ( r(1,1) ) ) write ( file_out_unit, '(a)' ) '#' end if write ( string, '(a,i3,a)' ) '(', 2 * m, '(f10.6,2x)' do j = 1, n write ( file_out_unit, string ) r(1:m,j) end do close ( unit = file_out_unit ) return end subroutine c4vec_uniform_01 ( n, seed, c ) !*****************************************************************************80 ! !! C4VEC_UNIFORM_01 returns a unit pseudorandom C4VEC. ! ! Discussion: ! ! A C4VEC is a vector of complex ( kind = 4 ) values. ! ! The angles should be uniformly distributed between 0 and 2 * PI, ! the square roots of the radius uniformly distributed between 0 and 1. ! ! This results in a uniform distribution of values in the unit circle. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the number of values to compute. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, complex ( kind = 4 ) C(N), the pseudorandom complex vector. ! implicit none integer ( kind = 4 ) n complex ( kind = 4 ) c(n) integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 4 ), parameter :: pi = 3.1415926E+00 real ( kind = 4 ) r integer ( kind = 4 ) seed real ( kind = 4 ) theta if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C4VEC_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = sqrt ( real ( seed, kind = 4 ) * 4.656612875E-10 ) k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if theta = 2.0E+00 * pi * ( real ( seed, kind = 4 ) * 4.656612875E-10 ) c(i) = r * cmplx ( cos ( theta ), sin ( theta ), kind = 4 ) end do return end function c8_uniform_01 ( seed ) !*****************************************************************************80 ! !! C8_UNIFORM_01 returns a unit pseudorandom C8. ! ! Discussion: ! ! A C8 is a complex ( kind = 8 ) value. ! ! For now, the input quantity SEED is an integer variable. ! ! The angle should be uniformly distributed between 0 and 2 * PI, ! the square root of the radius uniformly distributed between 0 and 1. ! ! This results in a uniform distribution of values in the unit circle. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, complex ( kind = 8 ) C8_UNIFORM_01, a pseudorandom complex value. ! implicit none complex ( kind = 8 ) c8_uniform_01 integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 real ( kind = 8 ) r integer ( kind = 4 ) seed real ( kind = 8 ) theta if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C8_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = sqrt ( real ( seed, kind = 8 ) * 4.656612875D-10 ) k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if theta = 2.0D+00 * pi * ( real ( seed, kind = 8 ) * 4.656612875D-10 ) c8_uniform_01 = r * cmplx ( cos ( theta ), sin ( theta ), kind = 8 ) return end subroutine c8mat_uniform_01 ( m, n, seed, c ) !*****************************************************************************80 ! !! C8MAT_UNIFORM_01 returns a unit pseudorandom C8MAT. ! ! Discussion: ! ! A C8MAT is a matrix of complex ( kind = 8 ) values. ! ! For now, the input quantity SEED is an integer variable. ! ! The angles should be uniformly distributed between 0 and 2 * PI, ! the square roots of the radius uniformly distributed between 0 and 1. ! ! This results in a uniform distribution of values in the unit circle. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns ! in the matrix. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, complex ( kind = 8 ) C(M,N), the pseudorandom complex matrix. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n complex ( kind = 8 ) c(m,n) integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) j real ( kind = 8 ) r integer ( kind = 4 ) k real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 integer ( kind = 4 ) seed real ( kind = 8 ) theta if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C8MAT_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = sqrt ( real ( seed, kind = 8 ) * 4.656612875D-10 ) k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if theta = 2.0D+00 * pi * ( real ( seed, kind = 8 ) * 4.656612875D-10 ) c(i,j) = r * cmplx ( cos ( theta ), sin ( theta ), kind = 8 ) end do end do return end subroutine c8mat_uniform_write ( m, n, seed_init, seed, r, file_out_name ) !*****************************************************************************80 ! !! C8MAT_UNIFORM_WRITE writes a uniform pseudorandom C8MAT to a file. ! ! Discussion: ! ! A C8MAT is an array of complex ( kind = 8 ) values. ! ! For now, the input quantity SEED_INIT is an integer variable. ! ! The initial lines of the file are comments, which begin with a ! '#' character. ! ! Thereafter, each line of the file contains the M-dimensional ! components of the next entry of the sequence. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, the spatial dimension. ! ! Input, integer ( kind = 4 ) N, the number of points. ! ! Input, integer ( kind = 4 ) SEED_INIT, the initial seed value. ! ! Input, integer ( kind = 4 ) SEED, the current seed. ! ! Input, complex ( kind = 8 ) R(M,N), the points. ! ! Input, character ( len = * ) FILE_OUT_NAME, the name of ! the output file. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n character ( len = * ) file_out_name integer ( kind = 4 ) file_out_unit logical, parameter :: header = .false. integer ( kind = 4 ) ios integer ( kind = 4 ) j complex ( kind = 8 ) r(m,n) integer ( kind = 4 ) seed integer ( kind = 4 ) seed_init character ( len = 40 ) string call get_unit ( file_out_unit ) open ( unit = file_out_unit, file = file_out_name, status = 'replace', & iostat = ios ) if ( ios /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C8MAT_UNIFORM_WRITE - Fatal error!' write ( *, '(a)' ) ' Could not open the output file.' stop end if if ( header ) then call timestring ( string ) write ( file_out_unit, '(a)' ) '# ' // trim ( file_out_name ) write ( file_out_unit, '(a)' ) '# created by C8MAT_UNIFORM_WRITE.F90.' write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a)' ) '# File generated on ' & // trim ( string ) write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a,i8)' ) '# Spatial dimension M = ', m write ( file_out_unit, '(a,i8)' ) '# Number of points N = ', n write ( file_out_unit, '(a,i12)' ) '# Initial seed = ', seed_init write ( file_out_unit, '(a,i12)' ) '# Current seed = ', seed write ( file_out_unit, '(a,g14.6)' ) '# EPSILON (unit roundoff) = ', & epsilon ( abs ( r(1,1) ) ) write ( file_out_unit, '(a)' ) '#' end if write ( string, '(a,i3,a)' ) '(', 2 * m, '(f10.6,2x)' do j = 1, n write ( file_out_unit, string ) r(1:m,j) end do close ( unit = file_out_unit ) return end subroutine c8vec_uniform_01 ( n, seed, c ) !*****************************************************************************80 ! !! C8VEC_UNIFORM_01 returns a unit pseudorandom C8VEC. ! ! Discussion: ! ! A C8VEC is a vector of complex ( kind = 8 ) values. ! ! For now, the input quantity SEED is an integer variable. ! ! The angles should be uniformly distributed between 0 and 2 * PI, ! the square roots of the radius uniformly distributed between 0 and 1. ! ! This results in a uniform distribution of values in the unit circle. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the number of values to compute. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, ! which should NOT be 0. ! On output, SEED has been updated. ! ! Output, complex ( kind = 8 ) C(N), the pseudorandom complex vector. ! implicit none integer ( kind = 4 ) n complex ( kind = 8 ) c(n) integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 real ( kind = 8 ) r integer ( kind = 4 ) k real ( kind = 8 ), parameter :: pi = 3.141592653589793D+00 integer ( kind = 4 ) seed real ( kind = 8 ) theta if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'C8VEC_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = sqrt ( real ( seed, kind = 8 ) * 4.656612875D-10 ) k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if theta = 2.0D+00 * pi * ( real ( seed, kind = 8 ) * 4.656612875D-10 ) c(i) = r * cmplx ( cos ( theta ), sin ( theta ), kind = 8 ) end do return end function ch_uniform ( clo, chi, seed ) !*****************************************************************************80 ! !! CH_UNIFORM returns a scaled pseudorandom CH. ! ! Discussion: ! ! A CH is an alphabetic character value. ! ! The value is scaled to lie between characters CLO and CHI. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character CLO, CHI, the minimum and maximum acceptable characters. ! ! Input/output, integer ( kind = 4 ) SEED, a seed for the random ! number generator. ! ! Output, character CH_UNIFORM, the randomly chosen character. ! implicit none character ch_uniform character chi character clo real ( kind = 4 ) r4_uniform_01 integer ( kind = 4 ) i integer ( kind = 4 ) ihi integer ( kind = 4 ) ilo integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'CH_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if ilo = ichar ( clo ) ihi = ichar ( chi ) i = ilo + int ( r4_uniform_01 ( seed ) * real ( ihi + 1 - ilo ) ) i = max ( i, ilo ) i = min ( i, ihi ) ch_uniform = char ( i ) return end subroutine congruence ( a, b, c, ierror, x ) !*****************************************************************************80 ! !! CONGRUENCE solves a congruence of the form ( A * X = C ) mod B. ! ! Discussion: ! ! A, B and C are given integers. The equation is solvable if and only ! if the greatest common divisor of A and B also divides C. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Eric Weisstein, ! CRC Concise Encyclopedia of Mathematics, ! CRC Press, 2002, ! Second edition, ! ISBN: 1584883472, ! LC: QA5.W45. ! ! Parameters: ! ! Input, integer ( kind = 4 ) A, B, C, the coefficients of the ! Diophantine equation. ! ! Output, integer ( kind = 4 ) IERROR, error flag. ! 0, no error, X was computed. ! 1, A = B = 0, C is nonzero. ! 2, A = 0, B and C nonzero, but C is not a multiple of B. ! 3, A nonzero, B zero, C nonzero, but C is not a multiple of A. ! 4, A, B, C nonzero, but GCD of A and B does not divide C. ! 5, algorithm ran out of internal space. ! ! Output, integer ( kind = 4 ) X, the solution of the Diophantine equation. ! X will be between 0 and B-1. ! implicit none integer ( kind = 4 ), parameter :: nmax = 100 integer ( kind = 4 ) a integer ( kind = 4 ) a_copy integer ( kind = 4 ) a_mag integer ( kind = 4 ) a_sign integer ( kind = 4 ) b integer ( kind = 4 ) b_copy integer ( kind = 4 ) b_mag integer ( kind = 4 ) b_sign integer ( kind = 4 ) c integer ( kind = 4 ) c_copy integer ( kind = 4 ) g integer ( kind = 4 ) i4_gcd integer ( kind = 4 ) ierror integer ( kind = 4 ) k integer ( kind = 4 ) n integer ( kind = 4 ), parameter :: one = 1 integer ( kind = 4 ) q(nmax) logical swap integer ( kind = 4 ) x integer ( kind = 4 ) y integer ( kind = 4 ) z ! ! Defaults for output parameters. ! ierror = 0 x = 0 y = 0 ! ! Special cases. ! if ( a == 0 .and. b == 0 .and. c == 0 ) then x = 0 return else if ( a == 0 .and. b == 0 .and. c /= 0 ) then ierror = 1 x = 0 return else if ( a == 0 .and. b /= 0 .and. c == 0 ) then x = 0 return else if ( a == 0 .and. b /= 0 .and. c /= 0 ) then x = 0 if ( mod ( c, b ) /= 0 ) then ierror = 2 end if return else if ( a /= 0 .and. b == 0 .and. c == 0 ) then x = 0 return else if ( a /= 0 .and. b == 0 .and. c /= 0 ) then x = c / a if ( mod ( c, a ) /= 0 ) then ierror = 3 end if return else if ( a /= 0 .and. b /= 0 .and. c == 0 ) then ! g = i4_gcd ( a, b ) ! x = b / g x = 0 return end if ! ! Handle the "general" case: A, B and C are nonzero. ! ! Step 1: Compute the GCD of A and B, which must also divide C. ! g = i4_gcd ( a, b ) if ( mod ( c, g ) /= 0 ) then ierror = 4 return end if a_copy = a / g b_copy = b / g c_copy = c / g ! ! Step 2: Split A and B into sign and magnitude. ! a_mag = abs ( a_copy ) a_sign = sign ( one, a_copy ) b_mag = abs ( b_copy ) b_sign = sign ( one, b_copy ) ! ! Another special case, A_MAG = 1 or B_MAG = 1. ! if ( a_mag == 1 ) then x = a_sign * c_copy return else if ( b_mag == 1 ) then x = 0 return end if ! ! Step 3: Produce the Euclidean remainder sequence. ! if ( b_mag <= a_mag ) then swap = .false. q(1) = a_mag q(2) = b_mag else swap = .true. q(1) = b_mag q(2) = a_mag end if n = 3 do q(n) = mod ( q(n-2), q(n-1) ) if ( q(n) == 1 ) then exit end if n = n + 1 if ( nmax < n ) then ierror = 5 write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'CONGRUENCE - Fatal error!' write ( *, '(a)' ) ' Exceeded number of iterations.' stop end if end do ! ! Step 4: Go backwards to solve X * A_MAG + Y * B_MAG = 1. ! y = 0 do k = n, 2, -1 x = y y = ( 1 - x * q(k-1) ) / q(k) end do ! ! Step 5: Undo the swapping. ! if ( swap ) then z = x x = y y = z end if ! ! Step 6: Apply signs to X and Y so that X * A + Y * B = 1. ! x = x * a_sign ! ! Step 7: Multiply by C, so that X * A + Y * B = C. ! x = x * c_copy ! ! Step 8: Force 0 <= X < B. ! x = mod ( x, b ) ! ! Step 9: Force positivity. ! if ( x < 0 ) then x = x + b end if return end subroutine get_seed ( seed ) !*****************************************************************************80 ! !! GET_SEED returns a seed for the random number generator. ! ! Discussion: ! ! The seed depends on the current time, and ought to be (slightly) ! different every millisecond. Once the seed is obtained, a random ! number generator should be called a few times to further process ! the seed. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) SEED, a pseudorandom seed value. ! implicit none integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) seed real ( kind = 8 ) temp character ( len = 10 ) time character ( len = 8 ) today integer ( kind = 4 ) values(8) character ( len = 5 ) zone call date_and_time ( today, time, zone, values ) temp = 0.0D+00 temp = temp + real ( values(2) - 1, kind = 8 ) / 11.0D+00 temp = temp + real ( values(3) - 1, kind = 8 ) / 30.0D+00 temp = temp + real ( values(5), kind = 8 ) / 23.0D+00 temp = temp + real ( values(6), kind = 8 ) / 59.0D+00 temp = temp + real ( values(7), kind = 8 ) / 59.0D+00 temp = temp + real ( values(8), kind = 8 ) / 999.0D+00 temp = temp / 6.0D+00 ! ! Force 0 < TEMP <= 1. ! do while ( temp <= 0.0D+00 ) temp = temp + 1.0D+00 end do do while ( 1.0D+00 < temp ) temp = temp - 1.0D+00 end do seed = int ( real ( i4_huge, kind = 8 ) * temp ) ! ! Never use a seed of 0 or maximum integer. ! if ( seed == 0 ) then seed = 1 end if if ( seed == i4_huge ) then seed = seed - 1 end if return end subroutine get_unit ( iunit ) !*****************************************************************************80 ! !! GET_UNIT returns a free FORTRAN unit number. ! ! Discussion: ! ! A "free" FORTRAN unit number is an integer between 1 and 99 which ! is not currently associated with an I/O device. A free FORTRAN unit ! number is needed in order to open a file with the OPEN command. ! ! If IUNIT = 0, then no free FORTRAN unit could be found, although ! all 99 units were checked (except for units 5, 6 and 9, which ! are commonly reserved for console I/O). ! ! Otherwise, IUNIT is an integer between 1 and 99, representing a ! free FORTRAN unit. Note that GET_UNIT assumes that units 5 and 6 ! are special, and will never return those values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) IUNIT, the free unit number. ! implicit none integer ( kind = 4 ) i integer ( kind = 4 ) ios integer ( kind = 4 ) iunit logical lopen iunit = 0 do i = 1, 99 if ( i /= 5 .and. i /= 6 .and. i /= 9 ) then inquire ( unit = i, opened = lopen, iostat = ios ) if ( ios == 0 ) then if ( .not. lopen ) then iunit = i return end if end if end if end do return end function i4_gcd ( i, j ) !*****************************************************************************80 ! !! I4_GCD finds the greatest common divisor of I and J. ! ! Discussion: ! ! Only the absolute values of I and J are ! considered, so that the result is always nonnegative. ! ! If I or J is 0, I4_GCD is returned as max ( 1, abs ( I ), abs ( J ) ). ! ! If I and J have no common factor, I4_GCD is returned as 1. ! ! Otherwise, using the Euclidean algorithm, I4_GCD is the ! largest common factor of I and J. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) I, J, two numbers whose greatest common ! divisor is desired. ! ! Output, integer ( kind = 4 ) I4_GCD, the greatest common divisor ! of I and J. ! implicit none integer ( kind = 4 ) i integer ( kind = 4 ) i4_gcd integer ( kind = 4 ) ip integer ( kind = 4 ) iq integer ( kind = 4 ) ir integer ( kind = 4 ) j i4_gcd = 1 ! ! Return immediately if either I or J is zero. ! if ( i == 0 ) then i4_gcd = max ( 1, abs ( j ) ) return else if ( j == 0 ) then i4_gcd = max ( 1, abs ( i ) ) return end if ! ! Set IP to the larger of I and J, IQ to the smaller. ! This way, we can alter IP and IQ as we go. ! ip = max ( abs ( i ), abs ( j ) ) iq = min ( abs ( i ), abs ( j ) ) ! ! Carry out the Euclidean algorithm. ! do ir = mod ( ip, iq ) if ( ir == 0 ) then exit end if ip = iq iq = ir end do i4_gcd = iq return end function i4_huge ( ) !*****************************************************************************80 ! !! I4_HUGE returns a "huge" I4. ! ! Discussion: ! ! On an IEEE 32 bit machine, I4_HUGE should be 2^31 - 1, and its ! bit pattern should be ! ! 01111111111111111111111111111111 ! ! In this case, its numerical value is 2147483647. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer ( kind = 4 ) I4_HUGE, a "huge" I4. ! implicit none integer ( kind = 4 ) i4 integer ( kind = 4 ) i4_huge i4_huge = 2147483647 return end function i4_seed_advance ( seed ) !*****************************************************************************80 ! !! I4_SEED_ADVANCE "advances" the seed. ! ! Discussion: ! ! This routine implements one step of the recursion ! ! SEED = ( 16807 * SEED ) mod ( 2^31 - 1 ) ! ! This version of the routine does not check whether the input value of ! SEED is zero. If the input value is zero, the output value will be zero. ! ! If we repeatedly use the output of SEED_ADVANCE as the next input, ! and we start with SEED = 12345, then the first few iterates are: ! ! Input Output ! SEED SEED ! ! 12345 207482415 ! 207482415 1790989824 ! 1790989824 2035175616 ! 2035175616 77048696 ! 77048696 24794531 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 14 December 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) SEED, the seed value. ! ! Output, integer ( kind = 4 ) I4_SEED_ADVANCE, the "next" seed. ! implicit none integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) i4_seed_advance integer ( kind = 4 ) k integer ( kind = 4 ) seed integer ( kind = 4 ) seed_new k = seed / 127773 seed_new = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed_new < 0 ) then seed_new = seed_new + i4_huge end if i4_seed_advance = seed_new return end function i4_uniform ( a, b, seed ) !*****************************************************************************80 ! !! I4_UNIFORM returns a scaled pseudorandom I4. ! ! Discussion: ! ! An I4 is an integer ( kind = 4 ) value. ! ! The pseudorandom number will be scaled to be uniformly distributed ! between A and B. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) A, B, the limits of the interval. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, integer ( kind = 4 ) I4_UNIFORM, a number between A and B. ! implicit none integer ( kind = 4 ) a integer ( kind = 4 ) b integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) i4_uniform integer ( kind = 4 ) k real ( kind = 4 ) r integer ( kind = 4 ) seed integer ( kind = 4 ) value if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'I4_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = real ( seed, kind = 4 ) * 4.656612875E-10 ! ! Scale R to lie between A-0.5 and B+0.5. ! r = ( 1.0E+00 - r ) * ( real ( min ( a, b ), kind = 4 ) - 0.5E+00 ) & + r * ( real ( max ( a, b ), kind = 4 ) + 0.5E+00 ) ! ! Use rounding to convert R to an integer between A and B. ! value = nint ( r, kind = 4 ) value = max ( value, min ( a, b ) ) value = min ( value, max ( a, b ) ) i4_uniform = value return end function i4_uniform_0i ( seed ) !*****************************************************************************80 ! !! I4_UNIFORM_0I returns a pseudorandom I4. ! ! Discussion: ! ! An I4 is an integer ( kind = 4 ) value. ! ! SEED = ( SEED * 7^5 ) mod (2^31 - 1) ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) SEED, the integer "seed" used to ! generate the output value. SEED should not be 0. ! ! Output, integer ( kind = 4 ) I4_UNIFORM_0I, a uniform random value ! between 1 and 2^31-1. ! ! Local parameters: ! ! IA = 7^5 ! IB = 2^15 ! IB16 = 2^16 ! IP = 2^31-1 ! implicit none integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) i4_uniform_0i integer ( kind = 4 ), parameter :: ia = 16807 integer ( kind = 4 ), parameter :: ib15 = 32768 integer ( kind = 4 ), parameter :: ib16 = 65536 integer ( kind = 4 ), parameter :: ip = 2147483647 integer ( kind = 4 ) iprhi integer ( kind = 4 ) ixhi integer ( kind = 4 ) k integer ( kind = 4 ) leftlo integer ( kind = 4 ) loxa integer ( kind = 4 ) seed ! ! Don't let SEED be 0. ! if ( seed == 0 ) then seed = i4_huge end if ! ! Get the 15 high order bits of SEED. ! ixhi = seed / ib16 ! ! Get the 16 low bits of SEED and form the low product. ! loxa = ( seed - ixhi * ib16 ) * ia ! ! Get the 15 high order bits of the low product. ! leftlo = loxa / ib16 ! ! Form the 31 highest bits of the full product. ! iprhi = ixhi * ia + leftlo ! ! Get overflow past the 31st bit of full product. ! k = iprhi / ib15 ! ! Assemble all the parts and presubtract IP. The parentheses are ! essential. ! seed = ( ( ( loxa - leftlo * ib16 ) - ip ) & + ( iprhi - k * ib15 ) * ib16 ) + k ! ! Add IP back in if necessary. ! if ( seed < 0 ) then seed = seed + ip end if i4_uniform_0i = seed return end subroutine i4mat_uniform ( m, n, a, b, seed, x ) !*****************************************************************************80 ! !! I4MAT_UNIFORM returns a scaled pseudorandom I4MAT. ! ! Discussion: ! ! An I4MAT is a matrix of integer ( kind = 4 ) values. ! ! The pseudorandom numbers will be scaled to be uniformly distributed ! between A and B. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the row and column dimensions ! of the matrix. ! ! Input, integer ( kind = 4 ) A, B, the limits of the interval. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, ! which should NOT be 0. ! On output, SEED has been updated. ! ! Output, integer ( kind = 4 ) X(M,N), a matrix of values between A and B. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n integer ( kind = 4 ) a integer ( kind = 4 ) b integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) j integer ( kind = 4 ) k real ( kind = 4 ) r integer ( kind = 4 ) seed integer ( kind = 4 ) value integer ( kind = 4 ) x(m,n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'I4MAT_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = real ( seed, kind = 4 ) * 4.656612875E-10 ! ! Scale R to lie between A-0.5 and B+0.5. ! r = ( 1.0E+00 - r ) * ( real ( min ( a, b ), kind = 4 ) - 0.5E+00 ) & + r * ( real ( max ( a, b ), kind = 4 ) + 0.5E+00 ) ! ! Use rounding to convert R to an integer between A and B. ! value = nint ( r, kind = 4 ) value = max ( value, min ( a, b ) ) value = min ( value, max ( a, b ) ) x(i,j) = value end do end do return end subroutine i4vec_uniform ( n, a, b, seed, x ) !*****************************************************************************80 ! !! I4VEC_UNIFORM returns a scaled pseudorandom I4VEC. ! ! Discussion: ! ! An I4VEC is a vector of integer ( kind = 4 ) values. ! ! The pseudorandom numbers should be scaled to be uniformly distributed ! between A and B. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the dimension of the vector. ! ! Input, integer ( kind = 4 ) A, B, the limits of the interval. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, integer ( kind = 4 ) X(N), a vector of numbers between A and B. ! implicit none integer ( kind = 4 ) n integer ( kind = 4 ) a integer ( kind = 4 ) b integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 4 ) r integer ( kind = 4 ) seed integer ( kind = 4 ) value integer ( kind = 4 ) x(n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'I4VEC_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r = real ( seed, kind = 4 ) * 4.656612875E-10 ! ! Scale R to lie between A-0.5 and B+0.5. ! r = ( 1.0E+00 - r ) * ( real ( min ( a, b ), kind = 4 ) - 0.5E+00 ) & + r * ( real ( max ( a, b ), kind = 4 ) + 0.5E+00 ) ! ! Use rounding to convert R to an integer between A and B. ! value = nint ( r, kind = 4 ) value = max ( value, min ( a, b ) ) value = min ( value, max ( a, b ) ) x(i) = value end do return end function i8_uniform ( a, b, seed ) !*****************************************************************************80 ! !! I8_UNIFORM returns a scaled pseudorandom I8. ! ! Discussion: ! ! An I8 is an integer ( kind = 8 ) value. ! ! Note that ALL integer variables in this routine are ! of type integer ( kind = 8 )! ! ! The pseudorandom number should be uniformly distributed ! between A and B. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 8 ) A, B, the limits of the interval. ! ! Input/output, integer ( kind = 8 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, integer ( kind = 8 ) I8_UNIFORM, a number between A and B. ! implicit none integer ( kind = 8 ) a integer ( kind = 8 ) b integer ( kind = 8 ) i8_uniform real ( kind = 8 ) r real ( kind = 8 ) r8i8_uniform_01 integer ( kind = 8 ) seed integer ( kind = 8 ) value if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'I8_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if r = r8i8_uniform_01 ( seed ) ! ! Scale R to lie between A-0.5 and B+0.5. ! r = ( 1.0D+00 - r ) * ( real ( min ( a, b ), kind = 8 ) - 0.5D+00 ) & + r * ( real ( max ( a, b ), kind = 8 ) + 0.5D+00 ) ! ! Use rounding to convert R to an integer between A and B. ! value = nint ( r, kind = 8 ) value = max ( value, min ( a, b ) ) value = min ( value, max ( a, b ) ) i8_uniform = value return end function l_uniform ( seed ) !*****************************************************************************80 ! !! L_UNIFORM returns a pseudorandom L. ! ! Discussion: ! ! An L is a LOGICAL value. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 01 December 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, logical L_UNIFORM, a pseudorandom logical value. ! implicit none integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ), parameter :: i4_huge_half = 1073741823 integer ( kind = 4 ) k logical l_uniform integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'L_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if l_uniform = ( i4_huge_half < seed ) return end subroutine lcrg_anbn ( a, b, c, n, an, bn ) !*****************************************************************************80 ! !! LCRG_ANBN computes the "N-th power" of a linear congruential generator. ! ! Discussion: ! ! We are considering a linear congruential random number generator. ! The LCRG takes as input an integer value called SEED, and returns ! an updated value of SEED, ! ! SEED(out) = ( a * SEED(in) + b ) mod c. ! ! and an associated pseudorandom real value ! ! U = SEED(out) / c. ! ! In most cases, a user is content to call the LCRG repeatedly, with ! the updating of SEED being taken care of automatically. ! ! The purpose of this routine is to determine the values of AN and BN ! that describe the LCRG that is equivalent to N applications of the ! original LCRG. ! ! One use for such a facility would be to do random number computations ! in parallel. If each of N processors is to compute many random values, ! you can guarantee that they work with distinct random values ! by starting with a single value of SEED, using the original LCRG to generate ! the first N-1 "iterates" of SEED, so that you now have N "seed" values, ! and from now on, applying the N-th power of the LCRG to the seeds. ! ! If the K-th processor starts from the K-th seed, it will essentially ! be computing every N-th entry of the original random number sequence, ! offset by K. Thus the individual processors will be using a random ! number stream as good as the original one, and without repeating, and ! without having to communicate. ! ! To evaluate the N-th value of SEED directly, we start by ignoring ! the modular arithmetic, and working out the sequence of calculations ! as follows: ! ! SEED(0) = SEED. ! SEED(1) = a * SEED + b ! SEED(2) = a * SEED(1) + b = a^2 * SEED + a * b + b ! SEED(3) = a * SEED(2) + b = a^3 * SEED + a^2 * b + a * b + b ! ... ! SEED(N-1) = a * SEED(N-2) + b ! ! SEED(N) = a * SEED(N-1) + b = a^N * SEED ! + ( a^(n-1) + a^(n-2) + ... + a + 1 ) * b ! ! or, using the geometric series, ! ! SEED(N) = a^N * SEED + ( a^N - 1) / ( a - 1 ) * b ! = AN * SEED + BN ! ! Thus, from any SEED, we can determine the result of N applications of the ! original LCRG directly if we can solve ! ! ( a - 1 ) * BN = ( a^N - 1 ) * b in modular arithmetic, ! ! and evaluate: ! ! AN = a^N ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 April 2008 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Barry Wilkinson, Michael Allen, ! Parallel Programming: ! Techniques and Applications Using Networked Workstations and Parallel Computers, ! Prentice Hall, ! ISBN: 0-13-140563-2, ! LC: QA76.642.W54. ! ! Parameters: ! ! Input, integer ( kind = 4 ) A, the multiplier for the LCRG. ! ! Input, integer ( kind = 4 ) B, the added value for the LCRG. ! ! Input, integer ( kind = 4 ) C, the base for the modular arithmetic. ! For 32 bit arithmetic, this is often 2^31 - 1, or 2147483647. It is ! required that 0 < C. ! ! Input, integer ( kind = 4 ) N, the "index", or number of times that the ! LCRG is to be applied. It is required that 0 <= N. ! ! Output, integer ( kind = 4 ) AN, BN, the multiplier and added value for ! the LCRG that represent N applications of the original LCRG. ! implicit none integer ( kind = 4 ) a integer ( kind = 4 ) am1 integer ( kind = 4 ) an integer ( kind = 4 ) anm1tb integer ( kind = 4 ) b integer ( kind = 4 ) bn integer ( kind = 4 ) c integer ( kind = 4 ) ierror integer ( kind = 4 ) n if ( n < 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LCRG_ANBN - Fatal error!' write ( *, '(a,i12)' ) ' Illegal input value of N = ', n stop end if if ( c <= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LCRG_ANBN - Fatal error!' write ( *, '(a,i12)' ) ' Illegal input value of C = ', c stop end if if ( n == 0 ) then an = 1 bn = 0 else if ( n == 1 ) then an = a bn = b else ! ! Compute A^N. ! call power_mod ( a, n, c, an ) ! ! Solve ! ( a - 1 ) * BN = ( a^N - 1 ) mod B ! for BN. ! am1 = a - 1 anm1tb = ( an - 1 ) * b call congruence ( am1, c, anm1tb, ierror, bn ) if ( ierror /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LCRG_ANBN - Fatal error!' write ( *, '(a)' ) ' An error occurred in the CONGRUENCE routine.' write ( *, '(a,i8)' ) ' The error code was IERROR = ', ierror stop end if end if return end subroutine lcrg_evaluate ( a, b, c, x, y ) !*****************************************************************************80 ! !! LCRG_EVALUATE evaluates an LCRG, y = ( A * x + B ) mod C. ! ! Discussion: ! ! This routine cannot be recommended for production use. Because we want ! to do modular arithmetic, but the base is not a power of 2, we need to ! use "double precision" integers to keep accuracy. ! ! If we knew the base C, we could try to avoid overflow while not changing ! precision. ! ! If the base C was a power of 2, we could rely on the usual properties of ! integer arithmetic on computers, in which overflow bits, which are always ! ignored, don't actually matter. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 April 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) A, the multiplier for the LCRG. ! ! Input, integer ( kind = 4 ) B, the added value for the LCRG. ! ! Input, integer ( kind = 4 ) C, the base for the modular arithmetic. ! For 32 bit arithmetic, this is often 2^31 - 1, or 2147483647. It is ! required that 0 < C. ! ! Input, integer ( kind = 4 ) X, the value to be processed. ! ! Output, integer ( kind = 4 ) Y, the processed value. ! implicit none integer ( kind = 4 ) a integer ( kind = 8 ) a8 integer ( kind = 4 ) b integer ( kind = 8 ) b8 integer ( kind = 4 ) c integer ( kind = 8 ) c8 integer ( kind = 4 ) x integer ( kind = 8 ) x8 integer ( kind = 4 ) y integer ( kind = 8 ) y8 ! ! To avoid roundoff issues, we need to go to "double precision" integers. ! (Not available on all planets.) ! a8 = a b8 = b c8 = c x8 = x y8 = mod ( a8 * x8 + b8, c8 ) y = int ( y8, kind = 4 ) if ( y < 0 ) then y = y + c end if return end subroutine lcrg_seed ( a, b, c, n, seed, seed_lcrg ) !*****************************************************************************80 ! !! LCRG_SEED computes the N-th seed of a linear congruential generator. ! ! Discussion: ! ! We are considering a linear congruential random number generator. ! The LCRG takes as input an integer value called SEED, and returns ! an updated value of SEED, ! ! SEED(out) = ( a * SEED(in) + b ) mod c. ! ! and an associated pseudorandom real value ! ! U = SEED(out) / c. ! ! In most cases, a user is content to call the LCRG repeatedly, with ! the updating of SEED being taken care of automatically. ! ! The purpose of this routine is to determine the value of SEED that ! would be output after N successive applications of the LCRG. This ! allows the user to know, in advance, what the 1000-th value of ! SEED would be, for instance. Obviously, one way to do this is to ! apply the LCRG formula 1,000 times. However, it is possible to ! do this in a more direct and efficient way. ! ! One use for such a facility would be to do random number computations ! in parallel. If each processor is to compute 1,000 values, you can ! guarantee that they work with distinct random values by starting the ! first processor with SEED, the second with the value of SEED after ! 1,000 applications of the LCRG, and so on. ! ! To evaluate the N-th value of SEED directly, we start by ignoring ! the modular arithmetic, and working out the sequence of calculations ! as follows: ! ! SEED(0) = SEED. ! SEED(1) = a * SEED + b ! SEED(2) = a * SEED(1) + b = a^2 * SEED + a * b + b ! SEED(3) = a * SEED(2) + b = a^3 * SEED + a^2 * b + a * b + b ! ... ! SEED(N) = a * SEED(N-1) + b = a^N * SEED ! + ( a^(n-1) + a^(n-2) + ... + a + 1 ) * b ! ! or, using the geometric series, ! ! SEED(N) = a^N * SEED + ( a^N - 1) / ( a - 1 ) * b ! ! Therefore, we can determine SEED(N) directly if we can solve ! ! ( a - 1 ) * BN = ( a^N - 1 ) * b in modular arithmetic, ! ! and evaluated: ! ! AN = a^N ! ! Using the formula: ! ! SEED(N) = ( AN * SEED + BN ) mod c ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 April 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) A, the multiplier for the LCRG. ! ! Input, integer ( kind = 4 ) B, the added value for the LCRG. ! ! Input, integer ( kind = 4 ) C, the base for the modular arithmetic. ! For 32 bit arithmetic, this is often 2^31 - 1, or 2147483647. It is ! required that 0 < C. ! ! Input, integer ( kind = 4 ) N, the "index", or number of times that the ! LCRG is to be applied. It is required that 0 <= N. ! ! Input, integer ( kind = 4 ) SEED, the starting value of SEED. It is ! customary that 0 < SEED. ! ! Output, integer ( kind = 4 ) SEED_LCRG, the value of SEED that would ! be output if the LCRG were applied to the starting value N times. ! implicit none integer ( kind = 4 ) a integer ( kind = 4 ) am1 integer ( kind = 4 ) an integer ( kind = 4 ) anm1tb integer ( kind = 4 ) b integer ( kind = 4 ) bn integer ( kind = 4 ) c integer ( kind = 4 ) ierror integer ( kind = 4 ) n integer ( kind = 4 ) seed integer ( kind = 4 ) seed_lcrg integer ( kind = 8 ) value2 if ( n < 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LCRG_SEED - Fatal error!' write ( *, '(a,i12)' ) ' Illegal input value of N = ', n stop end if if ( c <= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LCRG_SEED - Fatal error!' write ( *, '(a,i12)' ) ' Illegal input value of C = ', c stop end if if ( n == 0 ) then seed_lcrg = mod ( seed, c ) if ( seed_lcrg < 0 ) then seed_lcrg = seed_lcrg + c end if return end if ! ! Get A^N. ! call power_mod ( a, n, c, an ) ! ! Solve ( a - 1 ) * BN = ( a^N - 1 ) for BN. ! ! The LCRG I have been investigating uses B = 0, so this code ! has not been properly tested yet. ! am1 = a - 1 anm1tb = ( an - 1 ) * b call congruence ( am1, c, anm1tb, ierror, bn ) if ( ierror /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LCRG_SEED - Fatal error!' write ( *, '(a)' ) ' An error occurred in the CONGRUENCE routine.' write ( *, '(a,i8)' ) ' The error code was IERROR = ', ierror stop end if ! ! Set the new SEED. ! value2 = int ( an, kind = 8 ) * int ( seed, kind = 8 ) & + int ( bn, kind = 8 ) value2 = mod ( value2, int ( c, kind = 8 ) ) ! ! Guarantee that the value is positive. ! if ( value2 < 0 ) then value2 = value2 + int ( c, kind = 8 ) end if seed_lcrg = int ( value2, kind = 4 ) return end subroutine lmat_uniform ( m, n, seed, lmat ) !*****************************************************************************80 ! !! LMAT_UNIFORM returns a pseudorandom LMAT. ! ! Discussion: ! ! An LMAT is a two dimensional array of LOGICAL values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 01 December 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the order of the matrix. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, logical LMAT(M,N), a pseudorandom logical matrix. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ), parameter :: i4_huge_half = 1073741823 integer ( kind = 4 ) i integer ( kind = 4 ) j integer ( kind = 4 ) k logical lmat(m,n) integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LMAT_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if lmat(i,j) = ( i4_huge_half < seed ) end do end do return end subroutine lvec_uniform ( n, seed, lvec ) !*****************************************************************************80 ! !! LVEC_UNIFORM returns a pseudorandom LVEC. ! ! Discussion: ! ! An LVEC is a vector of LOGICAL values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 01 December 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the order of the vector. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, logical LVEC(N), a pseudorandom logical vector. ! implicit none integer ( kind = 4 ) n integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ), parameter :: i4_huge_half = 1073741823 integer ( kind = 4 ) i integer ( kind = 4 ) k logical lvec(n) integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'LVEC_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if lvec(i) = ( i4_huge_half < seed ) end do return end subroutine power_mod ( a, n, m, x ) !*****************************************************************************80 ! !! POWER_MOD computes ( A^N ) mod M. ! ! Discussion: ! ! Some programming tricks are used to speed up the computation, and to ! allow computations in which the value A**N is much too large to ! store in an integer word. ! ! First, for efficiency, the power A**N is computed by determining ! the binary expansion of N, then computing A, A**2, A**4, and so on ! by repeated squaring, and multiplying only those factors that ! contribute to A**N. ! ! Secondly, the intermediate products are immediately "mod'ed", which ! keeps them small. ! ! For instance, to compute ( A^13 ) mod 11, we essentially compute ! ! 13 = 1 + 4 + 8 ! ! A^13 = A * A^4 * A^8 ! ! A^13 ( mod 11 ) = A ( mod 11 ) * A^4 ( mod 11 ) * A^8 ( mod 11 ). ! ! Fermat's little theorem says that if P is prime, and A is not divisible ! by P, then ( A^(P-1) - 1 ) is divisible by P. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 May 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) A, the base of the expression to be tested. ! 0 <= A is required. ! ! Input, integer ( kind = 4 ) N, the power to which the base is raised. ! 0 <= N is required. ! ! Input, integer ( kind = 4 ) M, the divisor against which the expression ! is tested. 0 < M is required. ! ! Output, integer ( kind = 4 ) X, the remainder when A**N is divided by M. ! If any input quantity is unacceptable, then the nonsensical value ! X = -1 is returned. ! implicit none integer ( kind = 4 ) a integer ( kind = 8 ) a_square2 integer ( kind = 4 ) d integer ( kind = 4 ) m integer ( kind = 8 ) m2 integer ( kind = 4 ) n integer ( kind = 4 ) ncopy integer ( kind = 4 ), parameter :: two = 2 integer ( kind = 4 ) x integer ( kind = 8 ) x2 if ( a < 0 ) then x = -1 return end if if ( m <= 0 ) then x = -1 return end if if ( n < 0 ) then x = -1 return end if ! ! A_SQUARE contains the successive squares of A. ! a_square2 = int ( a, kind = 8 ) x2 = int ( 1, kind = 8 ) m2 = int ( m, kind = 8 ) ncopy = n do while ( 0 < ncopy ) d = mod ( ncopy, two ) if ( d == 1 ) then x2 = mod ( x2 * a_square2, m2 ) end if a_square2 = mod ( a_square2 * a_square2, m2 ) ncopy = ( ncopy - d ) / 2 end do ! ! Fix up X so that it is nonnegative. ! do while ( x2 < 0 ) x2 = x2 + m2 end do x = int ( x2 ) return end function r4_uniform ( a, b, seed ) !*****************************************************************************80 ! !! R4_UNIFORM returns a scaled pseudorandom R4. ! ! Discussion: ! ! An R4 is a real ( kind = 4 ) value. ! ! The pseudorandom number should be uniformly distributed ! between A and B. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, real ( kind = 4 ) A, B, the limits of the interval. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 4 ) R4_UNIFORM, a number strictly between A and B. ! implicit none real ( kind = 4 ) a real ( kind = 4 ) b integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 4 ) r4_uniform integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R4_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r4_uniform = a + ( b - a ) * real ( seed, kind = 4 ) * 4.656612875E-10 return end function r4_uniform_01 ( seed ) !*****************************************************************************80 ! !! R4_UNIFORM_01 returns a unit pseudorandom R4. ! ! Discussion: ! ! An R4 is a real ( kind = 4 ) value. ! ! This routine implements the recursion ! ! seed = ( 16807 * seed ) mod ( 2^31 - 1 ) ! r4_uniform_01 = seed / ( 2^31 - 1 ) ! ! The integer arithmetic never requires more than 32 bits, ! including a sign bit. ! ! If the initial seed is 12345, then the first three computations are ! ! Input Output R4_UNIFORM_01 ! SEED SEED ! ! 12345 207482415 0.096616 ! 207482415 1790989824 0.833995 ! 1790989824 2035175616 0.947702 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 4 ) R4_UNIFORM_01, a new pseudorandom variate, ! strictly between 0 and 1. ! implicit none integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 4 ) r4_uniform_01 if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R4_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r4_uniform_01 = real ( seed, kind = 4 ) * 4.656612875E-10 return end subroutine r4mat_uniform ( m, n, a, b, seed, r ) !*****************************************************************************80 ! !! R4MAT_UNIFORM returns a scaled pseudorandom R4MAT. ! ! Discussion: ! ! An R4MAT is an array of real ( kind = 4 ) values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns ! in the array. ! ! Input, real ( kind = 4 ) A, B, the lower and upper limits. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, ! which should NOT be 0. ! On output, SEED has been updated. ! ! Output, real ( kind = 4 ) R(M,N), the array of pseudorandom values. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n real ( kind = 4 ) a real ( kind = 4 ) b integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) j integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 4 ) r(m,n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R4MAT_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i,j) = a + ( b - a ) * real ( seed, kind = 4 ) * 4.656612875E-10 end do end do return end subroutine r4mat_uniform_01 ( m, n, seed, r ) !*****************************************************************************80 ! !! R4MAT_UNIFORM_01 returns a unit pseudorandom R4MAT. ! ! Discussion: ! ! An R4MAT is an array of real ( kind = 4 ) values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns ! in the array. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, ! which should NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 4 ) R(M,N), the array of pseudorandom values. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) j integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 4 ) r(m,n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R4MAT_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i,j) = real ( seed, kind = 4 ) * 4.656612875E-10 end do end do return end subroutine r4mat_uniform_write ( m, n, seed_init, seed, r, file_out_name ) !*****************************************************************************80 ! !! R4MAT_UNIFORM_WRITE writes a uniform pseudorandom R4MAT to a file. ! ! Discussion: ! ! An R4MAT is an array of real ( kind = 4 ) values. ! ! The initial lines of the file are comments, which begin with a ! '#' character. ! ! Thereafter, each line of the file contains the M-dimensional ! components of the next entry of the sequence. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, the spatial dimension. ! ! Input, integer ( kind = 4 ) N, the number of points. ! ! Input, integer ( kind = 4 ) SEED_INIT, the initial seed value. ! ! Input, integer ( kind = 4 ) SEED, the current seed. ! ! Input, real ( kind = 4 ) R(M,N), the points. ! ! Input, character ( len = * ) FILE_OUT_NAME, the name of ! the output file. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n character ( len = * ) file_out_name integer ( kind = 4 ) file_out_unit logical, parameter :: header = .false. integer ( kind = 4 ) ios integer ( kind = 4 ) j real ( kind = 4 ) r(m,n) integer ( kind = 4 ) seed integer ( kind = 4 ) seed_init character ( len = 40 ) string call get_unit ( file_out_unit ) open ( unit = file_out_unit, file = file_out_name, status = 'replace', & iostat = ios ) if ( ios /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R4MAT_UNIFORM_WRITE - Fatal error!' write ( *, '(a)' ) ' Could not open the output file.' stop end if if ( header ) then call timestring ( string ) write ( file_out_unit, '(a)' ) '# ' // trim ( file_out_name ) write ( file_out_unit, '(a)' ) '# created by R4MAT_UNIFORM_WRITE.F90.' write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a)' ) '# File generated on ' & // trim ( string ) write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a,i8)' ) '# Spatial dimension M = ', m write ( file_out_unit, '(a,i8)' ) '# Number of points N = ', n write ( file_out_unit, '(a,i12)' ) '# Initial seed = ', seed_init write ( file_out_unit, '(a,i12)' ) '# Current seed = ', seed write ( file_out_unit, '(a,g14.6)' ) '# EPSILON (unit roundoff) = ', & epsilon ( r(1,1) ) write ( file_out_unit, '(a)' ) '#' end if write ( string, '(a,i3,a)' ) '(', m, 'f10.6)' do j = 1, n write ( file_out_unit, string ) r(1:m,j) end do close ( unit = file_out_unit ) return end subroutine r4vec_uniform ( n, a, b, seed, r ) !*****************************************************************************80 ! !! R4VEC_UNIFORM returns a scaled pseudorandom R4VEC. ! ! Discussion: ! ! An R4VEC is a vector of real ( kind = 4 ) values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, the number of entries in the vector. ! ! Input, real ( kind = 4 ) A, B, the lower and upper limits. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, ! which should NOT be 0. ! On output, SEED has been updated. ! ! Output, real ( kind = 4 ) R(N), the vector of pseudorandom values. ! implicit none integer ( kind = 4 ) n real ( kind = 4 ) a real ( kind = 4 ) b integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 4 ) r(n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R4VEC_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i) = a + ( b - a ) * real ( seed, kind = 4 ) * 4.656612875E-10 end do return end subroutine r4vec_uniform_01 ( n, seed, r ) !*****************************************************************************80 ! !! R4VEC_UNIFORM_01 returns a unit pseudorandom R4VEC. ! ! Discussion: ! ! An R4VEC is an array of real ( kind = 4 ) values. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the number of entries in the vector. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, ! which should NOT be 0. ! On output, SEED has been updated. ! ! Output, real ( kind = 4 ) R(N), the vector of pseudorandom values. ! implicit none integer ( kind = 4 ) n integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 4 ) r(n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R4VEC_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i) = real ( seed, kind = 4 ) * 4.656612875E-10 end do return end function r8_uniform ( a, b, seed ) !*****************************************************************************80 ! !! R8_UNIFORM returns a scaled pseudorandom R8. ! ! Discussion: ! ! An R8 is a real ( kind = 8 ) value. ! ! For now, the input quantity SEED is an integer variable. ! ! The pseudorandom number should be uniformly distributed ! between A and B. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, real ( kind = 8 ) A, B, the limits of the interval. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R8_UNIFORM, a number strictly between A and B. ! implicit none real ( kind = 8 ) a real ( kind = 8 ) b integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 8 ) r8_uniform integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r8_uniform = a + ( b - a ) * real ( seed, kind = 8 ) * 4.656612875D-10 return end function r8_uniform_01 ( seed ) !*****************************************************************************80 ! !! R8_UNIFORM_01 returns a unit pseudorandom R8. ! ! Discussion: ! ! An R8 is a real ( kind = 8 ) value. ! ! For now, the input quantity SEED is an integer variable. ! ! This routine implements the recursion ! ! seed = ( 16807 * seed ) mod ( 2^31 - 1 ) ! r8_uniform_01 = seed / ( 2^31 - 1 ) ! ! The integer arithmetic never requires more than 32 bits, ! including a sign bit. ! ! If the initial seed is 12345, then the first three computations are ! ! Input Output R8_UNIFORM_01 ! SEED SEED ! ! 12345 207482415 0.096616 ! 207482415 1790989824 0.833995 ! 1790989824 2035175616 0.947702 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R8_UNIFORM_01, a new pseudorandom variate, ! strictly between 0 and 1. ! implicit none integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k real ( kind = 8 ) r8_uniform_01 integer ( kind = 4 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if ! ! Although SEED can be represented exactly as a 32 bit integer, ! it generally cannot be represented exactly as a 32 bit real number! ! r8_uniform_01 = real ( seed, kind = 8 ) * 4.656612875D-10 return end function r8i8_uniform ( a, b, seed ) !*****************************************************************************80 ! !! R8I8_UNIFORM returns a scaled pseudorandom R8 using an I8 seed. ! ! Discussion: ! ! An R8 is a real ( kind = 8 ) value. ! ! An I8 is an integer ( kind = 8 ) value. ! ! The pseudorandom number should be uniformly distributed ! between A and B. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, real ( kind = 8 ) A, B, the limits of the interval. ! ! Input/output, integer ( kind = 8 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R8I8_UNIFORM, a number strictly between A and B. ! implicit none real ( kind = 8 ) a real ( kind = 8 ) b integer ( kind = 8 ) k real ( kind = 8 ) r8i8_uniform integer ( kind = 8 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8I8_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + huge ( seed ) end if r8i8_uniform = a + ( b - a ) * real ( seed, kind = 8 ) * 4.656612875D-10 return end function r8i8_uniform_01 ( seed ) !*****************************************************************************80 ! !! R8I8_UNIFORM_01 returns a unit pseudorandom R8 using an I8 seed. ! ! Discussion: ! ! An R8 is a real ( kind = 8 ) value. ! ! An I8 is an integer ( kind = 8 ) value. ! ! This routine implements the recursion ! ! seed = ( 16807 * seed ) mod ( 2^31 - 1 ) ! r8_uniform_01 = seed / ( 2^31 - 1 ) ! ! The integer arithmetic never requires more than 32 bits, ! including a sign bit. ! ! If the initial seed is 12345, then the first three computations are ! ! Input Output R8I8_UNIFORM_01 ! SEED SEED ! ! 12345 207482415 0.096616 ! 207482415 1790989824 0.833995 ! 1790989824 2035175616 0.947702 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input/output, integer ( kind = 8 ) SEED, the "seed" value, which should ! NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R8I8_UNIFORM_01, a new pseudorandom variate, ! strictly between 0 and 1. ! implicit none integer ( kind = 8 ) k real ( kind = 8 ) r8i8_uniform_01 integer ( kind = 8 ) seed if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8I8_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + huge ( seed ) end if r8i8_uniform_01 = real ( seed, kind = 8 ) * 4.656612875D-10 return end subroutine r8mat_uniform ( m, n, a, b, seed, r ) !*****************************************************************************80 ! !! R8MAT_UNIFORM returns a scaled pseudorandom R8MAT. ! ! Discussion: ! ! An R8MAT is an array of real ( kind = 8 ) values. ! ! For now, the input quantity SEED is an integer variable. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns ! in the array. ! ! Input, real ( kind = 8 ) A, B, the lower and upper limits. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R(M,N), the array of pseudorandom values. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n real ( kind = 8 ) a real ( kind = 8 ) b integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) j integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 8 ) r(m,n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8MAT_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i,j) = a + ( b - a ) * real ( seed, kind = 8 ) * 4.656612875D-10 end do end do return end subroutine r8mat_uniform_01 ( m, n, seed, r ) !*****************************************************************************80 ! !! R8MAT_UNIFORM_01 returns a unit pseudorandom R8MAT. ! ! Discussion: ! ! An R8MAT is an array of real ( kind = 8 ) values. ! ! For now, the input quantity SEED is an integer variable. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, N, the number of rows and columns ! in the array. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R(M,N), the array of pseudorandom values. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) j integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 8 ) r(m,n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8MAT_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do j = 1, n do i = 1, m k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i,j) = real ( seed, kind = 8 ) * 4.656612875D-10 end do end do return end subroutine r8mat_uniform_write ( m, n, seed_init, seed, r, file_out_name ) !*****************************************************************************80 ! !! R8MAT_UNIFORM_WRITE writes a uniform pseudorandom R8MAT to a file. ! ! Discussion: ! ! An R8MAT is an array of real ( kind = 8 ) values. ! ! For now, the input quantity SEED is an integer variable. ! ! The initial lines of the file are comments, which begin with a ! '#' character. ! ! Thereafter, each line of the file contains the M-dimensional ! components of the next entry of the sequence. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, the spatial dimension. ! ! Input, integer ( kind = 4 ) N, the number of points. ! ! Input, integer ( kind = 4 ) SEED_INIT, the initial seed value. ! ! Input, integer ( kind = 4 ) SEED, the current seed value. ! ! Input, real ( kind = 8 ) R(M,N), the points. ! ! Input, character ( len = * ) FILE_OUT_NAME, the name of ! the output file. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n character ( len = * ) file_out_name integer ( kind = 4 ) file_out_unit logical, parameter :: header = .false. integer ( kind = 4 ) ios integer ( kind = 4 ) j real ( kind = 8 ) r(m,n) integer ( kind = 4 ) seed integer ( kind = 4 ) seed_init character ( len = 40 ) string call get_unit ( file_out_unit ) open ( unit = file_out_unit, file = file_out_name, status = 'replace', & iostat = ios ) if ( ios /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8MAT_UNIFORM_WRITE - Fatal error!' write ( *, '(a)' ) ' Could not open the output file.' stop end if if ( header ) then call timestring ( string ) write ( file_out_unit, '(a)' ) '# ' // trim ( file_out_name ) write ( file_out_unit, '(a)' ) '# created by R8MAT_UNIFORM_WRITE.F90.' write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a)' ) '# File generated on ' & // trim ( string ) write ( file_out_unit, '(a)' ) '#' write ( file_out_unit, '(a,i8)' ) '# Spatial dimension M = ', m write ( file_out_unit, '(a,i8)' ) '# Number of points N = ', n write ( file_out_unit, '(a,g14.6)' ) '# EPSILON (unit roundoff) = ', & epsilon ( r(1,1) ) write ( file_out_unit, '(a,i12)' ) '# Initial seed = ', seed_init write ( file_out_unit, '(a,i12)' ) '# Current seed = ', seed write ( file_out_unit, '(a)' ) '#' end if write ( string, '(a,i3,a)' ) '(', m, '(f10.6,2x))' do j = 1, n write ( file_out_unit, string ) r(1:m,j) end do close ( unit = file_out_unit ) return end subroutine r8vec_uniform ( n, a, b, seed, r ) !*****************************************************************************80 ! !! R8VEC_UNIFORM returns a scaled pseudorandom R8VEC. ! ! Discussion: ! ! An R8VEC is a vector of real ( kind = 8 ) values. ! ! For now, the input quantity SEED is an integer variable. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) M, the number of entries in the vector. ! ! Input, real ( kind = 8 ) A, B, the lower and upper limits. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R(N), the vector of pseudorandom values. ! implicit none integer ( kind = 4 ) n real ( kind = 8 ) a real ( kind = 8 ) b integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 8 ) r(n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8VEC_UNIFORM - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i) = a + ( b - a ) * real ( seed, kind = 8 ) * 4.656612875D-10 end do return end subroutine r8vec_uniform_01 ( n, seed, r ) !*****************************************************************************80 ! !! R8VEC_UNIFORM_01 returns a unit pseudorandom R8VEC. ! ! Discussion: ! ! An R8VEC is a vector of real ( kind = 8 ) values. ! ! For now, the input quantity SEED is an integer variable. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Paul Bratley, Bennett Fox, Linus Schrage, ! A Guide to Simulation, ! Second Edition, ! Springer, 1987, ! ISBN: 0387964673, ! LC: QA76.9.C65.B73. ! ! Bennett Fox, ! Algorithm 647: ! Implementation and Relative Efficiency of Quasirandom ! Sequence Generators, ! ACM Transactions on Mathematical Software, ! Volume 12, Number 4, December 1986, pages 362-376. ! ! Pierre L'Ecuyer, ! Random Number Generation, ! in Handbook of Simulation, ! edited by Jerry Banks, ! Wiley, 1998, ! ISBN: 0471134031, ! LC: T57.62.H37. ! ! Peter Lewis, Allen Goodman, James Miller, ! A Pseudo-Random Number Generator for the System/360, ! IBM Systems Journal, ! Volume 8, Number 2, 1969, pages 136-143. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, the number of entries in the vector. ! ! Input/output, integer ( kind = 4 ) SEED, the "seed" value, which ! should NOT be 0. On output, SEED has been updated. ! ! Output, real ( kind = 8 ) R(N), the vector of pseudorandom values. ! implicit none integer ( kind = 4 ) n integer ( kind = 4 ) i integer ( kind = 4 ), parameter :: i4_huge = 2147483647 integer ( kind = 4 ) k integer ( kind = 4 ) seed real ( kind = 8 ) r(n) if ( seed == 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'R8VEC_UNIFORM_01 - Fatal error!' write ( *, '(a)' ) ' Input value of SEED = 0.' stop end if do i = 1, n k = seed / 127773 seed = 16807 * ( seed - k * 127773 ) - k * 2836 if ( seed < 0 ) then seed = seed + i4_huge end if r(i) = real ( seed, kind = 8 ) * 4.656612875D-10 end do return end subroutine timestamp ( ) !*****************************************************************************80 ! !! TIMESTAMP prints the current YMDHMS date as a time stamp. ! ! Example: ! ! 31 May 2001 9:45:54.872 AM ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 06 August 2005 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! None ! implicit none character ( len = 8 ) ampm integer d integer h integer m integer mm character ( len = 9 ), parameter, dimension(12) :: month = (/ & 'January ', 'February ', 'March ', 'April ', & 'May ', 'June ', 'July ', 'August ', & 'September', 'October ', 'November ', 'December ' /) integer n integer s integer values(8) integer y call date_and_time ( values = values ) y = values(1) m = values(2) d = values(3) h = values(5) n = values(6) s = values(7) mm = values(8) if ( h < 12 ) then ampm = 'AM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Noon' else ampm = 'PM' end if else h = h - 12 if ( h < 12 ) then ampm = 'PM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Midnight' else ampm = 'AM' end if end if end if write ( *, '(i2,1x,a,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) & d, trim ( month(m) ), y, h, ':', n, ':', s, '.', mm, trim ( ampm ) return end subroutine timestring ( string ) !*****************************************************************************80 ! !! TIMESTRING writes the current YMDHMS date into a string. ! ! Example: ! ! STRING = 'May 31 2001 9:45:54.872 AM' ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 31 May 2007 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, character ( len = * ) STRING, contains the date information. ! A character length of 40 should always be sufficient. ! implicit none character ( len = 8 ) ampm integer ( kind = 4 ) d character ( len = 8 ) date integer ( kind = 4 ) h integer ( kind = 4 ) m integer ( kind = 4 ) mm character ( len = 9 ), parameter, dimension(12) :: month = (/ & 'January ', 'February ', 'March ', 'April ', & 'May ', 'June ', 'July ', 'August ', & 'September', 'October ', 'November ', 'December ' /) integer ( kind = 4 ) n integer ( kind = 4 ) s character ( len = * ) string character ( len = 10 ) time integer ( kind = 4 ) values(8) integer ( kind = 4 ) y character ( len = 5 ) zone call date_and_time ( date, time, zone, values ) y = values(1) m = values(2) d = values(3) h = values(5) n = values(6) s = values(7) mm = values(8) if ( h < 12 ) then ampm = 'AM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Noon' else ampm = 'PM' end if else h = h - 12 if ( h < 12 ) then ampm = 'PM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Midnight' else ampm = 'AM' end if end if end if write ( string, '(a,1x,i2,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) & trim ( month(m) ), d, y, h, ':', n, ':', s, '.', mm, trim ( ampm ) return end