Abracadabra
Abracadabra

Reputation: 199

Convert upper triangular matrix into vector In Fortran

I would like to convert upper triangle part of the matrix to the vector.

For example I have the following matrix (4x4 for simplicity):

 1     2     3     4  
 5     6     7     8 
 9     10    11    12
 13    14    15    16 
  1. How can I get upper triangle part of the matrix, written 'by rows':

    1 2 3 4 6 7 8 11 12 16

  2. And how can I get upper triangle part of the matrix, written 'by columns':

    1 2 6 3 7 11 4 8 12 16

Thanks for your help!

Edited: Here is a code generating identity matrix:

    program main

    use constants  ! global vairables and conventional constants
    use trans      ! transformation between different frames

    implicit none
    integer ::  ii, ij
    real*8,dimension(4,4) :: R_reg

    !call cpu_time(tic)


    write(*,*) "check1" !check-point

    !creating diagonal unity matrix
    DO ii = 1, 4  
        DO ij = 1, 4 
            R_reg(ij,ii) = (ij/ii)*(ii/ij) !integer division
        END DO
    END DO
    
    write(*,*) "check2" !check-point
    
    
    !create the test .txt file: 
    open(50, file='R_reg.txt', status='replace')
        DO ii=1, 4
            write(50,*) R_reg(ii,:)
        END DO  
    close(50)

    write(*,*) "check3" !check-point
 end program

Upvotes: 3

Views: 481

Answers (3)

veryreverie
veryreverie

Reputation: 2981

As concisely as possible, "by rows":

[(R_reg(i, i:), i=1, 4)]

and "by cols":

[(R_reg(:i, i), i=1, 4)]

Upvotes: 3

francescalus
francescalus

Reputation: 32366

As has been noted, one can go row-by-row or column-by-column selecting the desired elements. Using array constructors one needn't worry about keeping track of at least one index:

  implicit none
  integer, parameter :: N=4
  
  integer A(N,N), i, j

  A = reshape([(i,i=1,N**2)], [N, N], order=[2,1])

  print '("Matrix:")'
  do i=1,N
     print '(*(I5))', A(i,:)
  end do

  print '(/,"By rows:",/,*(I5))', [((A(i,j), j=i,N), i=1,N)]
  print '(/,"By columns:",/,*(I5))', [((A(j,i), j=1,i), i=1,N)]

end program

To store the upper-triangular parts in an array, the array constructor can easily be assigned to an allocatable rank-1 array instead of simply being printed.

Upvotes: 3

It is really just going through the array in the right order and storing the elements that you go through. It may just take a bit of experimenting to get the loop bounds correct.

integer : n    
real*8,dimension(10) :: ut_c, ut_r    


DO ii = 1, 4  
    DO ij = 1, 4 
        R_reg(ij,ii) = ii + (ij-1)*4
    END DO
END DO

n = 0
DO ij = 1, 4 
    DO ii = ij, 4  
        n = n + 1
        ut_r(n) = R_reg(ij,ii)
    END DO
END DO


n = 0
DO ii = 1, 4
   DO ij = 1, ii
        n = n + 1
        ut_c(n) = R_reg(ij,ii)
    END DO
END DO

print *, "rows:", ut_r
print *, "columns:", ut_c

Note that the real*8 syntax is not standard Fortran. See Fortran: integer*4 vs integer(4) vs integer(kind=4) and Fortran 90 kind parameter

Upvotes: 4

Related Questions