program main !*****************************************************************************80 ! !! MAIN is the main program for CHEBYSHEV2_RULE. ! ! Discussion: ! ! This program computes a standard Gauss-Chebyshev type 2 quadrature rule ! and writes it to a file. ! ! The user specifies: ! * the ORDER (number of points) in the rule ! * the root name of the output files. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 February 2008 ! ! Author: ! ! John Burkardt ! implicit none integer ( kind = 4 ) arg_num integer ( kind = 4 ) iarg integer ( kind = 4 ) iargc integer ( kind = 4 ) ierror integer ( kind = 4 ) last integer ( kind = 4 ) order character ( len = 80 ) output character ( len = 80 ) string call timestamp ( ) write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'CHEBYSHEV2_RULE' write ( *, '(a)' ) ' FORTRAN90 version' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' Compute a Gauss-Chebyshev type 1 rule for' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' Integral ( -1 <= x <= +1 ) f(x) sqrt ( 1 - x^2 ) dx' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' of order ORDER.' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' The user specifies ORDER and OUTPUT.' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' OUTPUT is:' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' "C++" for printed C++ output;' write ( *, '(a)' ) ' "F77" for printed Fortran77 output;' write ( *, '(a)' ) ' "F90" for printed Fortran90 output;' write ( *, '(a)' ) ' "MAT" for printed MATLAB output;' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' or:' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' "filename" to generate 3 files:' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' filename_w.txt - the weight file' write ( *, '(a)' ) ' filename_x.txt - the abscissa file.' write ( *, '(a)' ) ' filename_r.txt - the region file.' ! ! Get the number of command line arguments. ! arg_num = iargc ( ) ! ! Get the order. ! if ( 1 <= arg_num ) then iarg = 1 call getarg ( iarg, string ) call s_to_i4 ( string, order, ierror, last ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' Enter the rule order ORDER:' read ( *, * ) order end if write ( *, '(a)' ) ' ' write ( *, '(a,i8)' ) ' The requested order of the rule is ', order ! ! Get the output option or quadrature file root name: ! if ( 2 <= arg_num ) then iarg = 2 call getarg ( iarg, output ) else write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' Enter OUTPUT (one of C++, F77, F90, MAT,' write ( *, '(a)' ) ' or else the "root name" of the quadrature files).' read ( *, '(a)' ) output end if write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' OUTPUT option = "' // trim ( output ) // '".' ! ! Construct the rule and output it. ! call chebyshev2_handle ( order, output ) write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'CHEBYSHEV2_RULE:' write ( *, '(a)' ) ' Normal end of execution.' write ( *, '(a)' ) ' ' call timestamp ( ) stop end subroutine ch_cap ( c ) !*****************************************************************************80 ! !! CH_CAP capitalizes a single character. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input/output, character C, the character to capitalize. ! implicit none character c integer ( kind = 4 ) itemp itemp = ichar ( c ) if ( 97 <= itemp .and. itemp <= 122 ) then c = char ( itemp - 32 ) end if return end function ch_eqi ( c1, c2 ) !*****************************************************************************80 ! !! CH_EQI is a case insensitive comparison of two characters for equality. ! ! Example: ! ! CH_EQI ( 'A', 'a' ) is .TRUE. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character C1, C2, the characters to compare. ! ! Output, logical CH_EQI, the result of the comparison. ! implicit none logical ch_eqi character c1 character c1_cap character c2 character c2_cap c1_cap = c1 c2_cap = c2 call ch_cap ( c1_cap ) call ch_cap ( c2_cap ) if ( c1_cap == c2_cap ) then ch_eqi = .true. else ch_eqi = .false. end if return end subroutine ch_to_digit ( c, digit ) !*****************************************************************************80 ! !! CH_TO_DIGIT returns the integer value of a base 10 digit. ! ! Example: ! ! C DIGIT ! --- ----- ! '0' 0 ! '1' 1 ! ... ... ! '9' 9 ! ' ' 0 ! 'X' -1 ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character C, the decimal digit, '0' through '9' or blank ! are legal. ! ! Output, integer ( kind = 4 ) DIGIT, the corresponding integer value. ! If C was 'illegal', then DIGIT is -1. ! implicit none character c integer ( kind = 4 ) digit if ( lge ( c, '0' ) .and. lle ( c, '9' ) ) then digit = ichar ( c ) - 48 else if ( c == ' ' ) then digit = 0 else digit = -1 end if return end subroutine chebyshev2_compute ( order, x, w ) !*****************************************************************************80 ! !! CHEBYSHEV2_COMPUTE computes a Gauss-Chebyshev type 2 quadrature rule. ! ! Discussion: ! ! The integration interval is [ -1, 1 ]. ! ! The weight function is w(x) = sqrt ( 1 - x^2 ). ! ! The integral to approximate: ! ! Integral ( -1 <= X <= 1 ) F(X) sqrt ( 1 - x^2 ) dX ! ! The quadrature rule: ! ! Sum ( 1 <= I <= ORDER ) WEIGHT(I) * F ( XTAB(I) ) ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 February 2008 ! ! Author: ! ! John Burkardt ! ! Reference: ! ! Philip Davis, Philip Rabinowitz, ! Methods of Numerical Integration, ! Second Edition, ! Dover, 2007, ! ISBN: 0486453391, ! LC: QA299.3.D28. ! ! Parameters: ! ! Input, integer ( kind = 4 ) ORDER, the order of the rule. ! ORDER must be greater than 0. ! ! Output, real ( kind = 8 ) X(ORDER), the abscissas. ! ! Output, real ( kind = 8 ) W(ORDER), the weights. ! implicit none integer ( kind = 4 ) order real ( kind = 8 ) angle integer ( kind = 4 ) i real ( kind = 8 ) :: pi = 3.141592653589793D+00 real ( kind = 8 ) x(order) real ( kind = 8 ) w(order) if ( order < 1 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'CHEBYSHEV2_COMPUTE - Fatal error!' write ( *, '(a,i8)' ) ' Illegal value of ORDER = ', order stop end if do i = 1, order angle = pi * real ( order + 1 - i, kind = 8 ) / real ( order + 1, kind = 8 ) w(i) = pi / real ( order + 1, kind = 8 ) * ( sin ( angle ) )**2 x(i) = cos ( angle ) end do return end subroutine chebyshev2_handle ( order, output ) !*****************************************************************************80 ! !! CHEBYSHEV2_HANDLE computes a Gauss-Chebyshev rule of type 2 and outputs it. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 22 February 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) ORDER, the order of the rule. ! ! Input, character ( len = * ) OUTPUT, specifies the output. ! * 'C++', print as C++ code. ! * 'F77', print as FORTRAN77 code. ! * 'F90', print as FORTRAN90 code. ! * 'MAT', print as MATLAB code. ! * file, write files 'file_w.txt', 'file_x.txt', 'file_r.txt' defining weights, ! abscissas, and region. ! implicit none logical header integer ( kind = 4 ) i integer ( kind = 4 ) order character ( len = * ) output character ( len = 80 ) output_r character ( len = 80 ) output_w character ( len = 80 ) output_x real ( kind = 8 ) r(2) real ( kind = 8 ), allocatable, dimension ( : ) :: w real ( kind = 8 ), allocatable, dimension ( : ) :: x r(1) = - 1.0D+00 r(2) = + 1.0D+00 allocate ( w(order) ) allocate ( x(order) ) call chebyshev2_compute ( order, x, w ) if ( output(1:3) == 'C++' .or. output(1:3) == 'c++' ) then write ( *, '(a)' ) '//' write ( *, '(a)' ) '// Weights W, abscissas X and range R' write ( *, '(a)' ) '// for a Gauss-Chebyshev type 2 quadrature rule' write ( *, '(a,i8)' ) '// ORDER = ', order write ( *, '(a)' ) '//' write ( *, '(a)' ) '// Standard rule:' write ( *, '(a)' ) '// Integral ( -1 <= x <= +1 ) f(x) sqrt ( 1 - x^2 ) dx' write ( *, '(a)' ) '// is to be approximated by' write ( *, '(a)' ) '// sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).' write ( *, '(a)' ) '//' do i = 1, order write ( *, '(a,i2,a,g24.16,a)' ) ' w[', i-1, '] = ', w(i), ';' end do write ( *, '(a)' ) ' ' do i = 1, order write ( *, '(a,i2,a,g24.16,a)' ) ' x[', i-1, '] = ', x(i), ';' end do write ( *, '(a)' ) ' ' do i = 1, 2 write ( *, '(a,i2,a,g24.16,a)' ) ' r[', i-1, '] = ', r(i), ';' end do else if ( output(1:3) == 'F77' .or. output(1:3) == 'f77' ) then write ( *, '(a)' ) 'c' write ( *, '(a)' ) 'c Weights W, abscissas X and range R' write ( *, '(a)' ) 'c for a Gauss-Chebyshev type 2 quadrature rule' write ( *, '(a,i8)' ) 'c ORDER = ', order write ( *, '(a)' ) 'c' write ( *, '(a)' ) 'c Standard rule:' write ( *, '(a)' ) 'c Integral ( -1 <= x <= +1 ) f(x) sqrt ( 1 - x^2 ) dx' write ( *, '(a)' ) 'c is to be approximated by' write ( *, '(a)' ) 'c sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).' write ( *, '(a)' ) 'c' do i = 1, order write ( *, '(a,i2,a,g24.16)' ) ' w(', i, ') = ', w(i) end do write ( *, '(a)' ) ' ' do i = 1, order write ( *, '(a,i2,a,g24.16)' ) ' x(', i, ') = ', x(i) end do write ( *, '(a)' ) ' ' do i = 1, 2 write ( *, '(a,i2,a,g24.16)' ) ' r(', i, ') = ', r(i) end do else if ( output(1:3) == 'F90' .or. output(1:3) == 'f90' ) then write ( *, '(a)' ) '!' write ( *, '(a)' ) '! Weights W, abscissas X and range R' write ( *, '(a)' ) '! for a Gauss-Chebyshev type 2 quadrature rule' write ( *, '(a,i8)' ) '! ORDER = ', order write ( *, '(a)' ) '!' write ( *, '(a)' ) '! Standard rule:' write ( *, '(a)' ) '! Integral ( -1 <= x <= +1 ) f(x) sqrt ( 1 - x^2 ) dx' write ( *, '(a)' ) '! is to be approximated by' write ( *, '(a)' ) '! sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).' write ( *, '(a)' ) '!' do i = 1, order write ( *, '(a,i2,a,g24.16)' ) ' w(', i, ') = ', w(i) end do write ( *, '(a)' ) ' ' do i = 1, order write ( *, '(a,i2,a,g24.16)' ) ' x(', i, ') = ', x(i) end do write ( *, '(a)' ) ' ' do i = 1, 2 write ( *, '(a,i2,a,g24.16)' ) ' r(', i, ') = ', r(i) end do else if ( output(1:3) == 'MAT' ) then write ( *, '(a)' ) '%' write ( *, '(a)' ) '% Weights W, abscissas X and range R' write ( *, '(a)' ) '% for a Gauss-Chebyshev type 2 quadrature rule' write ( *, '(a,i8)' ) '% ORDER = ', order write ( *, '(a)' ) '%' write ( *, '(a)' ) '% Standard rule:' write ( *, '(a)' ) '% Integral ( -1 <= x <= +1 ) f(x) sqrt ( 1 - x^2 ) dx' write ( *, '(a)' ) '% is to be approximated by' write ( *, '(a)' ) '% sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).' write ( *, '(a)' ) '%' do i = 1, order write ( *, '(a,i2,a,g24.16,a)' ) ' w(', i, ') = ', w(i), ';' end do write ( *, '(a)' ) ' ' do i = 1, order write ( *, '(a,i2,a,g24.16,a)' ) ' x(', i, ') = ', x(i), ';' end do write ( *, '(a)' ) ' ' do i = 1, 2 write ( *, '(a,i2,a,g24.16,a)' ) ' r(', i, ') = ', r(i), ';' end do else output_w = trim ( output ) // '_w.txt' output_x = trim ( output ) // '_x.txt' output_r = trim ( output ) // '_r.txt' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' Creating quadrature files.' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' "Root" file name is "' // trim ( output ) // '".' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' Weight file will be "' // trim ( output_w ) // '".' write ( *, '(a)' ) ' Abscissa file will be "' // trim ( output_x ) // '".' write ( *, '(a)' ) ' Region file will be "' // trim ( output_r ) // '".' header = .false. call dtable_write ( output_w, 1, order, w, header ) call dtable_write ( output_x, 1, order, x, header ) call dtable_write ( output_r, 1, 2, r, header ) end if deallocate ( w ) deallocate ( x ) return end subroutine dtable_close_write ( output_unit ) !*****************************************************************************80 ! !! DTABLE_CLOSE_WRITE closes a file used to write a DTABLE. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OUTPUT_UNIT, the output unit that was used. ! implicit none integer ( kind = 4 ) output_unit close ( unit = output_unit ) return end subroutine dtable_data_write ( output_unit, m, n, table ) !*****************************************************************************80 ! !! DTABLE_DATA_WRITE writes DTABLE data to a file. ! ! Discussion: ! ! This routine writes a single line of output for each point, ! containing its spatial coordinates. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer ( kind = 4 ) OUTPUT_UNIT, the output unit. ! ! Input, integer ( kind = 4 ) M, the spatial dimension. ! ! Input, integer ( kind = 4 ) N, the number of points. ! ! Input, real ( kind = 8 ) TABLE(M,N), the table data. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n integer ( kind = 4 ) output_unit integer ( kind = 4 ) j character ( len = 30 ) string real ( kind = 8 ) table(m,n) ! ! Create the format string. ! write ( string, '(a1,i8,a1,i8,a1,i8,a1)' ) '(', m, 'g', 24, '.', 16, ')' call s_blank_delete ( string ) do j = 1, n write ( output_unit, string ) table(1:m,j) end do return end subroutine dtable_header_write ( output_file_name, output_unit, m, n ) !*****************************************************************************80 ! !! DTABLE_HEADER_WRITE writes the header to a DTABLE file. ! ! Discussion: ! ! The file must already be open before this routine is called. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) OUTPUT_FILE_NAME, the output file name. ! ! Input, integer ( kind = 4 ) OUTPUT_UNIT, the output unit. ! ! Input, integer ( kind = 4 ) M, the spatial dimension. ! ! Input, integer ( kind = 4 ) N, the number of points. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n character ( len = * ) output_file_name integer ( kind = 4 ) output_unit character ( len = 40 ) string real ( kind = 8 ), parameter :: x = 1.0D+00 call timestring ( string ) write ( output_unit, '(a)' ) '# ' // trim ( output_file_name ) write ( output_unit, '(a)' ) '# created by TABLE_IO.F90' write ( output_unit, '(a)' ) '# at ' // trim ( string ) write ( output_unit, '(a)' ) '#' write ( output_unit, '(a,i8)' ) '# Spatial dimension M = ', m write ( output_unit, '(a,i8)' ) '# Number of points N = ', n write ( output_unit, '(a,g14.6)' ) '# EPSILON (unit roundoff) = ', & epsilon ( x ) write ( output_unit, '(a)' ) '#' return end subroutine dtable_open_write ( output_file_name, output_unit ) !*****************************************************************************80 ! !! DTABLE_OPEN_WRITE opens a file to write a DTABLE. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) OUTPUT_FILE_NAME, the output file name. ! ! Output, integer ( kind = 4 ) OUTPUT_UNIT, the output unit to be used. ! implicit none character ( len = * ) output_file_name integer ( kind = 4 ) output_status integer ( kind = 4 ) output_unit call get_unit ( output_unit ) open ( unit = output_unit, file = output_file_name, & status = 'replace', iostat = output_status ) if ( output_status /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'DTABLE_OPEN_WRITE - Fatal error!' write ( *, '(a,i8)' ) ' Could not open the output file "' // & trim ( output_file_name ) // '" on unit ', output_unit output_unit = -1 stop end if return end subroutine dtable_write ( output_file_name, m, n, table, header ) !*****************************************************************************80 ! !! DTABLE_WRITE writes a DTABLE to a file. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) OUTPUT_FILE_NAME, the output file name. ! ! Input, integer ( kind = 4 ) M, the spatial dimension. ! ! Input, integer ( kind = 4 ) N, the number of points. ! ! Input, real ( kind = 8 ) TABLE(M,N), the table data. ! ! Input, logical HEADER, is TRUE if the header is to be included. ! implicit none integer ( kind = 4 ) m integer ( kind = 4 ) n logical header character ( len = * ) output_file_name integer ( kind = 4 ) output_unit real ( kind = 8 ) table(m,n) call dtable_open_write ( output_file_name, output_unit ) if ( header ) then call dtable_header_write ( output_file_name, output_unit, m, n ) end if call dtable_data_write ( output_unit, m, n, table ) call dtable_close_write ( output_unit ) 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: ! ! 15 January 2008 ! ! 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 subroutine s_blank_delete ( s ) !*****************************************************************************80 ! !! S_BLANK_DELETE removes blanks from a string, left justifying the remainder. ! ! Discussion: ! ! All TAB characters are also removed. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input/output, character ( len = * ) S, the string to be transformed. ! implicit none character c integer ( kind = 4 ) get integer ( kind = 4 ) put integer ( kind = 4 ) nchar character ( len = * ) s character, parameter :: TAB = char ( 9 ) put = 0 nchar = len_trim ( s ) do get = 1, nchar c = s(get:get) if ( c /= ' ' .and. c /= TAB ) then put = put + 1 s(put:put) = c end if end do s(put+1:nchar) = ' ' return end subroutine s_to_i4 ( s, ival, ierror, length ) !*****************************************************************************80 ! !! S_TO_I4 reads an I4 from a string. ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) S, a string to be examined. ! ! Output, integer ( kind = 4 ) IVAL, the integer value read from the string. ! If the string is blank, then IVAL will be returned 0. ! ! Output, integer ( kind = 4 ) IERROR, an error flag. ! 0, no error. ! 1, an error occurred. ! ! Output, integer ( kind = 4 ) LENGTH, the number of characters of S ! used to make IVAL. ! implicit none character c integer ( kind = 4 ) i integer ( kind = 4 ) ierror integer ( kind = 4 ) isgn integer ( kind = 4 ) istate integer ( kind = 4 ) ival integer ( kind = 4 ) length character ( len = * ) s ierror = 0 istate = 0 isgn = 1 ival = 0 do i = 1, len_trim ( s ) c = s(i:i) ! ! Haven't read anything. ! if ( istate == 0 ) then if ( c == ' ' ) then else if ( c == '-' ) then istate = 1 isgn = -1 else if ( c == '+' ) then istate = 1 isgn = + 1 else if ( lle ( '0', c ) .and. lle ( c, '9' ) ) then istate = 2 ival = ichar ( c ) - ichar ( '0' ) else ierror = 1 return end if ! ! Have read the sign, expecting digits. ! else if ( istate == 1 ) then if ( c == ' ' ) then else if ( lle ( '0', c ) .and. lle ( c, '9' ) ) then istate = 2 ival = ichar ( c ) - ichar ( '0' ) else ierror = 1 return end if ! ! Have read at least one digit, expecting more. ! else if ( istate == 2 ) then if ( lle ( '0', c ) .and. lle ( c, '9' ) ) then ival = 10 * ival + ichar ( c ) - ichar ( '0' ) else ival = isgn * ival length = i - 1 return end if end if end do ! ! If we read all the characters in the string, see if we're OK. ! if ( istate == 2 ) then ival = isgn * ival length = len_trim ( s ) else ierror = 1 length = 0 end if return end subroutine timestamp ( ) !*****************************************************************************80 ! !! TIMESTAMP prints the current YMDHMS date as a time stamp. ! ! Example: ! ! May 31 2001 9:45:54.872 AM ! ! Licensing: ! ! This code is distributed under the GNU LGPL license. ! ! Modified: ! ! 15 January 2008 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! None ! 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 = 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 ( *, '(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 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: ! ! 15 January 2008 ! ! 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