问题
I have a matrix say REAL*8 MATRIX(100,100)
, I want to create a pointer out of just the main diagonal or the upper triangle. How to do that?
The purpose is to easily access those elements in a clean "named" way.
回答1:
For the main diagonal, with care, you can do something like:
PROGRAM diagonal
IMPLICIT NONE
REAL, TARGET :: array(4,4)
REAL, POINTER :: ptr(:)
INTEGER :: i
array = RESHAPE([(i,i=1,SIZE(array))], SHAPE(array))
CALL get_diagonal_pointer(array, SIZE(array, 1), ptr)
PRINT "(*(G0,:,','))", ptr
CONTAINS
SUBROUTINE get_diagonal_pointer(arr, n, ptr)
REAL, INTENT(IN), TARGET :: arr(*)
INTEGER, INTENT(IN) :: n
REAL, INTENT(OUT), POINTER :: ptr(:)
!****
ptr => arr(1:n*n:n+1)
END SUBROUTINE get_diagonal_pointer
END PROGRAM diagonal
But note that array
in the main program is simply contiguous and has the TARGET attribute. If array
was not simply contiguous, then things get ... complicated.
You can accomplish the same using an intermediate rank one pointer and pointer bounds remapping. The same requirements as for the assumed size approach apply.
REAL, POINTER :: tmp(:)
tmp(1:SIZE(array)) => array
ptr => tmp(::SIZE(array,1)+1)
The upper triangle of a matrix is not "regular" (the spacing between elements that you want to point at varies) and hence it can't be pointed at.
来源:https://stackoverflow.com/questions/16203092/how-to-assign-a-pointer-to-a-diagonal-of-a-matrix