I am trying to compute the inverse of a complex matrix with ZGETRI, but
even if it executes without error (info = 0),
it does not give me the correct inverse matrix and I have absolutely
no idea where the error comes from.
PROGRAM solvelinear
implicit none
INTEGER :: i,j,info,lwork
INTEGER,dimension(3) :: ipiv
COMPLEX(16), dimension(3,3) :: C,Cinv,M,LU
COMPLEX(16),allocatable :: work(:)
info=0
lwork=100
allocate(work(lwork))
ipiv=0
work=(0.d0,0.d0)
C(1,1)=(0.d0,-1.d0)
C(1,2)=(1.d0,5.d0)
C(1,3)=(2.d0,-2.d0)
C(2,1)=(4.d0,-1.d0)
C(2,2)=(2.d0,-3.d0)
C(2,3)=(-1.d0,2.d0)
C(3,1)=(1.d0,0.d0)
C(3,2)=(3.d0,-2.d0)
C(3,3)=(0.d0,1.d0)
write(*,*)"C = "
do i=1,3
write(*,10)(C(i,j),j=1,3)
end do
!-- LU factorisation
LU=C
CALL ZGETRF(3,3,LU,3,ipiv,info)
write(*,*)'info = ',info
write(*,*)"LU = "
do i=1,3
write(*,10)(LU(i,j),j=1,3)
end do
!-- Inversion of matrix C using the LU
Cinv=LU
CALL ZGETRI(3,Cinv,3,ipiv,work,lwork,info)
write(*,*)'info = ',info
write(*,*)"Cinv = "
do i=1,3
write(*,10)(Cinv(i,j),j=1,3)
end do
!-- computation of C^-1 * C to check the inverse
M = matmul(Cinv,C)
write(*,*)"M = "
do i=1,3
write(*,10)(M(i,j),j=1,3)
end do
10 FORMAT(3('(',F20.10,',',F20.10,') '))
END PROGRAM solvelinear
I compile with ifort (and my LAPACK librairies version 3.7.1 are also compiled with ifort). Makefile:
#$Id: Makefile $
.SUFFIXES: .f90 .f .c .o
FC = ifort
FFLAGS = -g -check all -zmuldefs -i8
LIBS = -L/path/to/lapack-3.7.1 -llapack -ltmglib -lrefblas
MAIN = prog.o
EXEC = xx
all: ${MAIN} Makefile
${FC} ${FFLAGS} -o ${EXEC} ${MAIN} ${LIBS}
.f.o: ${MODS} Makefile
${FC} ${FFLAGS} -c $<
.f90.o: ${MODS} Makefile
${FC} ${FFLAGS} -c $<
I have no errors when compiling. Here is my output:
C =
( 0.00000, -1.00000) ( 1.00000, 5.00000) ( 2.00000, -2.00000)
( 4.00000, -1.00000) ( 2.00000, -3.00000) ( -1.00000, 2.00000)
( 1.00000, 0.00000) ( 3.00000, -2.00000) ( 0.00000, 1.00000)
info = 0
LU =
( 4.00000, 0.00000) ( 2.00000, 120470.58824) ( 2.00000, -2.00000)
( 0.00000, 0.00000) (28003147.29412, -3.00000) ( -1.00000, 2.00000)
( 1.00000, 0.00000) ( 3.00000, -2.00000) ( 0.00000, 1.00000)
info = 0
Cinv =
( 0.00000, 0.00000) ( -0.00000, -0.00000) ( 2.00000, -2.00000)
( -0.00000, 0.00000) ( -0.00000, -3.00000) ( -1.00000, 2.00000)
( -0.00000, -0.00000) ( 3.00000, -2.00000) ( 0.00000, 1.00000)
M =
( 2.00000, -2.00000) ( 2.00000, -10.00000) ( 2.00000, 2.00000)
( -4.00000, -10.00000) ( -8.00000, 2.00000) ( 4.00000, 2.00000)
( 10.00000, -10.00000) ( 2.00000, -10.00000) ( -0.00000, 8.00000)
And M should be the identity if I'm not wrong.
I suggest you to NOT use the kind notation with literal numbers like REAL(4) or COMPLEX(16).
First, it is ugly and not portable.
Second, it can be confusing for complex variables.
Here you define your variables as COMPLEX(16), but ZGETRI, and all other LAPACK Z routines, expects COMPLEX*16. These are NOT the same.
COMPLEX*16 is a non-standard notation for complex numbers with REAL*8 components. REAL*8 is a nonstandard notation for 8 byte real numbers that are normally equivalent to DOUBLE PRECISION.
COMPLEX(16) is a complex number with two REAL(16) components, provided such a kind exists. In compilers which provide REAL(16) this real is a quadruple precision, not double precision.
So you are effectively passing 32-byte complex variables instead of 16-byte complex variables.
There are enough resources where to learn how to use Fortran kinds properly. You can start with
integer, parameter :: dp = kind(1.d0)
and
real(dp) :: x
complex(dp) :: c
Related
This is my code:
Program String_Triming
Implicit none
Open(15, File = 'Output.txt')
Write(15,'(A,1x,"j",1x,A)') Ispis(20.45),Ispis(20.45)
Write(15,'(A,1x,"j",1x,A)') Ispis(-20.45),Ispis(-20.45)
Close(15)
Contains
Function Ispis ( Deg ) result ( Str )
Real,intent(in)::Deg
Character(len=16):: Str
If ( Deg > 0 ) then
Write(Str,'(F0.3)') 1000.0 + Deg
Str = Str(2:)
Else
Write(Str,'(F8.3)') 1000.0 + abs(Deg)
Write(Str,'("-",A)') Str(3:)
End If
End Function Ispis
End program String_Triming
The content of Output.txt file is:
020.450 j 020.450
-20.450 j -20.450
The result I want to get from this code is:
020.450 j 020.450
-20.450 j -20.450
How do I get that result? Is there way to trim the length of Str to Len=8 which is the length of 020.450?
It's not quite clear what you want. If all you want is to remove the spaces from the output file, why not just run it through sed instead of writing a Fortran Program:
$ cat Output.txt
020.450 j 020.450
-20.450 j -20.450
$ sed -r 's/ +/ /g' Output.txt
020.450 j 020.450
-20.450 j -20.450
If you want to produce output like this in the first place, you could 'overwrite' the first three characters of str with an integer format. Something like this:
function Ispis(Deg) result(Str)
real, intent(in) :: Deg
character(len=7) :: Str
write(Str, '(F7.3)') Deg
if ( Deg < 0 ) then
write(Str(:3), '(I3.2)') int(Deg)
else
write(Str(:3), '(I3.3)') int(Deg)
end if
end function Ispis
note: the length of 020.450 is 7, not 8.
This is the solution for getting wanted result:
Program Main
Implicit none
Open(15,File='Output.txt')
Write(15,'(1x,a,1x,"j",1x,a,1x,"Juhu!")') Writing_01(67.45),Writing_01(-4.04)
Write(15,'(1x,a,1x,"j",1x,a,1x,"Juhu!")') Writing_02(67.45),Writing_02(-4.04)
Close(15)
Contains
Function Writing_01 ( Deg ) Result ( Str )
Real,intent(in) :: Deg
Character(:),allocatable :: Str
Character(len = 15 ) :: Str_temp
If ( int( Deg ) > 0 ) then
Write(Str_temp , '(F0.2)' ) 100000.0 + Deg
Str_temp = Str_temp(2:)
Else
Write(Str_temp, '(F0.2)' ) 100000.0 + abs(Deg)
Str_temp = "-"//Str_temp(3:)
Endif
Str = trim ( adjustl ( Str_temp ))
End Function Writing_01
Function Writing_02 ( Deg ) Result ( Str_temp )
Real,intent(in) :: Deg
Character(:),allocatable :: Str_temp
Character(len=1561) :: Form_02 , Res
If (int( Deg ) > 0 ) then
Form_02 = '(i5.5,f0.2)' ! allow a total of 4 leading zeros.
Else
Form_02 = '(i5.4,f0.2)' ! "-" sign takes up one space, so 3 leading zeros remain.
Endif
Write(Res , Form_02 ) int( Deg ), abs( Deg - int( Deg ) )
Str_temp = trim ( adjustl ( Res ))
End Function Writing_02
End program Main
I am doing a multiple integral, there is a parameter M_D which I can modify. Both M_D=2.9d3 or M_D=3.1d3 works fine, but when I change it into M_D=3.0d0 it got an error
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F831A103E08
#1 0x7F831A102F90
#2 0x7F83198344AF
#3 0x43587C in __mc_vegas_MOD_vegas
#4 0x400EBE in MAIN__ at MAINqq.f90:?
Segmentation fault (core dumped)
It's very unlikely there is a sigularity which out of range while progressing. From the answer to this kind of problem I found, I guess it's not about array dimension that is out of bounds.
This time I didn't make it to simplify the problem which can demonstrate my question in order to write less amount of code . It's unpractical to post all the code here, so I post the segment which I think is relevant to the error.
module my_fxn
implicit none
private
public :: fxn_1
public :: cos_theta
real(kind(0d0)), parameter :: S=1.690d8
real(kind(0d0)), parameter :: g_s = 0.118d0
real(kind(0d0)), parameter :: M_D = 3.0d3 !!!
real(kind(0d0)), parameter :: m=172d0
real(kind(0d0)), parameter :: Q=2d0
real(kind(0d0)), parameter :: pi=3.14159d0
real(kind(0d0)), external :: CT14pdf
real(kind(0d0)) :: cos_theta
real(kind(0d0)) :: s12
integer :: i
contains
function jacobian( upper, lower) result(jfactor)
implicit none
real(kind(0d0)), dimension(1:6) :: upper, lower
real(kind(0d0)) :: jfactor
jfactor = 1d0
do i = 1, 6
jfactor = jfactor * (upper(i) - lower(i))
end do
end function jacobian
function dot_vec(p,q) result(fourvectordot)
implicit none
real(kind(0d0)) :: fourvectordot
real(kind(0d0)), dimension(0:3) :: p,q
fourvectordot = p(0) * q(0)
do i = 1, 3
fourvectordot = fourvectordot - p(i) * q(i)
end do
end function dot_vec
subroutine commonpart(p3_0, p4_0, eta, k_v,P3_v, p4_v, s13, s14, s23, s24)
implicit none
real(kind(0d0)), intent(in) :: p3_0, p4_0, eta, k_v, p3_v, p4_v
real(kind(0d0)), intent(out):: s13, s14, s23, s24
real(kind(0d0)) :: sin_theta, &
cos_eta, sin_eta, &
cos_ksi, sin_ksi
real(kind(0d0)), dimension(0:3) :: k1, k2, p3, p4, k
sin_theta = sqrt(1-cos_theta**2)
cos_eta = cos(eta)
sin_eta = sqrt(1-cos_eta**2)
cos_ksi = (k_v**2-p3_v**2-p4_v**2)/(2*p3_v*p4_v)
sin_ksi = sqrt(1-cos_ksi**2)
k1 = [sqrt(s12)/2d0,0d0,0d0, sqrt(s12)/2d0]
k2 = [sqrt(s12)/2d0,0d0,0d0, -sqrt(s12)/2d0]
p3 = [p3_0, p3_v*(cos_theta*cos_eta*sin_ksi+sin_theta*cos_ksi), &
p3_v* sin_eta*sin_ksi, p3_v*( cos_theta*cos_ksi-sin_theta*cos_eta*sin_ksi)]
p4 = [p4_0, p4_v*sin_theta, 0d0, p4_v*cos_theta]
do i = 1, 3
k(i) = 0 - p3(i) - p4(i)
end do
k(0) = sqrt(s12) - p3_0-p4_0
s13 = m**2- 2*dot_vec(k1,p3)
s14 = m**2- 2*dot_vec(k1,p4)
s23 = m**2- 2*dot_vec(k2,p3)
s24 = m**2- 2*dot_vec(k2,p3)
end subroutine commonpart
function fxn_1(z, wgt) result(fxn_qq)
implicit none
real(kind(0d0)), dimension(1:6) :: z
real(kind(0d0)) :: wgt
real(kind(0d0)) :: tau_0
real(kind(0d0)) :: sigma, tau, m_plus, m_minus, & ! intermediate var
p3_v, p4_v, k_v, phi
real(kind(0d0)) :: s13,s14,s23, s24, gm
real(kind(0d0)) :: part1_qq,part_qq,fxn_qq
real(kind(0d0)) :: p3_0_max, p4_0_max, eta_max, gm_max, x1_max, x2_max, &
p3_0_min, p4_0_min, eta_min, gm_min, x1_min, x2_min
real(kind(0d0)), dimension(1:6) :: upper, lower
real(kind(0d0)) :: jfactor
wgt = 0
gm_max = M_D
gm_min = 0.1d0
z(1)= (gm_max-gm_min)*z(1) + gm_min
tau_0 = (2*m)**2/S
eta_max = 2*pi
eta_min = 0
z(2) = (eta_max-eta_min)*z(2)+eta_min
x1_max = 1
x1_min = tau_0
z(3) = (x1_max-x1_min)*z(3) + x1_min
x2_max = 1
x2_min = tau_0/z(3)
z(4) = (x2_max-x2_min)*z(4)+x2_min
s12 = z(3)*z(4) * S
if (sqrt(s12) < (2*m+z(1)))then
fxn_qq = 0d0
return
else
end if
p4_0_max = sqrt(s12)/2 - ((m+z(1))**2-m**2)/(2*sqrt(s12))
p4_0_min = m
z(5) = (p4_0_max-p4_0_min)*z(5)+p4_0_min
p4_v = sqrt(z(5)**2-m**2)
sigma = sqrt(s12)-z(5)
tau = sigma**2 - p4_v**2
m_plus = m + z(1)
m_minus = m - z(1)
p3_0_max = 1/(2*tau)*(sigma*(tau+m_plus*m_minus)+p4_v*sqrt((tau-m_plus**2)*(tau-m_minus**2)))
p3_0_min = 1/(2*tau)*(sigma*(tau+m_plus*m_minus)-p4_v-sqrt((tau-m_plus**2)*(tau-m_minus**2)))
z(6) = (p3_0_max-p3_0_min)*z(6)+p3_0_min
p3_v = sqrt(z(6)**2-m**2)
k_v = sqrt((sqrt(s12)-z(5)-z(6))**2-z(1)**2)
gm = z(1)
upper = [gm_max, eta_max, x1_max, x2_max, p4_0_max, p3_0_max]
lower = [gm_min, eta_min, x1_min, x2_min, p4_0_min, p3_0_min]
jfactor = jacobian(upper, lower)
call commonpart(z(6),z(5),z(2), k_v,p3_v, p4_v, s13, s14, s23, s24)
include "juicy.m"
part1_qq = 0d0
do i = 1, 5
part1_qq = part1_qq+CT14Pdf(i, z(3), Q)*CT14Pdf(-i, z(4), Q)*part_qq
end do
phi = 1/(8*(2*pi)**4) * 1/(2*s12)
fxn_qq = jfactor * g_s**4/M_D**5*pi*z(1)**2*phi*part1_qq
end function fxn_1
end module my_fxn
MC_VEGAS
MODULE MC_VEGAS
!*****************************************************************
! This module is a modification f95 version of VEGA_ALPHA.for
! by G.P. LEPAGE SEPT 1976/(REV)AUG 1979.
!*****************************************************************
IMPLICIT NONE
SAVE
INTEGER,PARAMETER :: MAX_SIZE=20 ! The max dimensions of the integrals
INTEGER,PRIVATE :: i_vegas
REAL(KIND(1d0)),DIMENSION(MAX_SIZE),PUBLIC:: XL=(/(0d0,i_vegas=1,MAX_SIZE)/),&
XU=(/(1d0,i_vegas=1,MAX_SIZE)/)
INTEGER,PUBLIC :: NCALL=50000,& ! The number of integrand evaluations per iteration
!+++++++++++++++++++++++++++++++++++++++++++++++++++++
! You can change NCALL to change the precision
!+++++++++++++++++++++++++++++++++++++++++++++++++++++
ITMX=5,& ! The maximum number of iterations
NPRN=5,& ! printed or not
NDEV=6,& ! device number for output
IT=0,& ! number of iterations completed
NDO=1,& ! number of subdivisions on an axis
NDMX=50,& ! determines the maximum number of increments along each axis
MDS=1 ! =0 use importance sampling only
! =\0 use importance sampling and stratified sampling
! increments are concentrated either wehre the
! integrand is largest in magnitude (MDS=1), or
! where the contribution to the error is largest(MDS=-1)
INTEGER,PUBLIC :: IINIP
REAL(KIND(1d0)),PUBLIC :: ACC=-1d0 ! Algorithm stops when the relative accuracy,
! |SD/AVGI|, is less than ACC; accuracy is not
! cheched when ACC<0
REAL(KIND(1d0)),PUBLIC :: MC_SI=0d0,& ! sum(AVGI_i/SD_i^2,i=1,IT)
SWGT=0d0,& ! sum(1/SD_i^2,i=1,IT)
SCHI=0d0,& ! sum(AVGI_i^2/SD_i^2,i=1,IT)
ALPH=1.5d0 ! controls the rate which the grid is modified from
! iteration to iteration; decreasing ALPH slows
! modification of the grid
! (ALPH=0 implies no modification)
REAL(KIND(1d0)),PUBLIC :: DSEED=1234567d0 ! seed of
! location of the I-th division on the J-th axi, normalized to lie between 0 and 1.
REAL(KIND(1d0)),DIMENSION(50,MAX_SIZE),PUBLIC::XI=1d0
REAL(KIND(1d0)),PUBLIC :: CALLS,TI,TSI
CONTAINS
SUBROUTINE RANDA(NR,R)
IMPLICIT NONE
INTEGER,INTENT(IN) :: NR
REAL(KIND(1d0)),DIMENSION(NR),INTENT(OUT) :: R
INTEGER :: I
! D2P31M=(2**31) - 1 D2P31 =(2**31)(OR AN ADJUSTED VALUE)
REAL(KIND(1d0))::D2P31M=2147483647.d0,D2P31=2147483711.d0
!FIRST EXECUTABLE STATEMENT
DO I=1,NR
DSEED = DMOD(16807.d0*DSEED,D2P31M)
R(I) = DSEED / D2P31
ENDDO
END SUBROUTINE RANDA
SUBROUTINE VEGAS(NDIM,FXN,AVGI,SD,CHI2A,INIT)
!***************************************************************
! SUBROUTINE PERFORMS NDIM-DIMENSIONAL MONTE CARLO INTEG'N
! - BY G.P. LEPAGE SEPT 1976/(REV)AUG 1979
! - ALGORITHM DESCRIBED IN J COMP PHYS 27,192(1978)
!***************************************************************
! Without INIT or INIT=0, CALL VEGAS
! INIT=1 CALL VEGAS1
! INIT=2 CALL VEGAS2
! INIT=3 CALL VEGAS3
!***************************************************************
IMPLICIT NONE
INTEGER,INTENT(IN) :: NDIM
REAL(KIND(1d0)),EXTERNAL :: FXN
INTEGER,INTENT(IN),OPTIONAL :: INIT
REAL(KIND(1d0)),INTENT(INOUT) :: AVGI,SD,CHI2A
REAL(KIND(1d0)),DIMENSION(50,MAX_SIZE):: D,DI
REAL(KIND(1d0)),DIMENSION(50) :: XIN,R
REAL(KIND(1d0)),DIMENSION(MAX_SIZE) :: DX,X,DT,RAND
INTEGER,DIMENSION(MAX_SIZE) :: IA,KG
INTEGER :: initflag
REAL(KIND(1d0)),PARAMETER :: ONE=1.d0
INTEGER :: I, J, K, NPG, NG, ND, NDM, LABEL = 0
REAL(KIND(1d0)) :: DXG, DV2G, XND, XJAC, RC, XN, DR, XO, TI2, WGT, FB, F2B, F, F2
!***************************
!SAVE AVGI,SD,CHI2A
!SQRT(A)=DSQRT(A)
!ALOG(A)=DLOG(A)
!ABS(A)=DABS(A)
!***************************
IF(PRESENT(INIT))THEN
initflag=INIT
ELSE
initflag=0
ENDIF
! INIT=0 - INITIALIZES CUMULATIVE VARIABLES AND GRID
ini0:IF(initflag.LT.1) THEN
NDO=1
DO J=1,NDIM
XI(1,J)=ONE
ENDDO
ENDIF ini0
! INIT=1 - INITIALIZES CUMULATIVE VARIABLES, BUT NOT GRID
ini1:IF(initflag.LT.2) THEN
IT=0
MC_SI=0.d0
SWGT=MC_SI
SCHI=MC_SI
ENDIF ini1
! INIT=2 - NO INITIALIZATION
ini2:IF(initflag.LE.2)THEN
ND=NDMX
NG=1
IF(MDS.NE.0) THEN
NG=(NCALL/2.d0)**(1.d0/NDIM)
MDS=1
IF((2*NG-NDMX).GE.0) THEN
MDS=-1
NPG=NG/NDMX+1
ND=NG/NPG
NG=NPG*ND
ENDIF
ENDIF
K=NG**NDIM ! K sub volumes
NPG=NCALL/K ! The number of random numbers in per sub volumes Ms
IF(NPG.LT.2) NPG=2
CALLS=DBLE(NPG*K) ! The total number of random numbers M
DXG=ONE/NG
DV2G=(CALLS*DXG**NDIM)**2/NPG/NPG/(NPG-ONE) ! 1/(Ms-1)
XND=ND ! ~NDMX!
! determines the number of increments along each axis
NDM=ND-1 ! ~NDMX-1
DXG=DXG*XND ! determines the number of increments along each axis per sub-v
XJAC=ONE/CALLS
DO J=1,NDIM
DX(J)=XU(J)-XL(J)
XJAC=XJAC*DX(J) ! XJAC=Volume/M
ENDDO
! REBIN, PRESERVING BIN DENSITY
IF(ND.NE.NDO) THEN
RC=NDO/XND ! XND=ND
outer:DO J=1, NDIM ! Set the new division
K=0
XN=0.d0
DR=XN
I=K
LABEL=0
inner5:DO
IF(LABEL.EQ.0) THEN
inner4:DO
K=K+1
DR=DR+ONE
XO=XN
XN=XI(K,J)
IF(RC.LE.DR) EXIT
ENDDO inner4
ENDIF
I=I+1
DR=DR-RC
XIN(I)=XN-(XN-XO)*DR
IF(I.GE.NDM) THEN
EXIT
ELSEIF(RC.LE.DR) THEN
LABEL=1
ELSE
LABEL=0
ENDIF
ENDDO inner5
inner:DO I=1,NDM
XI(I,J)=XIN(I)
ENDDO inner
XI(ND,J)=ONE
ENDDO outer
NDO=ND
ENDIF
IF(NPRN.GE.0) WRITE(NDEV,200) NDIM,CALLS,IT,ITMX,ACC,NPRN,&
ALPH,MDS,ND,(XL(J),XU(J),J=1,NDIM)
ENDIF ini2
!ENTRY VEGAS3(NDIM,FXN,AVGI,SD,CHI2A) INIT=3 - MAIN INTEGRATION LOOP
mainloop:DO
IT=IT+1
TI=0.d0
TSI=TI
DO J=1,NDIM
KG(J)=1
DO I=1,ND
D(I,J)=TI
DI(I,J)=TI
ENDDO
ENDDO
LABEL=0
level1:DO
level2:DO
ifla:IF(LABEL.EQ.0)THEN
FB=0.d0
F2B=FB
level3:DO K=1,NPG
CALL RANDA(NDIM,RAND)
WGT=XJAC
DO J=1,NDIM
XN=(KG(J)-RAND(J))*DXG+ONE
IA(J)=XN
IF(IA(J).LE.1) THEN
XO=XI(IA(J),J)
RC=(XN-IA(J))*XO
ELSE
XO=XI(IA(J),J)-XI(IA(J)-1,J)
RC=XI(IA(J)-1,J)+(XN-IA(J))*XO
ENDIF
X(J)=XL(J)+RC*DX(J)
WGT=WGT*XO*XND
ENDDO
F=WGT
F=F*FXN(X,WGT)
F2=F*F
FB=FB+F
F2B=F2B+F2
DO J=1,NDIM
DI(IA(J),J)=DI(IA(J),J)+F
IF(MDS.GE.0) D(IA(J),J)=D(IA(J),J)+F2
ENDDO
ENDDO level3
! K=K-1 !K=NPG
F2B=DSQRT(F2B*DBLE(NPG))
F2B=(F2B-FB)*(F2B+FB)
TI=TI+FB
TSI=TSI+F2B
IF(MDS.LT.0) THEN
DO J=1,NDIM
D(IA(J),J)=D(IA(J),J)+F2B
ENDDO
ENDIF
K=NDIM
ENDIF ifla
KG(K)=MOD(KG(K),NG)+1
IF(KG(K).EQ.1) THEN
EXIT
ELSE
LABEL=0
ENDIF
ENDDO level2
K=K-1
IF(K.GT.0) THEN
LABEL=1
ELSE
EXIT
ENDIF
ENDDO level1
! COMPUTE FINAL RESULTS FOR THIS ITERATION
TSI=TSI*DV2G
TI2=TI*TI
WGT=ONE/TSI
MC_SI=MC_SI+TI*WGT
SWGT=SWGT+WGT
SCHI=SCHI+TI2*WGT
AVGI=MC_SI/SWGT
CHI2A=(SCHI-MC_SI*AVGI)/(IT-0.9999d0)
SD=DSQRT(ONE/SWGT)
IF(NPRN.GE.0) THEN
TSI=DSQRT(TSI)
WRITE(NDEV,201) IT,TI,TSI,AVGI,SD,CHI2A
ENDIF
IF(NPRN.GT.0) THEN
DO J=1,NDIM
WRITE(NDEV,202) J,(XI(I,J),DI(I,J),I=1+NPRN/2,ND,NPRN)
ENDDO
ENDIF
!*************************************************************************************
! REFINE GRID
! XI(k,j)=XI(k,j)-(XI(k,j)-XI(k-1,j))*(sum(R(i),i=1,k)-s*sum(R(i),i=1,ND)/M)/R(k)
! divides the original k-th interval into s parts
!*************************************************************************************
outer2:DO J=1,NDIM
XO=D(1,J)
XN=D(2,J)
D(1,J)=(XO+XN)/2.d0
DT(J)=D(1,J)
inner2:DO I=2,NDM
D(I,J)=XO+XN
XO=XN
XN=D(I+1,J)
D(I,J)=(D(I,J)+XN)/3.d0
DT(J)=DT(J)+D(I,J)
ENDDO inner2
D(ND,J)=(XN+XO)/2.d0
DT(J)=DT(J)+D(ND,J)
ENDDO outer2
le1:DO J=1,NDIM
RC=0.d0
DO I=1,ND
R(I)=0.d0
IF(D(I,J).GT.0.) THEN
XO=DT(J)/D(I,J)
R(I)=((XO-ONE)/XO/DLOG(XO))**ALPH
ENDIF
RC=RC+R(I)
ENDDO
RC=RC/XND
K=0
XN=0.d0
DR=XN
I=K
LABEL=0
le2:DO
le3:DO
IF(LABEL.EQ.0)THEN
K=K+1
DR=DR+R(K)
XO=XN
XN=XI(K,J)
ENDIF
IF(RC.LE.DR) THEN
EXIT
ELSE
LABEL=0
ENDIF
ENDDO le3
I=I+1
DR=DR-RC
XIN(I)=XN-(XN-XO)*DR/R(K)
IF(I.GE.NDM) THEN
EXIT
ELSE
LABEL=1
ENDIF
ENDDO le2
DO I=1,NDM
XI(I,J)=XIN(I)
ENDDO
XI(ND,J)=ONE
ENDDO le1
IF(IT.GE.ITMX.OR.ACC*ABS(AVGI).GE.SD) EXIT
ENDDO mainloop
200 FORMAT(/," INPUT PARAMETERS FOR MC_VEGAS: ",/," NDIM=",I3," NCALL=",F8.0,&
" IT=",I3,/," ITMX=",I3," ACC= ",G9.3,&
" NPRN=",I3,/," ALPH=",F5.2," MDS=",I3," ND=",I4,/,&
"(XL,XU)=",(T10,"(" G12.6,",",G12.6 ")"))
201 FORMAT(/," INTEGRATION BY MC_VEGAS ", " ITERATION NO. ",I3, /,&
" INTEGRAL = ",G14.8, /," SQURE DEV = ",G10.4,/,&
" ACCUMULATED RESULTS: INTEGRAL = ",G14.8,/,&
" DEV = ",G10.4, /," CHI**2 PER IT'N = ",G10.4)
! X is the division of the coordinate
! DELTA I is the sum of F in this interval
202 FORMAT(/,"DATA FOR AXIS ",I2,/," X DELTA I ", &
24H X DELTA I ,18H X DELTA I, &
/(1H ,F7.6,1X,G11.4,5X,F7.6,1X,G11.4,5X,F7.6,1X,G11.4))
END SUBROUTINE VEGAS
END MODULE MC_VEGAS
Main.f90
program main
use my_fxn
use MC_VEGAS
implicit none
integer, parameter :: NDIM = 6
real(kind(0d0)) :: avgi, sd, chi2a
Character(len=40) :: Tablefile
data Tablefile/'CT14LL.pds'/
Call SetCT14(Tablefile)
call vegas(NDIM,fxn_1,avgi,sd,chi2a)
print *, avgi
end program main
After running build.sh
#!/bin/sh
rm -rf *.mod
rm -rf *.o
rm -rf ./calc
rm DATAqq.txt
gfortran -c CT14Pdf.for
gfortran -c FXNqq.f90
gfortran -c MC_VEGAS.f90
gfortran -c MAINqq.f90
gfortran -g -fbacktrace -fcheck=all -Wall -o calc MAINqq.o CT14Pdf.o FXNqq.o MC_VEGAS.o
./calc
rm -rf *.mod
rm -rf *.o
rm -rf ./calc
The whole output has not changed
rm: cannot remove 'DATAqq.txt': No such file or directory
INPUT PARAMETERS FOR MC_VEGAS:
NDIM= 6 NCALL= 46875. IT= 0
ITMX= 5 ACC= -1.00 NPRN= 5
ALPH= 1.50 MDS= 1 ND= 50
(XL,XU)= ( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
( 0.00000 , 1.00000 )
INTEGRATION BY MC_VEGAS ITERATION NO. 1
INTEGRAL = NaN
SQURE DEV = NaN
ACCUMULATED RESULTS: INTEGRAL = NaN
DEV = NaN
CHI**2 PER IT'N = NaN
DATA FOR AXIS 1
X DELTA I X DELTA I X DELTA I
.060000 0.2431E-14 .160000 0.5475E-15 .260000 0.8216E-14
.360000 0.3641E-14 .460000 0.6229E-12 .560000 0.6692E-13
.660000 0.9681E-15 .760000 0.9121E-15 .860000 0.2753E-13
.960000 -0.9269E-16
DATA FOR AXIS 2
X DELTA I X DELTA I X DELTA I
.060000 0.1658E-13 .160000 0.5011E-14 .260000 0.8006E-12
.360000 0.1135E-14 .460000 0.9218E-13 .560000 0.7337E-15
.660000 0.6192E-12 .760000 0.3676E-14 .860000 0.2315E-14
.960000 0.5426E-13
DATA FOR AXIS 3
X DELTA I X DELTA I X DELTA I
.060000 0.3197E-14 .160000 0.1096E-12 .260000 0.5996E-14
.360000 0.5695E-13 .460000 0.3240E-14 .560000 0.5504E-13
.660000 0.9276E-15 .760000 0.6193E-12 .860000 0.1151E-13
.960000 0.7968E-17
DATA FOR AXIS 4
X DELTA I X DELTA I X DELTA I
.060000 0.3605E-13 .160000 0.1656E-14 .260000 0.7266E-12
.360000 0.2149E-13 .460000 0.8086E-13 .560000 0.9119E-14
.660000 0.3692E-15 .760000 0.6499E-15 .860000 0.1906E-17
.960000 0.1542E-19
DATA FOR AXIS 5
X DELTA I X DELTA I X DELTA I
.060000 -0.4229E-15 .160000 -0.4056E-14 .260000 -0.1121E-14
.360000 0.6757E-15 .460000 0.7460E-14 .560000 0.9331E-15
.660000 0.8301E-14 .760000 0.6595E-14 .860000 -0.5203E-11
.960000 0.6361E-12
DATA FOR AXIS 6
X DELTA I X DELTA I X DELTA I
.060000 0.2111E-12 .160000 0.5410E-13 .260000 0.1418E-12
.360000 0.1103E-13 .460000 0.8338E-14 .560000 -0.5840E-14
.660000 0.1263E-14 .760000 -0.1501E-15 .860000 0.4647E-14
.960000 0.3134E-15
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F9D828B0E08
#1 0x7F9D828AFF90
#2 0x7F9D81FE24AF
#3 0x43586C in __mc_vegas_MOD_vegas
#4 0x400EAE in MAIN__ at MAINqq.f90:?
Segmentation fault (core dumped)
I have the following external file with 8 rows ad 11 columns. This file cannot be changed in anyway.
Name Sun Jupiter Saturn Uranus Neptune EarthBC Mercury Venus Mars Pluto
mass(Msun) 1.000 9.547922048e-4 2.858857575e-4 4.366245355e-5 5.151391279e-5 3.040433607e-6 1.660477111e-7 2.448326284e-6 3.227778035e-7 6.607313077e-9
a(AU) 5.20219308 9.54531447 19.19247127 30.13430686 1.00000159 0.38709889 0.72332614 1.52364259 39.80634014
e 0.04891224 0.05409072 0.04723911 0.00734566 0.01669714 0.20563613 0.00676922 0.09330305 0.25439724
I(deg) 1.30376425 2.48750693 0.77193683 1.77045595 0.00090235 7.00457121 3.39460666 1.84908137 17.12113756
M(deg) 240.35086842 045.76754755 171.41809349 293.26102612 094.81131358 242.19484206 345.30814403 330.93171908 024.68081529
w(deg) 274.15634048 339.60245769 098.79773610 255.50375800 286.84104687 029.14401042 054.54948603 286.56509772 114.39445491
OMEGA(deg) 100.50994468 113.63306105 073.98592654 131.78208581 176.14784451 048.32221297 076.66204037 049.53656349 110.32482041
This file is read by the following program which compiles properly
program readtable
implicit none
integer :: i, j, num_col, num_row
double precision, dimension (8,11) :: a
character(14), dimension (8) :: par
num_col = 4
num_row = 8
open(100,file='SSL.dat',status='old')
do j=1, num_row
read(100,*) par(j), (a(i,j), i=1,num_col)
end do
print *, par
print *, a(2,3) !Jupiter's Mass
end program
When I run this program as Fortran90 I get the following message:
At line 14 of file test.f (unit = 100, file='SSL.dat')
Fortran runtime error: Bad real number in item 2 of list input
I think I need to make a FORMAT() statement to help the program read the file properly but I can't seem to get the format right.
As agentp said list directed is fine here, you just have to account for the first 2 lines being different. I'd do it it something like (slight guess here - I'm not 100% convinced I understand what you want):
ian-admin#agon ~/test $ cat r.f90
Program readtable
Implicit None
Integer, Parameter :: wp = Selected_real_kind( 13, 70 )
Integer :: i, j, num_col, num_row
Real( wp ) :: msun
Real( wp ), Dimension (9,11) :: a
Character(14), Dimension (8) :: par
num_col = 9
num_row = 7
Open( 100, file = 'SSL.dat', status = 'old' )
Read( 100, * )
j = 1
Read( 100, * ) par(j), msun, (a(i,j), i=1,num_col)
Do j = 2, num_row
Read(100,*) par(j), (a(i,j), i=1,num_col)
End Do
Write( *, * ) par
Write( *, * ) a(2,3) !Jupiter's Mass
End Program readtable
ian-admin#agon ~/test $ gfortran -std=f2003 -Wall -Wextra -O -fcheck=all r.f90
ian-admin#agon ~/test $ ./a.out
mass(Msun) a(AU) e I(deg) M(deg) w(deg) OMEGA(deg)
5.4090720000000002E-002
I was writing code to use Fortran Eispack routines (compute eigenvalues and eigenvectors, just to check if the values would be different from the ones I got from Matlab), but every time it calls the qzhes subroutine the program hangs.
I load matrixes from files.
Tried commenting the call, and it works without an issue.
I just learned Fortran, and with the help of the internet I wrote this code (which compiles and run):
program qz
IMPLICIT NONE
INTEGER:: divm, i, divg
INTEGER(kind=4) :: dimen
LOGICAL :: matz
REAL(kind = 8), DIMENSION(:,:), ALLOCATABLE:: ma
REAL(kind = 8), DIMENSION(:), ALLOCATABLE:: tabm
REAL(kind = 8), DIMENSION(:,:), ALLOCATABLE:: ga
REAL(kind = 8), DIMENSION(:), ALLOCATABLE:: tabg
REAL(kind = 8), DIMENSION(:,:), ALLOCATABLE:: zet
divm = 1
divg = 2
dimen = 20
matz = .TRUE.
ALLOCATE(ma(1:dimen,1:dimen))
ALLOCATE(tabm(1:dimen))
ALLOCATE(ga(1:dimen,1:dimen))
ALLOCATE(tabg(1:dimen))
OPEN(divm, FILE='Em.txt')
DO i=1,dimen
READ (divm,*) tabm
ma(1:dimen,i)=tabm
END DO
CLOSE(divm)
OPEN(divg, FILE='Gje.txt')
DO i=1,dimen
READ (divg,*) tabg
ga(1:dimen,i)=tabg
END DO
CLOSE(divg)
call qzhes(dimen, ma, ga, matz, zet)
OPEN(divm, FILE='Em2.txt')
DO i=1,dimen
tabm = ma(1:dimen,i)
WRITE (divm,*) tabm
END DO
CLOSE(divm)
OPEN(divg, FILE='Gje2.txt')
DO i=1,dimen
tabg = ga(1:dimen,i)
WRITE (divg,*) tabg
END DO
CLOSE(divg)
end program qz
...//EISPACK subrotines//...
Matrixes:
Gje.txt:https://drive.google.com/file/d/0BxH3QOkswLy_c2hmTGpGVUI3NzQ/view?usp=sharing
Em.txt:https://drive.google.com/file/d/0BxH3QOkswLy_OEtJUGQwN3ZXX2M/view?usp=sharing
Edit:
subroutine qzhes ( n, a, b, matz, z )
!*****************************************************************************80
!
!! QZHES carries out transformations for a generalized eigenvalue problem.
!
! Discussion:
!
! This subroutine is the first step of the QZ algorithm
! for solving generalized matrix eigenvalue problems.
!
! This subroutine accepts a pair of real general matrices and
! reduces one of them to upper Hessenberg form and the other
! to upper triangular form using orthogonal transformations.
! it is usually followed by QZIT, QZVAL and, possibly, QZVEC.
!
! Licensing:
!
! This code is distributed under the GNU LGPL license.
!
! Modified:
!
! 18 October 2009
!
! Author:
!
! Original FORTRAN77 version by Smith, Boyle, Dongarra, Garbow, Ikebe,
! Klema, Moler.
! FORTRAN90 version by John Burkardt.
!
! Reference:
!
! James Wilkinson, Christian Reinsch,
! Handbook for Automatic Computation,
! Volume II, Linear Algebra, Part 2,
! Springer, 1971,
! ISBN: 0387054146,
! LC: QA251.W67.
!
! Brian Smith, James Boyle, Jack Dongarra, Burton Garbow,
! Yasuhiko Ikebe, Virginia Klema, Cleve Moler,
! Matrix Eigensystem Routines, EISPACK Guide,
! Lecture Notes in Computer Science, Volume 6,
! Springer Verlag, 1976,
! ISBN13: 978-3540075462,
! LC: QA193.M37.
!
! Parameters:
!
! Input, integer ( kind = 4 ) N, the order of the matrices.
!
! Input/output, real ( kind = 8 ) A(N,N). On input, the first real general
! matrix. On output, A has been reduced to upper Hessenberg form. The
! elements below the first subdiagonal have been set to zero.
!
! Input/output, real ( kind = 8 ) B(N,N). On input, a real general matrix.
! On output, B has been reduced to upper triangular form. The elements
! below the main diagonal have been set to zero.
!
! Input, logical MATZ, should be TRUE if the right hand transformations
! are to be accumulated for later use in computing eigenvectors.
!
! Output, real ( kind = 8 ) Z(N,N), contains the product of the right hand
! transformations if MATZ is TRUE.
!
implicit none
integer ( kind = 4 ) n
real ( kind = 8 ) a(n,n)
real ( kind = 8 ) b(n,n)
integer ( kind = 4 ) i
integer ( kind = 4 ) j
integer ( kind = 4 ) k
integer ( kind = 4 ) l
integer ( kind = 4 ) l1
integer ( kind = 4 ) lb
logical matz
integer ( kind = 4 ) nk1
integer ( kind = 4 ) nm1
real ( kind = 8 ) r
real ( kind = 8 ) rho
real ( kind = 8 ) s
real ( kind = 8 ) t
real ( kind = 8 ) u1
real ( kind = 8 ) u2
real ( kind = 8 ) v1
real ( kind = 8 ) v2
real ( kind = 8 ) z(n,n)
!
! Set Z to the identity matrix.
!
if ( matz ) then
z(1:n,1:n) = 0.0D+00
do i = 1, n
z(i,i) = 1.0D+00
end do
end if
!
! Reduce B to upper triangular form.
!
if ( n <= 1 ) then
return
end if
nm1 = n - 1
do l = 1, n - 1
l1 = l + 1
s = sum ( abs ( b(l+1:n,l) ) )
if ( s /= 0.0D+00 ) then
s = s + abs ( b(l,l) )
b(l:n,l) = b(l:n,l) / s
r = sqrt ( sum ( b(l:n,l)**2 ) )
r = sign ( r, b(l,l) )
b(l,l) = b(l,l) + r
rho = r * b(l,l)
do j = l + 1, n
t = dot_product ( b(l:n,l), b(l:n,j) )
b(l:n,j) = b(l:n,j) - t * b(l:n,l) / rho
end do
do j = 1, n
t = dot_product ( b(l:n,l), a(l:n,j) )
a(l:n,j) = a(l:n,j) - t * b(l:n,l) / rho
end do
b(l,l) = - s * r
b(l+1:n,l) = 0.0D+00
end if
end do
!
! Reduce A to upper Hessenberg form, while keeping B triangular.
!
if ( n == 2 ) then
return
end if
do k = 1, n - 2
nk1 = nm1 - k
do lb = 1, nk1
l = n - lb
l1 = l + 1
!
! Zero A(l+1,k).
!
s = abs ( a(l,k) ) + abs ( a(l1,k) )
if ( s /= 0.0D+00 ) then
u1 = a(l,k) / s
u2 = a(l1,k) / s
r = sign ( sqrt ( u1**2 + u2**2 ), u1 )
v1 = - ( u1 + r) / r
v2 = - u2 / r
u2 = v2 / v1
do j = k, n
t = a(l,j) + u2 * a(l1,j)
a(l,j) = a(l,j) + t * v1
a(l1,j) = a(l1,j) + t * v2
end do
a(l1,k) = 0.0D+00
do j = l, n
t = b(l,j) + u2 * b(l1,j)
b(l,j) = b(l,j) + t * v1
b(l1,j) = b(l1,j) + t * v2
end do
!
! Zero B(l+1,l).
!
s = abs ( b(l1,l1) ) + abs ( b(l1,l) )
if ( s /= 0.0 ) then
u1 = b(l1,l1) / s
u2 = b(l1,l) / s
r = sign ( sqrt ( u1**2 + u2**2 ), u1 )
v1 = -( u1 + r ) / r
v2 = -u2 / r
u2 = v2 / v1
do i = 1, l1
t = b(i,l1) + u2 * b(i,l)
b(i,l1) = b(i,l1) + t * v1
b(i,l) = b(i,l) + t * v2
end do
b(l1,l) = 0.0D+00
do i = 1, n
t = a(i,l1) + u2 * a(i,l)
a(i,l1) = a(i,l1) + t * v1
a(i,l) = a(i,l) + t * v2
end do
if ( matz ) then
do i = 1, n
t = z(i,l1) + u2 * z(i,l)
z(i,l1) = z(i,l1) + t * v1
z(i,l) = z(i,l) + t * v2
end do
end if
end if
end if
end do
end do
return
end
I would expand the allocation Process
integer :: status1, status2, status3, status4, status5
! check the allocation, returnvalue 0 means ok
ALLOCATE(ma(1:dimen,1:dimen), stat=status1)
ALLOCATE(tabm(1:dimen), stat=status2)
ALLOCATE(ga(1:dimen,1:dimen), stat=status3)
ALLOCATE(tabg(1:dimen), stat=status4)
ALLOCATE(zet(1:dimen,1:dimen), stat=status5)
And at the end of the Program deallocate all arrays, because, you maybe have no memoryleak now, but if you put this program into a subroutine and use it several time with big matricies during a programrun, the program could leak some serious memory.
....
DO i=1,dimen
tabg = ga(1:dimen,i)
WRITE (divg,*) tabg
END DO
CLOSE(divg)
DEALLOCATE(ma, stat=status1)
DEALLOCATE(tabm, stat=status2)
DEALLOCATE(ga, stat=status3)
DEALLOCATE(tabg, stat=status4)
DEALLOCATE(zet, stat=status5)
You can check again with the status integer, if the deallocation was ok, returnvalue again 0.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
Recently, I started to lean fortran programming. I have seen the following code at youtube without any error it is compiled. But I have got some errors.
I appreciate any help
program
implicit none
real, parameter :: pi=4*atan(1.0)
integer, parameter :: n = 100
real :: dimension(1:n) :: x, y
real :: a=0.0, b = 2*pi
real :: increment
integer :: i
increment = (b-a)/(real(n)-1)
x(1)=0.0
do i =2,n
x(i) = x(i-1) + increment
end do
y = sin(x)
print *, x(1:5)
print *, y(1:5)
end program
real :: dimension(1:n) :: x, y is a syntax error. Replace the first :: with a comma. You may need to give a name on the program statement.
You also have mixed-mode arithmetic in line
increment = (b-a)/(real(n)-1)
It will probably compile, and it may not even affect the program, but you should never, never have mixed-mode arithmetic in any programming language as it can cause strange, hard to find bugs.
It should look like this:
increment = (b-a)/(real(n)-1.0)
Here are the results of a working example which addresses the concerns of #High Performance Mark.
host system = (redacted)
compiler version = GCC version 5.1.0
compiler options = -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -Og -Wall -Wextra -Wconversion -Wpedantic -fmax-errors=5
execution command = ./a.out
Compare mesh points
1.57017982 1.57080817 1.57143652
1.57016802 1.57079625 1.57142460
Compare function values at these mesh points
1622.04211 -84420.7344 -1562.01758
1591.57471 13245402.0 -1591.65527
There is a bad programming practice in the demo you found: moving through the mesh by adding steps (+ increment) instead of counting them (k * increment). The problem is widespread and appears with severe consequences (https://www.ima.umn.edu/~arnold/disasters/patriot.html).
For demonstration on your code, the size of the mesh was boosted to 10K points. Also the sample function changed from cos x to tan x and we examine points near the singularity at pi/2 = 1.57079633. While the novitiate may find the discrepancies in mesh values trivial, the difference in function values is significant.
(Mesh errors can be reduced by using increments which have exact binary representation like 2^(-13) = 1 / 8192.)
The code is shown here. The compilation command is gfortran -Wall -Wextra -Wconversion -Og -pedantic -fmax-errors=5 demo.f95. The run command is ./a.out.
program demo
use iso_fortran_env
implicit none
real, parameter :: pi = acos ( -1.0 )
integer, parameter :: n = 10001
real, dimension ( 1 : n ) :: x, y, z
real :: a = 0.0, b = 2 * pi
real :: increment
integer :: k, quarter, status
character ( len = * ), parameter :: c_options = compiler_options( )
character ( len = * ), parameter :: c_version = compiler_version( )
character ( len = 255 ) :: host = " ", cmd = " "
! queries
call hostnm ( host, status )
call get_command ( cmd )
! write identifiers
write ( *, '( /, "host system = ", g0 )' ) trim ( host )
write ( *, '( "compiler version = ", g0 )' ) c_version
write ( *, '( "compiler options = ", g0 )' ) trim ( c_options )
write ( *, '( "execution command = ", g0, / )' ) trim ( cmd )
increment = ( b - a ) / ( n - 1 )
quarter = n / 4
! mesh accumulates errors
x ( 1 ) = 0.0
do k = 2, n
x ( k ) = x ( k - 1 ) + increment
end do
y = tan ( x )
print *, 'Compare mesh points'
print *, x ( quarter : quarter + 2 )
! better mesh
x ( 1 ) = 0.0
do k = 2, n
x ( k ) = ( k - 1 ) * increment
end do
z = tan ( x )
print *, x ( quarter : quarter + 2 )
print *, 'Compare function values at these mesh points'
print *, y ( quarter : quarter + 2 )
print *, z ( quarter : quarter + 2 )
end program demo