问题
Is it possible to declare a matrix as a derived type in Fortran? For example, can something be done so that the call
class(four_by_four_matrix) :: A
call A%inv
is valid? Where inv
is declared as a procedure of four_by_four_matrix
?
回答1:
The answer to the question "is it possible?" is yes, it is possible. Just put a 2d array into your type:
type four_by_four_matrix
real(rp) :: arr(4,4)
contains
procedure :: inv => four_by_four_matrix_inv
end type
contains
subroutine four_by_four_matrix_inv(self)
class(four_by_four_matrix), intent(inout) :: self
....
!somehow invert self%arr
end subroutine
end module
...
type(four_by_four_matrix) :: A
call A%inv
If you need more details, you have to make a question with your actual detailed problems.
BTW type-bound procedures and the class
keyword were introduced in Fortran 2003. Notice you don't necessarily need to use class
, you can also use type(four_by_four_matrix)
if your variable is not polymorphic.
回答2:
Vladimir F gives an approach using type-bound procedures introduced in Fortran 2003, and also comments on the polymorphic declaration of class
.
That answer assumes you have, as the question suggests, a four-by-four matrix, or at least a size known when compiling. In wider use one may want to generalize. Of value then would be making the component array allocatable (ensuring that it is somehow allocated and noting this isn't Fortran 90/95 either).
Alternatively, Fortran 2003 also introduced the concept of parameterized derived types. Here, much like the idea of length in a character variable one could have a length-parameterized derived type:
type square_matrix(n)
integer, len :: n
real matrix(n,n)
end type square_matrix
declaring variables like
type(square_matrix(4)) A ! Like type(four_by_four_matrix), perhaps
type(square_matrix(8)) B ! Like type(eight_by_eight_matrix), perhaps
One can even have deferred-length variables of this type
type(square_matrix(:)), allocatable :: A, B
integer q
q = ... ! Something run-time, perhaps.
allocate(square_matrix(q) :: A)
B = square_matrix(q)(matrix) ! Constructor using a matrix value
The type-bound procedure acts on an arbitrary parameterized type, using assumed-length syntax:
subroutine inv(sm)
class(square_matrix(*)), intent(inout) :: sm
...
end subroutine inv
An almost complete example would be as follows.
module matrix_mod
implicit none
type square_matrix(n)
integer, len :: n
real matrix(n,n)
contains
procedure inv
end type square_matrix
contains
subroutine inv(sm)
class(square_matrix(*)), intent(inout) :: sm
! Some inv stuff, but as a placeholder
print '("Called inv with a ",I0,"-by-",I0," matrix")', sm%n, sm%n
end subroutine inv
end module matrix_mod
use matrix_mod
implicit none
type(square_matrix(4)) A
! Establish A%matrix somehow, perhaps with a structure constructor
call A%inv()
end
Naturally, one isn't restricted to square matrices: multiple parameters can be used. Further, I've also skipped over the possibility of kind-parameterization.
来源:https://stackoverflow.com/questions/36254045/is-it-possible-to-declare-a-matrix-as-a-derived-type-in-fortran