subroutine bernstein_matrix ( n, a ) c*********************************************************************72 c cc bernstein_matrix() returns the Bernstein matrix. c c Discussion: c c The Bernstein matrix of order N is an NxN matrix A which can be used to c transform a vector of power basis coefficients C representing a polynomial c P(X) to a corresponding Bernstein basis coefficient vector B: c c B = A * C c c The N power basis vectors are ordered as (1,X,X^2,...X^(N-1)) and the N c Bernstein basis vectors as ((1-X)^(N-1), X*(1_X)^(N-2),...,X^(N-1)). c c For N = 5, the matrix has the form: c c 1 -4 6 -4 1 c 0 4 -12 12 -4 c 0 0 6 -12 6 c 0 0 0 4 -4 c 0 0 0 0 1 c c and the numbers in each column represent the coefficients in the power c series expansion of a Bernstein polynomial, so that c c B(5,4) = - 4 x^4 + 12 x^3 - 12 x^2 + 4 x c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 10 February 2012 c c Author: c c John Burkardt c c Parameters: c c Input, integer N, the order of the matrix. c c Output, double precision A(N,N), the Bernstein matrix. c implicit none integer n double precision a(n,n) integer i0 integer j0 integer n0 double precision r8_choose double precision r8_mop n0 = n - 1 do j0 = 0, n0 do i0 = 0, j0 a(i0+1,j0+1) = r8_mop ( j0 - i0 ) & * r8_choose ( n0 - i0, j0 - i0 ) * r8_choose ( n0, i0 ) end do do i0 = j0 + 1, n0 a(i0+1,j0+1) = 0.0D+00 end do end do return end subroutine bernstein_matrix_inverse ( n, a ) c*********************************************************************72 c cc bernstein_matrix_inverse() returns the inverse Bernstein matrix. c c Discussion: c c The inverse Bernstein matrix of order N is an NxN matrix A which can c be used to transform a vector of Bernstein basis coefficients B c representing a polynomial P(X) to a corresponding power basis c coefficient vector C: c c C = A * B c c The N power basis vectors are ordered as (1,X,X^2,...X^(N-1)) and the N c Bernstein basis vectors as ((1-X)^(N-1), X*(1_X)^(N-2),...,X^(N-1)). c c For N = 5, the matrix has the form: c c 1 1 1 1 1 c 0 1/4 1/2 3/4 1 c 0 0 1/6 1/2 1 c 0 0 0 1/4 1 c 0 0 0 0 1 c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 10 February 2012 c c Author: c c John Burkardt c c Parameters: c c Input, integer N, the order of the matrix. c c Output, double precision A(N,N), the inverse Bernstein matrix. c implicit none integer n double precision a(n,n) integer i0 integer j0 integer n0 double precision r8_choose n0 = n - 1 do j0 = 0, n0 do i0 = 0, j0 a(i0+1,j0+1) = r8_choose ( j0, i0 ) / r8_choose ( n0, i0 ) end do do i0 = j0 + 1, n0 a(i0+1,j0+1) = 0.0D+00 end do end do return end subroutine bernstein_poly_01 ( n, x, bern ) c*********************************************************************72 c cc BERNSTEIN_POLY_01 evaluates the Bernstein polynomials based in [0,1]. c c Discussion: c c The Bernstein polynomials are assumed to be based on [0,1]. c c The formula is: c c B(N,I)(X) = [N!/(I!*(N-I)!)] * (1-X)^(N-I) * X^I c c First values: c c B(0,0)(X) = 1 c c B(1,0)(X) = 1-X c B(1,1)(X) = X c c B(2,0)(X) = (1-X)^2 c B(2,1)(X) = 2 * (1-X) * X c B(2,2)(X) = X^2 c c B(3,0)(X) = (1-X)^3 c B(3,1)(X) = 3 * (1-X)^2 * X c B(3,2)(X) = 3 * (1-X) * X^2 c B(3,3)(X) = X^3 c c B(4,0)(X) = (1-X)^4 c B(4,1)(X) = 4 * (1-X)^3 * X c B(4,2)(X) = 6 * (1-X)^2 * X^2 c B(4,3)(X) = 4 * (1-X) * X^3 c B(4,4)(X) = X^4 c c Special values: c c B(N,I)(X) has a unique maximum value at X = I/N. c c B(N,I)(X) has an I-fold zero at 0 and and N-I fold zero at 1. c c B(N,I)(1/2) = C(N,K) / 2^N c c For a fixed X and N, the polynomials add up to 1: c c Sum ( 0 <= I <= N ) B(N,I)(X) = 1 c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 10 February 2012 c c Author: c c John Burkardt c c Parameters: c c Input, integer N, the degree of the Bernstein polynomials c to be used. For any N, there is a set of N+1 Bernstein polynomials, c each of degree N, which form a basis for polynomials on [0,1]. c c Input, double precision X, the evaluation point. c c Output, double precision BERN(0:N), the values of the N+1 c Bernstein polynomials at X. c implicit none integer n double precision bern(0:n) integer i integer j double precision x if ( n .eq. 0 ) then bern(0) = 1.0D+00 else if ( 0 .lt. n ) then bern(0) = 1.0D+00 - x bern(1) = x do i = 2, n bern(i) = x * bern(i-1) do j = i - 1, 1, -1 bern(j) = x * bern(j-1) & + ( 1.0D+00 - x ) * bern(j) end do bern(0) = ( 1.0D+00 - x ) * bern(0) end do end if return end subroutine bernstein_poly_01_values ( n_data, n, k, x, b ) c*********************************************************************72 c cc BERNSTEIN_POLY_01_VALUES returns some values of the Bernstein polynomials. c c Discussion: c c The Bernstein polynomials are assumed to be based on [0,1]. c c The formula for the Bernstein polynomials is c c B(N,I)(X) = [N!/(I!*(N-I)!)] * (1-X)^(N-I) * X^I c c In Mathematica, the function can be evaluated by: c c Binomial[n,i] * (1-x)^(n-i) * x^i c c First values: c c B(0,0)(X) = 1 c c B(1,0)(X) = 1-X c B(1,1)(X) = X c c B(2,0)(X) = (1-X)^2 c B(2,1)(X) = 2 * (1-X) * X c B(2,2)(X) = X^2 c c B(3,0)(X) = (1-X)^3 c B(3,1)(X) = 3 * (1-X)^2 * X c B(3,2)(X) = 3 * (1-X) * X^2 c B(3,3)(X) = X^3 c c B(4,0)(X) = (1-X)^4 c B(4,1)(X) = 4 * (1-X)^3 * X c B(4,2)(X) = 6 * (1-X)^2 * X^2 c B(4,3)(X) = 4 * (1-X) * X^3 c B(4,4)(X) = X^4 c c Special values: c c B(N,I)(X) has a unique maximum value at X = I/N. c c B(N,I)(X) has an I-fold zero at 0 and and N-I fold zero at 1. c c B(N,I)(1/2) = C(N,K) / 2^N c c For a fixed X and N, the polynomials add up to 1: c c Sum ( 0 <= I <= N ) B(N,I)(X) = 1 c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 20 March 2007 c c Author: c c John Burkardt c c Reference: c c Stephen Wolfram, c The Mathematica Book, c Fourth Edition, c Cambridge University Press, 1999, c ISBN: 0-521-64314-7, c LC: QA76.95.W65. c c Parameters: c c Input/output, integer N_DATA. The user sets N_DATA to 0 before the c first call. On each call, the routine increments N_DATA by 1, and c returns the corresponding data; when there is no more data, the c output value of N_DATA will be 0 again. c c Output, integer N, the degree of the polynomial. c c Output, integer K, the index of the polynomial. c c Output, double precision X, the argument of the polynomial. c c Output, double precision B, the value of the polynomial B(N,K)(X). c implicit none integer n_max parameter ( n_max = 15 ) double precision b double precision b_vec(n_max) integer k integer k_vec(n_max) integer n integer n_data integer n_vec(n_max) double precision x double precision x_vec(n_max) save b_vec save k_vec save n_vec save x_vec data b_vec / & 0.1000000000000000D+01, & 0.7500000000000000D+00, & 0.2500000000000000D+00, & 0.5625000000000000D+00, & 0.3750000000000000D+00, & 0.6250000000000000D-01, & 0.4218750000000000D+00, & 0.4218750000000000D+00, & 0.1406250000000000D+00, & 0.1562500000000000D-01, & 0.3164062500000000D+00, & 0.4218750000000000D+00, & 0.2109375000000000D+00, & 0.4687500000000000D-01, & 0.3906250000000000D-02 / data k_vec / & 0, & 0, 1, & 0, 1, 2, & 0, 1, 2, 3, & 0, 1, 2, 3, 4 / data n_vec / & 0, & 1, 1, & 2, 2, 2, & 3, 3, 3, 3, & 4, 4, 4, 4, 4 / data x_vec / & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00, & 0.25D+00 / if ( n_data .lt. 0 ) then n_data = 0 end if n_data = n_data + 1 if ( n_max .lt. n_data ) then n_data = 0 n = 0 k = 0 x = 0.0D+00 b = 0.0D+00 else n = n_vec(n_data) k = k_vec(n_data) x = x_vec(n_data) b = b_vec(n_data) end if return end subroutine bernstein_poly_ab ( n, a, b, x, bern ) c*********************************************************************72 c cc BERNSTEIN_POLY_AB evaluates the Bernstein polynomials based in [A,B]. c c Discussion: c c The formula is: c c BERN(N,I)(X) = [N!/(I!*(N-I)!)] * (B-X)^(N-I) * (X-A)^I / (B-A)^N c c First values: c c B(0,0)(X) = 1 c c B(1,0)(X) = ( B-X ) / (B-A) c B(1,1)(X) = ( X-A ) / (B-A) c c B(2,0)(X) = ( (B-X)^2 ) / (B-A)^2 c B(2,1)(X) = ( 2 * (B-X) * (X-A) ) / (B-A)^2 c B(2,2)(X) = ( (X-A)^2 ) / (B-A)^2 c c B(3,0)(X) = ( (B-X)^3 ) / (B-A)^3 c B(3,1)(X) = ( 3 * (B-X)^2 * (X-A) ) / (B-A)^3 c B(3,2)(X) = ( 3 * (B-X) * (X-A)^2 ) / (B-A)^3 c B(3,3)(X) = ( (X-A)^3 ) / (B-A)^3 c c B(4,0)(X) = ( (B-X)^4 ) / (B-A)^4 c B(4,1)(X) = ( 4 * (B-X)^3 * (X-A) ) / (B-A)^4 c B(4,2)(X) = ( 6 * (B-X)^2 * (X-A)^2 ) / (B-A)^4 c B(4,3)(X) = ( 4 * (B-X) * (X-A)^3 ) / (B-A)^4 c B(4,4)(X) = ( (X-A)^4 ) / (B-A)^4 c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 10 February 2012 c c Author: c c John Burkardt c c Parameters: c c Input, integer N, the degree of the Bernstein polynomials c to be used. For any N, there is a set of N+1 Bernstein polynomials, c each of degree N, which form a basis for polynomials on [A,B]. c c Input, double precision A, B, the endpoints of the interval on which the c polynomials are to be based. A and B should not be equal. c c Input, double precision X, the point at which the polynomials c are to be evaluated. c c Output, double precision BERN(0:N), the values of the N+1 c Bernstein polynomials at X. c implicit none integer n double precision a double precision b double precision bern(0:n) integer i integer j double precision x if ( b .eq. a ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'BERNSTEIN_POLY_AB - Fatal error!' write ( *, '(a,g14.6)' ) ' A = B = ', a stop end if if ( n .eq. 0 ) then bern(0) = 1.0D+00 else if ( 0 .lt. n ) then bern(0) = ( b - x ) / ( b - a ) bern(1) = ( x - a ) / ( b - a ) do i = 2, n bern(i) = ( x - a ) * bern(i-1) / ( b - a ) do j = i - 1, 1, -1 bern(j) = ( ( b - x ) * bern(j) & + ( x - a ) * bern(j-1) ) & / ( b - a ) end do bern(0) = ( b - x ) * bern(0) / ( b - a ) end do end if return end subroutine bernstein_poly_ab_approx ( n, a, b, ydata, & nval, xval, yval ) c*********************************************************************72 c cc BERNSTEIN_POLY_AB_APPROX: Bernstein approximant to F(X) on [A,B]. c c Formula: c c BPAB(F)(X) = sum ( 0 <= I <= N ) F(X(I)) * B_BASE(I,X) c c where c c X(I) = ( ( N - I ) * A + I * B ) / N c B_BASE(I,X) is the value of the I-th Bernstein basis polynomial at X. c c Discussion: c c The Bernstein polynomial BPAB(F) for F(X) over [A,B] is an approximant, c not an interpolant; in other words, its value is not guaranteed to equal c that of F at any particular point. However, for a fixed interval c [A,B], if we let N increase, the Bernstein polynomial converges c uniformly to F everywhere in [A,B], provided only that F is continuous. c Even if F is not continuous, but is bounded, the polynomial converges c pointwise to F(X) at all points of continuity. On the other hand, c the convergence is quite slow compared to other interpolation c and approximation schemes. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 10 February 2012 c c Author: c c John Burkardt c c Reference: c c David Kahaner, Cleve Moler, Steven Nash, c Numerical Methods and Software, c Prentice Hall, 1989, c ISBN: 0-13-627258-4, c LC: TA345.K34. c c Parameters: c c Input, integer N, the degree of the Bernstein polynomial c to be used. N must be at least 0. c c Input, double precision A, B, the endpoints of the interval on which the c approximant is based. A and B should not be equal. c c Input, double precision YDATA(0:N), the data values at N+1 equally c spaced points in [A,B]. If N = 0, then the evaluation point should c be 0.5 * ( A + B). Otherwise, evaluation point I should be c ( (N-I)*A + I*B ) / N ). c c Input, integer NVAL, the number of points at which the c approximant is to be evaluated. c c Input, double precision XVAL(NVAL), the point at which the Bernstein c polynomial approximant is to be evaluated. The entries of XVAL do not c have to lie in the interval [A,B]. c c Output, double precision YVAL(NVAL), the values of the Bernstein c polynomial approximant for F, based in [A,B], evaluated at XVAL. c implicit none integer n integer nval double precision a double precision b double precision bvec(0:n) integer i double precision r8vec_dot_product double precision xval(nval) double precision ydata(0:n) double precision yval(nval) do i = 1, nval c c Evaluate the Bernstein basis polynomials at XVAL. c call bernstein_poly_ab ( n, a, b, xval(i), bvec ) c c Now compute the sum of YDATA(I) * BVEC(I). c yval(i) = r8vec_dot_product ( n + 1, ydata, bvec ) end do return end function r8_choose ( n, k ) c*********************************************************************72 c cc R8_CHOOSE computes the binomial coefficient C(N,K) as an R8. c c Discussion: c c The value is calculated in such a way as to avoid overflow and c roundoff. The calculation is done in R8 arithmetic. c c The formula used is: c c C(N,K) = N! / ( K! * (N-K)! ) c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 07 June 2008 c c Author: c c John Burkardt c c Reference: c c ML Wolfson, HV Wright, c Algorithm 160: c Combinatorial of M Things Taken N at a Time, c Communications of the ACM, c Volume 6, Number 4, April 1963, page 161. c c Parameters: c c Input, integer N, K, are the values of N and K. c c Output, double precision R8_CHOOSE, the number of combinations of N c things taken K at a time. c implicit none integer i integer k integer mn integer mx integer n double precision r8_choose double precision value mn = min ( k, n - k ) if ( mn .lt. 0 ) then value = 0.0D+00 else if ( mn .eq. 0 ) then value = 1.0D+00 else mx = max ( k, n - k ) value = dble ( mx + 1 ) do i = 2, mn value = ( value * dble ( mx + i ) ) / dble ( i ) end do end if r8_choose = value return end function r8_mop ( i ) c*********************************************************************72 c cc R8_MOP returns the I-th power of -1 as an R8 value. c c Discussion: c c An R8 is a double precision real value. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 26 July 2008 c c Author: c c John Burkardt c c Parameters: c c Input, integer I, the power of -1. c c Output, double precision R8_MOP, the I-th power of -1. c implicit none integer i double precision r8_mop if ( mod ( i, 2 ) .eq. 0 ) then r8_mop = + 1.0D+00 else r8_mop = - 1.0D+00 end if return end function r8_uniform_01 ( seed ) c*********************************************************************72 c cc R8_UNIFORM_01 returns a unit pseudorandom R8. c c Discussion: c c This routine implements the recursion c c seed = 16807 * seed mod ( 2^31 - 1 ) c r8_uniform_01 = seed / ( 2^31 - 1 ) c c The integer arithmetic never requires more than 32 bits, c including a sign bit. c c If the initial seed is 12345, then the first three computations are c c Input Output R8_UNIFORM_01 c SEED SEED c c 12345 207482415 0.096616 c 207482415 1790989824 0.833995 c 1790989824 2035175616 0.947702 c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 11 August 2004 c c Author: c c John Burkardt c c Reference: c c Paul Bratley, Bennett Fox, Linus Schrage, c A Guide to Simulation, c Springer Verlag, pages 201-202, 1983. c c Pierre L'Ecuyer, c Random Number Generation, c in Handbook of Simulation, c edited by Jerry Banks, c Wiley Interscience, page 95, 1998. c c Bennett Fox, c Algorithm 647: c Implementation and Relative Efficiency of Quasirandom c Sequence Generators, c ACM Transactions on Mathematical Software, c Volume 12, Number 4, pages 362-376, 1986. c c Peter Lewis, Allen Goodman, James Miller, c A Pseudo-Random Number Generator for the System/360, c IBM Systems Journal, c Volume 8, pages 136-143, 1969. c c Parameters: c c Input/output, integer SEED, the "seed" value, which should NOT be 0. c On output, SEED has been updated. c c Output, double precision R8_UNIFORM_01, a new pseudorandom variate, c strictly between 0 and 1. c implicit none double precision r8_uniform_01 integer k integer seed if ( seed .eq. 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 .lt. 0 ) then seed = seed + 2147483647 end if r8_uniform_01 = dble ( seed ) * 4.656612875D-10 return end subroutine r8mat_is_identity ( n, a, error_frobenius ) c*********************************************************************72 c cc R8MAT_IS_IDENTITY determines if an R8MAT is the identity. c c Discussion: c c An R8MAT is a matrix of double precision values. c c The routine returns the Frobenius norm of A - I. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 02 November 2007 c c Author: c c John Burkardt c c Parameters: c c Input, integer N, the order of the matrix. c c Input, double precision A(N,N), the matrix. c c Output, double precision ERROR_FROBENIUS, the Frobenius norm c of the difference matrix A - I, which would be exactly zero c if A were the identity matrix. c implicit none integer n double precision a(n,n) double precision error_frobenius integer i integer j error_frobenius = 0.0D+00 do i = 1, n do j = 1, n if ( i .eq. j ) then error_frobenius = error_frobenius + ( a(i,j) - 1.0D+00 )**2 else error_frobenius = error_frobenius + a(i,j)**2 end if end do end do error_frobenius = sqrt ( error_frobenius ) return end subroutine r8mat_mm ( n1, n2, n3, a, b, c ) c*********************************************************************72 c cc R8MAT_MM multiplies two R8MAT's. c c Discussion: c c An R8MAT is an array of R8 values. c c In FORTRAN90, this operation is more efficiently done by the c command: c c C(1:N1,1:N3) = MATMUL ( A(1:N1,1;N2), B(1:N2,1:N3) ) c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 12 December 2004 c c Author: c c John Burkardt c c Parameters: c c Input, integer N1, N2, N3, the order of the matrices. c c Input, double precision A(N1,N2), B(N2,N3), the matrices to multiply. c c Output, double precision C(N1,N3), the product matrix C = A * B. c implicit none integer n1 integer n2 integer n3 double precision a(n1,n2) double precision b(n2,n3) double precision c(n1,n3) integer i integer j integer k do i = 1, n1 do j = 1, n3 c(i,j) = 0.0D+00 do k = 1, n2 c(i,j) = c(i,j) + a(i,k) * b(k,j) end do end do end do return end subroutine r8mat_mv ( m, n, a, x, y ) c*********************************************************************72 c cc R8MAT_MV multiplies a matrix times a vector. c c Discussion: c c An R8MAT is an array of R8's. c c In FORTRAN90, this operation can be more efficiently carried c out by the command c c Y(1:M) = MATMUL ( A(1:M,1:N), X(1:N) ) c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 12 December 2004 c c Author: c c John Burkardt c c Parameters: c c Input, integer M, N, the number of rows and columns of the matrix. c c Input, double precision A(M,N), the M by N matrix. c c Input, double precision X(N), the vector to be multiplied by A. c c Output, double precision Y(M), the product A*X. c implicit none integer m integer n double precision a(m,n) integer i integer j double precision x(n) double precision y(m) double precision y1(m) do i = 1, m y1(i) = 0.0D+00 do j = 1, n y1(i) = y1(i) + a(i,j) * x(j) end do end do do i = 1, m y(i) = y1(i) end do return end function r8mat_norm_fro ( m, n, a ) c*********************************************************************72 c cc R8MAT_NORM_FRO returns the Frobenius norm of an R8MAT. c c Discussion: c c An R8MAT is an array of R8's. c c The Frobenius norm is defined as c c R8MAT_NORM_FRO = sqrt ( c sum ( 1 .le. I .le. M ) sum ( 1 .le. j .le. N ) A(I,J)**2 ) c c The matrix Frobenius norm is not derived from a vector norm, but c is compatible with the vector L2 norm, so that: c c r8vec_norm_l2 ( A * x ) <= r8mat_norm_fro ( A ) * r8vec_norm_l2 ( x ). c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 26 July 2008 c c Author: c c John Burkardt c c Parameters: c c Input, integer M, the number of rows in A. c c Input, integer N, the number of columns in A. c c Input, double precision A(M,N), the matrix whose Frobenius c norm is desired. c c Output, double precision R8MAT_NORM_FRO, the Frobenius norm of A. c implicit none integer m integer n double precision a(m,n) integer i integer j double precision r8mat_norm_fro double precision value value = 0.0D+00 do j = 1, n do i = 1, m value = value + a(i,j) * a(i,j) end do end do value = sqrt ( value ) r8mat_norm_fro = value return end subroutine r8mat_print ( m, n, a, title ) c*********************************************************************72 c cc R8MAT_PRINT prints an R8MAT. c c Discussion: c c An R8MAT is an array of R8's. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 20 May 2004 c c Author: c c John Burkardt c c Parameters: c c Input, integer M, the number of rows in A. c c Input, integer N, the number of columns in A. c c Input, double precision A(M,N), the matrix. c c Input, character ( len = * ) TITLE, a title. c implicit none integer m integer n double precision a(m,n) character ( len = * ) title call r8mat_print_some ( m, n, a, 1, 1, m, n, title ) return end subroutine r8mat_print_some ( m, n, a, ilo, jlo, ihi, jhi, & title ) c*********************************************************************72 c cc R8MAT_PRINT_SOME prints some of an R8MAT. c c Discussion: c c An R8MAT is an array of R8's. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 25 January 2007 c c Author: c c John Burkardt c c Parameters: c c Input, integer M, N, the number of rows and columns. c c Input, double precision A(M,N), an M by N matrix to be printed. c c Input, integer ILO, JLO, the first row and column to print. c c Input, integer IHI, JHI, the last row and column to print. c c Input, character ( len = * ) TITLE, a title. c implicit none integer incx parameter ( incx = 5 ) integer m integer n double precision a(m,n) character * ( 14 ) ctemp(incx) integer i integer i2hi integer i2lo integer ihi integer ilo integer inc integer j integer j2 integer j2hi integer j2lo integer jhi integer jlo character * ( * ) title write ( *, '(a)' ) ' ' write ( *, '(a)' ) trim ( title ) if ( m .le. 0 .or. n .le. 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' (None)' return end if do j2lo = max ( jlo, 1 ), min ( jhi, n ), incx j2hi = j2lo + incx - 1 j2hi = min ( j2hi, n ) j2hi = min ( j2hi, jhi ) inc = j2hi + 1 - j2lo write ( *, '(a)' ) ' ' do j = j2lo, j2hi j2 = j + 1 - j2lo write ( ctemp(j2), '(i7,7x)') j end do write ( *, '('' Col '',5a14)' ) ( ctemp(j), j = 1, inc ) write ( *, '(a)' ) ' Row' write ( *, '(a)' ) ' ' i2lo = max ( ilo, 1 ) i2hi = min ( ihi, m ) do i = i2lo, i2hi do j2 = 1, inc j = j2lo - 1 + j2 write ( ctemp(j2), '(g14.6)' ) a(i,j) end do write ( *, '(i5,a,5a14)' ) i, ':', ( ctemp(j), j = 1, inc ) end do end do return end function r8vec_dot_product ( n, v1, v2 ) c*********************************************************************72 c cc R8VEC_DOT_PRODUCT finds the dot product of a pair of R8VEC's. c c Discussion: c c An R8VEC is a vector of R8 values. c c In FORTRAN90, the system routine DOT_PRODUCT should be called c directly. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 27 May 2008 c c Author: c c John Burkardt c c Parameters: c c Input, integer N, the dimension of the vectors. c c Input, double precision V1(N), V2(N), the vectors. c c Output, double precision R8VEC_DOT_PRODUCT, the dot product. c implicit none integer n integer i double precision r8vec_dot_product double precision v1(n) double precision v2(n) double precision value value = 0.0D+00 do i = 1, n value = value + v1(i) * v2(i) end do r8vec_dot_product = value return end subroutine r8vec_linspace ( n, a_first, a_last, a ) c*********************************************************************72 c cc R8VEC_LINSPACE creates a vector of linearly spaced values. c c Discussion: c c An R8VEC is a vector of R8's. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 14 March 2011 c c Author: c c John Burkardt c c Parameters: c c Input, integer N, the number of entries in the vector. c c Input, double precision A_FIRST, A_LAST, the first and last entries. c c Output, double precision A(N), a vector of linearly spaced data. c implicit none integer n double precision a(n) double precision a_first double precision a_last integer i if ( n .eq. 1 ) then a(1) = ( a_first + a_last ) / 2.0D+00 else do i = 1, n a(i) = ( dble ( n - i ) * a_first & + dble ( i - 1 ) * a_last ) & / dble ( n - 1 ) end do end if return end subroutine timestamp ( ) c*********************************************************************72 c cc TIMESTAMP prints out the current YMDHMS date as a timestamp. c c Discussion: c c This FORTRAN77 version is made available for cases where the c FORTRAN90 version cannot be used. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 12 January 2007 c c Author: c c John Burkardt c c Parameters: c c None c implicit none character * ( 8 ) ampm integer d character * ( 8 ) date integer h integer m integer mm character * ( 9 ) month(12) integer n integer s character * ( 10 ) time integer y save month data month / & 'January ', 'February ', 'March ', 'April ', & 'May ', 'June ', 'July ', 'August ', & 'September', 'October ', 'November ', 'December ' / call date_and_time ( date, time ) read ( date, '(i4,i2,i2)' ) y, m, d read ( time, '(i2,i2,i2,1x,i3)' ) h, n, s, mm if ( h .lt. 12 ) then ampm = 'AM' else if ( h .eq. 12 ) then if ( n .eq. 0 .and. s .eq. 0 ) then ampm = 'Noon' else ampm = 'PM' end if else h = h - 12 if ( h .lt. 12 ) then ampm = 'PM' else if ( h .eq. 12 ) then if ( n .eq. 0 .and. s .eq. 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, month(m), y, h, ':', n, ':', s, '.', mm, ampm return end