I just started learning Fortran and I have this function called matrix_power But I'm having difficulty trying to call the function. The file extension I'm using is .f and my compiler is gfortran.
Here is my code
function transpose_matrix(mat) result(mat_t)
implicit none
real, dimension(:,:), intent(in) :: mat
real, dimension(size(mat,2),size(mat,1)) :: mat_t
integer :: i, j
do i = 1, size(mat,1)
do j = 1, size(mat,2)
mat_t(j,i) = mat(i,j)
end do
end do
end function transpose_matrix
function matrix_power(mat, p) result(mat_p)
implicit none
integer, intent(in) :: p
real, dimension(:,:), intent(in) :: mat
real, dimension(size(mat,1),size(mat,2)) :: mat_p
integer :: i
mat_p = mat
do i = 2, p
mat_p = matmul(mat_p, mat)
end do
end function matrix_power
program matrix
implicit none
real, dimension(5, 5) :: matrix1 = reshape([2.0, 0.0, 0.0, 0.0, 0.0, &
0.0, 2.0, 0.0, 0.0, 0.0, &
0.0, 0.0, 2.0, 0.0, 0.0, &
0.0, 0.0, 0.0, 2.0, 0.0, &
2.0, 0.0, 0.0, 0.0, 2.0], (5, 5))
real, dimension(5, 5) :: mat_t, mat_p
integer :: i
mat_t = transpose_matrix(matrix1)
mat_p = matrix_power(matrix1, 3)
! Print the results
print *, "Matrix 1:"
print *, matrix1
print *, "Matrix 1 Transposed:"
print *, mat_t
print *, "Matrix 1 to the power of 3:"
print *, mat_p
end program matrix
I know that it's saying that there is a mismatch but it doesn't even make sense This is my definition of the mat_p
real, dimension(m,n) :: mat_t, mat_p
Here is the error I'm receiving
here is a text based error
Return type mismatch of function 'matrix_power' at (1) (UNKNOWN/REAL(4))
Function 'matrix_power' at (1) has no IMPLICIT type
As suspected by @VladimirFГероямслава in the comments, functions returning arrays must have explicit interfaces. Routines/functions with assumed shapes dummy arguments, or intent() attributes for the arguments, do also require explicit interfaces.
First of all , because you are using implicit none
(which is a good practice) in the main program, you have to define the return type of all the non-intrinsic functions you are using. For instance if you had this function:
function matrix_trace(mat,n) result(t)
implicit none
real :: mat(n,n)
real :: t
integer :: i
t = 0.0
do i = 1, n
t = t + mat(i,i)
end do
end function
You would simply have to insert in your main program:
real, external :: matrix_trace
This is an implicit interface, because you don't describe how arguments are passed. The implicit interface is the legacy pre-Fortran 90 way.
In your case your have to define explicit interfaces, with two possibilities.
Interface blocks:
In your main program you insert this code:
INTERFACE
function transpose_matrix(mat) result(mat_t)
implicit none
real, dimension(:,:), intent(in) :: mat
real, dimension(size(mat,2),size(mat,1)) :: mat_t
end function transpose_matrix
function matrix_power(mat, p) result(mat_p)
implicit none
integer, intent(in) :: p
real, dimension(:,:), intent(in) :: mat
real, dimension(size(mat,1),size(mat,2)) :: mat_p
end function matrix_power
END INTERFACE
Modules
Much better, use modules to encapsulate your functions:
!*****************************************
MODULE mymatfuncs
CONTAINS
function transpose_matrix(mat) result(mat_t)
implicit none
real, dimension(:,:), intent(in) :: mat
real, dimension(size(mat,2),size(mat,1)) :: mat_t
integer :: i, j
do i = 1, size(mat,1)
do j = 1, size(mat,2)
mat_t(j,i) = mat(i,j)
end do
end do
end function transpose_matrix
function matrix_power(mat, p) result(mat_p)
implicit none
integer, intent(in) :: p
real, dimension(:,:), intent(in) :: mat
real, dimension(size(mat,1),size(mat,2)) :: mat_p
integer :: i
mat_p = mat
do i = 2, p
mat_p = matmul(mat_p, mat)
end do
end function matrix_power
END MODULE mymatfuncs
!*****************************************
program matrix
USE mymatfuncs, only: matrix_power, transpose_matrix
implicit none
real, dimension(5, 5) :: matrix1 = reshape([2.0, 0.0, 0.0, 0.0, 0.0, &
0.0, 2.0, 0.0, 0.0, 0.0, &
0.0, 0.0, 2.0, 0.0, 0.0, &
0.0, 0.0, 0.0, 2.0, 0.0, &
2.0, 0.0, 0.0, 0.0, 2.0], (5, 5))
real, dimension(5, 5) :: mat_t, mat_p
integer :: i
mat_t = transpose_matrix(matrix1)
mat_p = matrix_power(matrix1, 3)
! Print the results
print *, "Matrix 1:"
print *, matrix1
print *, "Matrix 1 Transposed:"
print *, mat_t
print *, "Matrix 1 to the power of 3:"
print *, mat_p
end program matrix