Is it possible to declare a matrix as a derived type in Fortran?

非 Y 不嫁゛ 提交于 2019-12-08 06:46:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!