Reputation: 11
I am working on a 6 by 6 matrix to calculate the eigenvalues and eigenvectors. I define the dimension of eigenvalues and eigenvectors in the start like
INTEGER,PARAMETER :: max=6, LDA=max, LDEVEC=max
COMPLEX :: EVAL(max), EVEC(LDEVEC, max)
If I run my program I get the eigenvalues like
(8.8519789E-02,0.0000000E+00) (-8.8519737E-02,0.0000000E+00)
(-3.4551572E-03,8.2172059E-02) (3.4550922E-03,-8.2172029E-02)
(-3.4550924E-03,-8.2172029E-02) (3.4551430E-03,8.2172014E-02)
i.e. 9 digit after decimal point, but I need the length of each eigenvalue like
(8.85197E-02,0.00000E+00) (-8.85197E-02,0.00000E+00)
(-3.45515E-03,8.21720E-02) (3.45509E-03,-8.21720E-02)
(-3.45509E-03,-8.21720E-02) (3.45514E-03,8.21720E-02)
i.e. 7 digit after decimal point. How can I reduce the length of each eigenvalues by using some command in the initializing statement i.e., some where here
INTEGER,PARAMETER :: max=6, LDA=max, LDEVEC=max
COMPLEX :: EVAL(max), EVEC(LDEVEC, max), EVAL_WP(max)
so that I can get eigenvalues with each element having 7 digits after decimal point?
Upvotes: 1
Views: 123
Reputation: 18098
The number of digits (in terms of accuracy) is defined by the kind
of the variable. It usually is not representable in decimal system using an integer number of digits, as floats are defined to the base 2. See the wikipedia article for details on that topic. Also, if you are using math libraries (e.g. BLAS/LAPACK) to calculate Eigenvalues, you are limited to single and double precision, which corresponds to a certain number of digits.
So, all in all it probably is not possible to do what you want to do using a different declaration.
However, your problem is solved using a format
specifier for the write statement:
program test
write(*,*) sqrt(2.)
write(*,'(E14.7E2)') +sqrt(2.)
write(*,'(E14.7E2)') -sqrt(2.)
end program
results in
1.41421354
0.1414214E+01
-0.1414214E+01
The format specifies to use 14 places in total, with seven places after the dot, and two for the exponent. You need to add one character each for the dot, the sign of the value, the exponent indicator, and the sign of the exponent. That leaves one character for the place in front of the dot.
As Vladimir suggested, you can store the format
specifier in string and re-use it:
program test
character(len=*),parameter :: cmplxFmt = "('(',E14.7E2,',',E14.7E2,')')"
write(*,cmplxFmt) -sqrt(2.)*(1.,1.)
end program
Upvotes: 3