是否可以在 Fortran 中将矩阵声明为派生类型?
Is it possible to declare a matrix as a derived type in Fortran?
是否可以在 Fortran 中将矩阵声明为派生类型?例如,是否可以做一些事情,以便调用
class(four_by_four_matrix) :: A
call A%inv
有效吗?其中 inv
被声明为 four_by_four_matrix
?
的过程
问题"is it possible?"的答案是肯定的,有可能。只需将二维数组放入您的类型中:
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
如果你需要更详细的,你要用你实际的详细问题来提问。
BTW 类型绑定过程和 class
关键字是在 Fortran 2003 中引入的。请注意,您不一定需要使用 class
,如果您需要,也可以使用 type(four_by_four_matrix)
变量不是多态的。
Vladimir F 给出了 使用 Fortran 2003 中引入的类型绑定过程,并且还评论了 class
.
的多态声明
该答案假设您有一个四乘四的矩阵,或者至少是编译时已知的大小。在更广泛的使用中,人们可能想要概括。然后有价值的是使组件数组可分配(确保它以某种方式分配并注意这也不是 Fortran 90/95)。
或者,Fortran 2003 还引入了参数化 派生类型的概念。在这里,就像字符变量中长度的概念一样,可以有一个长度参数化的派生类型:
type square_matrix(n)
integer, len :: n
real matrix(n,n)
end type square_matrix
像
这样声明变量
type(square_matrix(4)) A ! Like type(four_by_four_matrix), perhaps
type(square_matrix(8)) B ! Like type(eight_by_eight_matrix), perhaps
甚至可以有这种类型的延迟长度变量
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
类型绑定过程作用于任意参数化类型,使用假定长度语法:
subroutine inv(sm)
class(square_matrix(*)), intent(inout) :: sm
...
end subroutine inv
一个几乎完整的例子如下。
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
当然,不限于方阵:可以使用多个参数。此外,我还跳过了种类参数化的可能性。
是否可以在 Fortran 中将矩阵声明为派生类型?例如,是否可以做一些事情,以便调用
class(four_by_four_matrix) :: A
call A%inv
有效吗?其中 inv
被声明为 four_by_four_matrix
?
问题"is it possible?"的答案是肯定的,有可能。只需将二维数组放入您的类型中:
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
如果你需要更详细的,你要用你实际的详细问题来提问。
BTW 类型绑定过程和 class
关键字是在 Fortran 2003 中引入的。请注意,您不一定需要使用 class
,如果您需要,也可以使用 type(four_by_four_matrix)
变量不是多态的。
Vladimir F 给出了 class
.
该答案假设您有一个四乘四的矩阵,或者至少是编译时已知的大小。在更广泛的使用中,人们可能想要概括。然后有价值的是使组件数组可分配(确保它以某种方式分配并注意这也不是 Fortran 90/95)。
或者,Fortran 2003 还引入了参数化 派生类型的概念。在这里,就像字符变量中长度的概念一样,可以有一个长度参数化的派生类型:
type square_matrix(n)
integer, len :: n
real matrix(n,n)
end type square_matrix
像
这样声明变量type(square_matrix(4)) A ! Like type(four_by_four_matrix), perhaps
type(square_matrix(8)) B ! Like type(eight_by_eight_matrix), perhaps
甚至可以有这种类型的延迟长度变量
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
类型绑定过程作用于任意参数化类型,使用假定长度语法:
subroutine inv(sm)
class(square_matrix(*)), intent(inout) :: sm
...
end subroutine inv
一个几乎完整的例子如下。
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
当然,不限于方阵:可以使用多个参数。此外,我还跳过了种类参数化的可能性。