0

Every time I compile this program I get these errors...

  1. (This error occurs every time I try to call the subroutine.)
 103 |                         call ColumnInsert(M(n,n), b, n, col, MatOut(n,n))
      |                                         1
Error: Explicit interface required for ‘columninsert’ at (1): assumed-shape argument
  1. (This error also occurs every time I run the function)
 107 |                         detA = Determinant (MatOut(:,:), n)
      |                               1
Error: Type mismatch in argument ‘m’ at (1); passed INTEGER(4) to REAL(8)

Here is the main program:

program CramersRule
       
   ! System of equations. 2x2, 3x3
   
   implicit none
   
   ! Declare varialble
   integer :: n, row, col, i
   real*8, allocatable :: Matrix1(:,:), b(:), x(:)
   real*8 :: detA, detM, determinant
   logical :: Success
   
   ! Open the input and output files.
   open(42,file='Data2.txt')
   open(43,file='Data2Out.txt')
   
   ! Solve each system in the input files.
   do
      ! Read in size of first system.
      read(42,*) n
      if (n .eq. 0) exit  ! Quit if zero.
      
      ! Allocate memory for system, right hand side, and solution vector.
      allocate(Matrix1(n,n), b(n), x(n))
      
      ! Read in the system. Ask if you do not understand how this works!
      do row = 1, n
         read(42,*) (Matrix1(row, col), col = 1, n), b(row)
         print*, Matrix1
      enddo
      
      ! Use cramers rule to get solution.
      call Cramer(Matrix1, b, n, x, Success)
      
      if (Success) then
         ! Write solution to file
         do row = 1, n
            write(43,*) x(row)
         enddo
         write(43,*)
      else ! This happens when there is no unique solution.
         write(43,*) 'No Solution'
         write(43,*)
      endif
       ! clean up memory and go back up to top for next system.
      deallocate(Matrix1, b, x)
      
   enddo
   
   ! close files
   close(42)
   close(43)

end program CramersRule

subroutine Cramer(M, b, n, x, Success)

   ! This subroutine does Cramer's Rule
      implicit none
   
   ! Declare and initialize your variables first.
       
       real*8, allocatable :: M(:,:), b(:), x(:)
       integer :: n, row, col, i
       integer :: MatOut(n,n)
       real*8 :: detA, detM, x1, x2, x3, Determinant, solution1, solution2, solution3
       logical :: Success
       
   ! Find the determinant of M first. print it to screen.
       
       detM = Determinant(M, n)
       
       print*, "The determinant of this matrix is = ", detM
       
   ! If it is zero, set the Success logical variable and quit.
       
       if (detM .eq. 0) then
           Success = .false.
           return
       end if
       
   ! Allocate memory for a working matrix for column substituion. Then, for each
   ! column, i, substitute column i with vector b and get that determinant. 
   ! Compute the ith solution.
       
       if (n .eq. 2)then
       
            col = 1
            
            call ColumnInsert(M(n,n), b, n, col, MatOut(n,n))
            
            print*, MatOut(:,:)
            
            detA = Determinant (MatOut(:,:), n)
            
            x1 = detA/detM
            
            solution1 = x1
            
            col = col + 1
            
            call ColumnInsert(M, b, n, col, MatOut)
            
            print*, MatOut(:,:)
            
            detA = Determinant (MatOut(:,:), n)
            
            x2 = detA/detM
            
            solution2 = x2 
            
            success = .true.
       
       return 
       
       else 
           
            col = 1
            
            call ColumnInsert(M, b, n, col, MatOut)
            
            print*, MatOut(:,:)
            
            detA = Determinant (MatOut(:,:), n)
            
            x1 = detA/detM
            
            solution1 = x1
            
            col = col + 1
            
            call ColumnInsert(M, b, n, col, MatOut)
            
            print*, MatOut(:,:)
            
            detA = Determinant (MatOut(:,:), n)
            
            x2 = detA/detM
            
            solution2 = x2
            
            col = col +1
            
            call ColumnInsert(M, b, n, col, MatOut)
            
            print*, MatOut(:,:)

            detA = Determinant (MatOut(:,:), n)
            
            x3 = detA/detM
            
            solution3 = x3
           
       success = .true.
       
       return      
       end if 
     
   ! deallocate memory for the working matrix.
       
     deallocate(M, b, x)
      
end subroutine Cramer

subroutine ColumnInsert(M, b, n, col, MatOut)

   ! This subroutine takes vector b and inserts in into matrix M at column col.
       
      implicit none 
      
      integer :: n
      integer, intent(out) :: col, MatOut(:,:)
      real :: a, b1, c, d, e, f, g, h, j, k, l, m1
      double precision :: M(n,n), b(1,n)
      
      if (n .eq. 2)then 
      
      
        a = M(1,1)
        b1 = M(1,2)
        c = M(2,1)
        d = M(2,2)
        e = b(1,1)
        f = b(1,2)
        
!the next if statement substitutes based on which column the main program asks for 
            if (col .eq. 1)then

                 M(1,1) = e
                 M(1,2) = f
                 M(2,1) = c
                 M(2,2) = d
      
                 MatOut(:,:) = M(:,:)
                 
                 print*, MatOut(:,:)
      
                 return
                 
             else
             
                 M(1,1) = a
                 M(1,2) = b1
                 M(2,1) = e
                 M(2,2) = f
      
                 MatOut(:,:) = M(:,:)
                                 
                 print*, MatOut(:,:)
      
                 return
             
              endif
            
!this is for 3x3 matricies                
      
      else
      
        a = M(1,1)
        b1 = M(1,2)
        c = M(1,3)
        d = M(2,1)
        e = M(2,2)
        f = M(2,3)
        g = M(3,1)
        h = M(3,2)
        j = M(3,3)
        k = b(1,1)
        l = b(1,2)
        m1 = b(1,3)
        
                if (col .eq. 1) then 
                
                M(1,1) = k
                M(1,2) = l
                M(1,3) = m1
                M(2,1) = d
                M(2,2) = e
                M(2,3) = f
                M(3,1) = g
                M(3,2) = h
                M(3,3) = j
                
                MatOut(:,:) = M(:,:)
                
                print*, MatOut(:,:)
                
                return
                
                else if (col .eq. 2)then

                M(1,1) = a
                M(1,2) = b1
                M(1,3) = c
                M(2,1) = k
                M(2,2) = l
                M(2,3) = m1
                M(3,1) = g
                M(3,2) = h
                M(3,3) = j
                
                MatOut(:,:) = M(:,:)
                
                print*, MatOut(:,:)
                
                return
                
                else
                    
                M(1,1) = a
                M(1,2) = b1
                M(1,3) = c
                M(2,1) = d
                M(2,2) = e
                M(2,3) = f
                M(3,1) = k
                M(3,2) = l
                M(3,3) = m1
                
                MatOut(:,:) = M(:,:)
                
                print*, MatOut(:,:)
                
                return
                
                endif
    endif
                
end subroutine ColumnInsert

function Determinant(M, n) result(Det)

!pulled straight from lab 2 in week 4   
    
    integer :: n
    real*8 :: M(n,n), Det, a, b, c, d, e, f, g, h, j
    
    if (n .eq. 2) then 
    
    a = M(1,1)
    b = M(1,2)
    c = M(2,1)
    d = M(2,2)
    
    Det = (a*d)-(b*c)
    
    else
        
    a = M(1,1)
    b = M(1,2)
    c = M(1,3)
    d = M(2,1)
    e = M(2,2)
    f = M(2,3)
    g = M(3,1)
    h = M(3,2)
    j = M(3,3)
    
    Det = (a*e*j)+(b*f*g)+(c*d*h)-(c*e*g)-(b*d*j)-(a*f*h)
     
    endif

 end function Determinant

I know this might seem like a dumb question to be asking, but I cannot for the life of me find where I need to change something. Any help or guidance is greatly appreciated. Thanks!

Nik Wrye
  • 21
  • 6
  • 1
    The best guidance would be to read an intro tutorial to Fortran. Put your subroutines and functions in the `contains` portion of the main program or use a `module`. You'll quickly see that you declare `real b(:)` but then use it as a rank 2 array, ie, `f = b(1,2)` – steve Sep 27 '21 at 02:24
  • Alright, I will try to do that. If I use your method correctly, which errors should I expect to be fixed. My professor has not gone over modules and contains yet. Thanks for the help! – Nik Wrye Sep 27 '21 at 02:32
  • Does this answer your question? [Procedure with assumed-shape dummy argument must have an explicit interface](https://stackoverflow.com/questions/42766530/procedure-with-assumed-shape-dummy-argument-must-have-an-explicit-interface) – veryreverie Sep 27 '21 at 08:53

0 Answers0