Salahuddin Ayubi
Salahuddin Ayubi

Reputation: 11

how to reduce the length of the element of a complex array

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

Answers (1)

Alexander Vogt
Alexander Vogt

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

Related Questions