How can I fix incorrect output from my Fortran subroutine for a test matrix?

Click For Summary

Discussion Overview

The discussion revolves around troubleshooting incorrect output from a Fortran subroutine that generates a matrix. Participants explore issues related to variable scope, initialization, and passing arrays to subroutines, focusing on programming concepts within the context of Fortran coding.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Homework-related

Main Points Raised

  • One participant notes that there are two arrays named test_mat: one in the main program and another in the subroutine, leading to confusion about which array is being initialized.
  • Another participant suggests passing the existing matrix from the main program to the subroutine instead of defining a new one within the subroutine.
  • A proposed code example illustrates how to correctly pass the matrix to the subroutine and highlights the difference in variable scope between the main program and the subroutine.
  • One participant expresses gratitude for the assistance and confirms that the suggested solution worked.

Areas of Agreement / Disagreement

Participants generally agree on the issue of variable scope and initialization, with a consensus on the need to pass the matrix to the subroutine. However, there is no explicit discussion of alternative solutions or unresolved disagreements.

Contextual Notes

The discussion does not address potential limitations in the original code, such as the handling of memory allocation or error checking, which may be relevant for robust programming practices.

Who May Find This Useful

This discussion may be useful for individuals learning Fortran programming, particularly those dealing with subroutines and array management.

autobot.d
Messages
67
Reaction score
0
Hi all,

So I have a program that calls a module that contains a subroutine so I can make a matrix.
When I write the matrix in the subroutine (commented out part in module) I get the right output, but when the main program tries to output it is some insanely small or large numbers.
I am new to Fortran (not coding) so any help/criticism would be greatly appreciated! Definitely a bit of a learning curve but I am excited to learn fortran.

Code:
program test

use test_mod

implicit none

integer :: k 
real, allocatable, Dimension(:,:) :: test_mat

write(*,*) 'Dimension for square test matrix: '
read (*,*) k

allocate(test_mat(k,k))
call test_matrix(k)

!This gives bad output, but right dimensions
write(*,*) test_mat
deallocate(test_mat)

end program test

Code:
module test_mod

implicit none

contains

    subroutine test_matrix(k)
    
integer :: k
real, dimension(:,:), allocatable :: test_mat
INTEGER :: i,j,m,nallocate(test_mat(k,k))

do i = 1,k
do j = 1,k

test_mat(i,j) = 1.d0*((i+j-1))
end do
end do

!This loop gives correct output
!do m = 1,k
!write(*,*)(test_mat(m,n), n=1,k)
!end do

deallocate(test_mat)

end subroutine test_matrix
end module test_mod
 
Technology news on Phys.org
I'm not a Fortran expert, but I think the problem is that you have two arrays named test_mat - one in the main program, and the other in your subroutine. The only one that gets initialized is the one in the subroutine, so when you print out its values, you get what you expect.

The array in the main program is never initialized, so when you print its values, you get garbage.
 
autobot.d said:
When I write the matrix in the subroutine (commented out part in module) I get the right output, but when the main program tries to output it is some insanely small or large numbers.
As Mark says, you've actually defined a new matrix in the subroutine. What you need to do is to pass the existing matrix to the subroutine. Try the following code (based on your code) for example and see if you can work out what it's doing

BTW. I put some redundant code in there to assign to "j" in the subroutine. This is just to help you understand how the variables defined in the subroutine are different to those in the main program, even if they have the same name (whereas the "passed" variables are effectively the same, even if they are given different names).

Code:
program alloctest
implicit none
  integer :: i,j 
  real, allocatable, Dimension(:,:) :: test_mat

  print "(a$)",'Dimension for square test matrix: '
  read (*,*) j
  allocate(test_mat(j,j))
  call test_matrix(test_mat,j)

  do i = 1,j
    print *,test_mat(i,:)
  end do

  deallocate(test_mat)

contains

subroutine test_matrix(tm,size)
implicit none
integer :: size
real, dimension(:,:) :: tm

  integer :: i,j
  do i = 1,size
    do j = 1,size
      test_mat(i,j) = 1.d0*((i+j-1))
    end do
  end do
  j = 0          ! Should have no effect in main program.

end subroutine test_matrix
end program alloctest
 
Last edited:
Thank you so much. That was very helpful and it worked!
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 59 ·
2
Replies
59
Views
12K
  • · Replies 5 ·
Replies
5
Views
8K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 1 ·
Replies
1
Views
3K