1

I want to obtain an array but this array include more array its inside. I will describe in an example! I want to create 4 matrix. Main matrix is E.

   Program array1
   !*************************************************! 
   implicit none

   INTEGER, PARAMETER :: m=2 !rows
   INTEGER, PARAMETER :: n=2 !cols
   Real, DIMENSION(m,n) :: A,D
   Real, DIMENSION(1,2) :: B,C

   REAL, allocatable,DIMENSION(:,:) :: E
   allocate(E(4,4))
   ! Assign values to the matrix
   A(1,:)=(/ 1,  1 /)   
   A(2,:)=(/ 1, 2/)  
   B(1,:)=(/ 1, 2/)   
   C(1,:)=(/ 1,  1 /)   
   D(1,:)=(/ 1,  1 /)   
   D(2,:)=(/ 1,  3 /)  

   !E=(/A, B
   !    C, D)
   ! This shape of array
   !E=[A B
   !   C D]
   !Result should be as under
   !E=[1 1 1 2
   !   1 2 0 0
   !   1 1 1 1
   !   0 0 1 3]
  print *,E
  End program array1

How can I obtain this array(E) in Fortran? I am working on f90 and f95. I create a new array which is array(E). Important thing obtain E and I can improve after the array because I don't know which case or function I will use for inside an array. If it is matlab, It is easy but for fotran I don't know!

2
  • Do you want to just create a new array E from arrays A,B,C,D by copying the numbers or do you want them to be somehow part of E? Do you really require the old Fortran 90? Do you have any code you can share? How are A,B,C,D declared? How should E be declared? Commented May 25, 2018 at 14:05
  • f90 and f95 is possible to work on it. I create a new array and want to put inside that array Commented May 25, 2018 at 14:24

2 Answers 2

4

Try assigning the array, row by row, using the array concatenation operation [a,b]

Program array1
!*************************************************! 
implicit none

INTEGER, PARAMETER :: m=2 !rows
INTEGER, PARAMETER :: n=2 !cols
Real, DIMENSION(m,n) :: A,D
Real, DIMENSION(m,n) :: B,C              ! made B,C conforming

REAL, allocatable,DIMENSION(:,:) :: E

    allocate(E(2*m,2*n))
    ! Assign values to the matrix
    A(1,:)=[ 1, 1 ]   
    A(2,:)=[ 1, 2 ]  
    B(1,:)=[ 1, 2 ]   
    C(1,:)=[ 1, 1 ]   
    D(1,:)=[ 1, 1 ]   
    D(2,:)=[ 1, 3 ]

    ! This shape of array
    !E=[A B
    !   C D]

    ! assign row-by-row, using array concat
    E(1,:) = [A(1,:),B(1,:)]
    E(2,:) = [A(2,:),B(2,:)]
    E(3,:) = [C(1,:),D(1,:)]
    E(4,:) = [C(2,:),D(2,:)]

   ! print results row-by-row
    write (*,*) E(1,:)
    write (*,*) E(2,:)
    write (*,*) E(3,:)
    write (*,*) E(4,:)

End program array1

Alternatively, you can use array sections

E(1:2, 1:2) = A
E(1:1, 3:4) = B
E(3:3, 1:2) = C
E(3:4, 3:4) = D
Sign up to request clarification or add additional context in comments.

4 Comments

There is no differrence between (/ /) and [ ]. The latter is a Fortran 2003 syntax for the same thing, the array constructor. It is not an "array concatenation operator".
@VladimirF - it is both. c = [a, b] concatenates a and b into c.
It forms an array from a and b, whatever they are. But the combination of (/ /) in the first half of the code and then suddenly [ ] in the other half of the code, combined with the inexact name (or a name not found in the standard) and the fact that the OP requested F95, warranted a clarification comment IMO.
@VladimirF - I edited the post to remove the "old" (\ X \) notation with the "new" [ X ].
3

I wrote a function, catmat, that gets two 2d arrays and concatenates them along a common dimension. See E and F to understand how it works. The array you want is G.

Notice that the allocation is done inside catmat.

program main
  implicit none
  real, dimension(2,2) :: A
  real, dimension(1,2) :: B
  real, dimension(1,2) :: C
  real, dimension(2,2) :: D
  real, dimension(:,:), allocatable :: E
  real, dimension(:,:), allocatable :: F
  real, dimension(:,:), allocatable :: G
  integer :: i

  A = reshape( [1, 2, 3, 4], [2,2] )
  B(1,:) = [ -1, -2 ]
  C(1,:) = [ -3, -4 ]
  D = reshape( [5, 6, 7, 8], [2,2] )


  write(*,*) ( A(i,:), NEW_LINE('a'), i = 1, size(A,dim=1) )

  write(*,*) ( D(i,:), NEW_LINE('a'), i = 1, size(D,dim=1) )


  E = catmat( A, D, 1)

  write(*,*) "size of E", size(E, dim=1), size(E, dim=2)
  write(*,*) ( E(i,:), NEW_LINE('a'), i = 1, size(E,dim=1) )

  F = catmat( A, D, 2)

  write(*,*) "size of F", size(F, dim=1), size(F, dim=2)
  write(*,*) ( F(i,:), NEW_LINE('a'), i = 1, size(F,dim=1) )

  G = catmat( catmat( A, B, 1), catmat( C, D, 1), 2)

  write(*,*) "size of G", size(G, dim=1), size(G, dim=2)
  write(*,*) ( G(i,:), NEW_LINE('a'), i = 1, size(G,dim=1) )



contains
  function catmat(matl, matr, cdim) result(res)
    real, dimension(:,:), intent(in)  :: matl
    real, dimension(:,:), intent(in)  :: matr
    integer, intent(in)               :: cdim
    real, dimension(:,:), allocatable :: res
    integer                           :: max_dim

    ! Assuming 2d arrays
    if( cdim .ne. 1 .and. cdim .ne. 2 ) then
      write(*,*) "ERROR"
      stop
    end if

    max_dim =  size(matl,dim=cdim)
    if ( size(matr,dim=cdim) .gt. size(matl,dim=cdim) ) max_dim = size(matr,dim=cdim)


    if( cdim .eq. 1 ) then
      allocate( res( max_dim, size(matl,dim=2) + size(matr,dim=2) ) )
    else
      allocate( res( size(matl,dim=1) + size(matr,dim=1), max_dim ) )
    end if

    res = 0

    if(cdim .eq.1 ) then
      res(:,1:size(matl,dim=2)) = matl
      res(:,size(matl,dim=2)+1:size(matl,dim=2)+size(matr,dim=2)) = matr
    else
      res(1:size(matl,dim=1),:) = matl
      res(size(matl,dim=1)+1:size(matl,dim=1)+size(matr,dim=1),:) = matr
    end if

  end function catmat

end program main

5 Comments

I tried to execute in fortran f90 but i think this is written in fortran 2003 syntax. Because i am working on f90/f95 and giving error. I dont know where i am doing wrong. Thanks for effort :)
@Nobody The NEW_LINE intrinsic and the [ ] syntax come from F2003. And also the allocatable result of the function is F2003 or F95 + a Technical Specification.
I have still tried to convert to code in f90. Because function catmat(matl, matr, cdim) result(res) is a 2003 syntax. Can someone help for f90/f95 format? I think this(result(res)) format is not possible for f90 @Eliad and @Vladimir
@nobody The result clause is perfectly fine in Fortran 90. The allocatable attribute of the result variable is F2003, but the result keyword itself is Fortran 90. Fortran 90 is obsolete anyway, it is too old and inadequate for modern programs.
Thanks a lot for all comments and helping for program :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.