【问题标题】:Is it possible to declare a matrix as a derived type in Fortran?是否可以在 Fortran 中将矩阵声明为派生类型?
【发布时间】:2016-07-15 05:20:37
【问题描述】:

是否可以在 Fortran 中将矩阵声明为派生类型?例如,可以做些什么,以便调用

class(four_by_four_matrix) :: A

call A%inv 

有效吗?其中inv 声明为four_by_four_matrix 的过程?

【问题讨论】:

    标签: oop fortran fortran2003 derived-types


    【解决方案1】:

    “有可能吗?”这个问题的答案是的,有可能。只需将二维数组放入您的类型:

      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)

    【讨论】:

      【解决方案2】:

      Vladimir F 使用 Fortran 2003 中引入的类型绑定过程给出 an approach,并且还在 class 的多态声明上使用 cmets。

      正如问题所暗示的那样,该答案假设您有一个 4×4 矩阵,或者至少在编译时具有已知的大小。在更广泛的使用中,人们可能想要概括。那么有价值的是使组件数组可分配(确保它以某种方式分配并注意这也不是 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
      

      当然,不限于方阵:可以使用多个参数。此外,我还跳过了种类参数化的可能性。

      【讨论】:

      • 我正在考虑写这篇文章,因为这种用法很自然。但是我还没有准备好在实践中使用它,因为 gfortran 的支持在大多数人使用的版本中仍然不可用。
      • 我没有注意到即使在最近的 gfortran 版本中也有支持(但我没有跟上),所以是的,这是对未来和更广泛受众的回答。这个站点上的 PDT 示例很少,可能是因为编译器支持有限,这似乎是一个简单而自然的案例。
      猜你喜欢
      • 1970-01-01
      • 2012-10-23
      • 2019-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多