num_matrix_full.F90 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. !
  2. ! NAME
  3. ! num_matrix_full - defines full matrix
  4. !
  5. ! USAGE
  6. !
  7. ! use num_matrix_full
  8. !
  9. ! type(TFullMatrix) :: A
  10. !
  11. ! ! initialize matrix:
  12. ! ! o no memory allocated
  13. ! ! o zero flag
  14. ! call Init( A )
  15. !
  16. ! ! (re)allocate memory to store contents:
  17. ! call SetStorage( A, am, an )
  18. ! call ClearStorage( A )
  19. !
  20. ! ! zero flag ?
  21. ! if ( IsZero(A) ) ...
  22. !
  23. ! ! define full matrix:
  24. ! call SetFull( A, m, n )
  25. ! call SetFull( A, arr(:,:) )
  26. !
  27. ! ! done
  28. ! call Done( A )
  29. !
  30. module num_matrix_full
  31. implicit none
  32. ! --- in/out ------------------------------------
  33. private
  34. public :: TFullMatrix
  35. public :: Init, Done
  36. public :: SetStorage, ClearStorage
  37. public :: IsZero
  38. public :: SetFull
  39. ! --- const ----------------------------------
  40. character(len=*), parameter :: mname = 'module num_matrix_full'
  41. ! --- types ------------------------------------
  42. type TFullMatrix
  43. ! key name for error mesages
  44. character(len=20) :: key
  45. ! logical matrix dimension:
  46. integer :: m, n
  47. ! contents flags
  48. logical :: zero
  49. ! physical storage:
  50. real, pointer :: a(:,:)
  51. integer :: am, an
  52. integer :: knd
  53. end type TFullMatrix
  54. ! --- interfaces ------------------------------
  55. interface Init
  56. module procedure mat_Init
  57. end interface
  58. interface Done
  59. module procedure mat_Done
  60. end interface
  61. interface SetStorage
  62. module procedure mat_SetStorage
  63. end interface
  64. interface ClearStorage
  65. module procedure mat_ClearStorage
  66. end interface
  67. interface IsZero
  68. module procedure mat_IsZero
  69. end interface
  70. interface SetFull
  71. module procedure mat_SetFull_range
  72. module procedure mat_SetFull_array
  73. end interface
  74. contains
  75. ! ==============================================================
  76. subroutine mat_Init( mat, key )
  77. ! --- in/out ------------------------------
  78. type(TFullMatrix), intent(out) :: mat
  79. character(len=*), intent(in) :: key
  80. ! --- const ----------------------------------
  81. character(len=*), parameter :: name = mname//', mat_Init'
  82. ! --- begin -------------------------------
  83. ! store key
  84. mat%key = key
  85. ! dummy size:
  86. mat%m = 0
  87. mat%n = 0
  88. ! start with zero matrix:
  89. mat%zero = .true.
  90. ! initialize physical storage
  91. nullify( mat%a )
  92. mat%knd = kind(1.0)
  93. end subroutine mat_Init
  94. ! ***
  95. subroutine mat_Done( mat )
  96. ! --- in/out ------------------------------
  97. type(TFullMatrix), intent(inout) :: mat
  98. ! --- const ----------------------------------
  99. character(len=*), parameter :: name = mname//', mat_Done'
  100. ! --- begin -------------------------------
  101. ! clear memory ...
  102. call ClearStorage( mat )
  103. end subroutine mat_Done
  104. ! =========================================================
  105. subroutine mat_SetStorage( mat, am, an )
  106. ! --- in/out ------------------------------
  107. type(TFullMatrix), intent(inout) :: mat
  108. integer, intent(in) :: am, an
  109. ! --- const ----------------------------------
  110. character(len=*), parameter :: name = mname//', mat_SetStorage'
  111. ! --- local -------------------------------
  112. integer :: stat
  113. ! --- begin -------------------------------
  114. ! check ...
  115. if ( (am < 1) .or. (an < 1) ) then
  116. write (*,'("ERROR - strange storage definition:")')
  117. write (*,'("ERROR - storage : ",2i6)') am, an
  118. write (*,'("ERROR in ",a)') name; stop
  119. end if
  120. ! set maximum shape:
  121. mat%am = am
  122. mat%an = an
  123. ! allocate memory:
  124. if ( associated(mat%a) ) then
  125. if ( any( shape(mat%a) /= (/mat%am,mat%an/) ) ) then
  126. deallocate( mat%a, stat=stat )
  127. if ( stat /= 0 ) then
  128. write (*,'("ERROR - error during deallocation of matrix;")')
  129. write (*,'("ERROR - status : ",i6)') stat
  130. write (*,'("ERROR - matrix key : ",a)') mat%key
  131. write (*,'("ERROR in ",a)') name; stop
  132. end if
  133. end if
  134. end if
  135. if ( .not. associated(mat%a) ) then
  136. allocate( mat%a(mat%am,mat%an), stat=stat )
  137. if ( stat /= 0 ) then
  138. write (*,'("ERROR - error during allocation of matrix;")')
  139. write (*,'("ERROR - status : ",i6)') stat
  140. write (*,'("ERROR - matrix key : ",a)') mat%key
  141. write (*,'("ERROR in ",a)') name; stop
  142. end if
  143. end if
  144. end subroutine mat_SetStorage
  145. ! ***
  146. subroutine mat_ClearStorage( mat )
  147. ! --- in/out ------------------------------
  148. type(TFullMatrix), intent(inout) :: mat
  149. ! --- const ----------------------------------
  150. character(len=*), parameter :: name = mname//', mat_ClearStorage'
  151. ! --- local -------------------------------
  152. integer :: stat
  153. ! --- begin -------------------------------
  154. ! remove physical storage ...
  155. if ( associated(mat%a) ) then
  156. deallocate( mat%a, stat=stat )
  157. if ( stat /= 0 ) then
  158. write (*,'("ERROR - error during deallocation of matrix;")')
  159. write (*,'("ERROR - status : ",i6)') stat
  160. write (*,'("ERROR - matrix key : ",a)') mat%key
  161. write (*,'("ERROR in ",a)') name; stop
  162. end if
  163. nullify( mat%a )
  164. end if
  165. end subroutine mat_ClearStorage
  166. ! =========================================================
  167. logical function mat_IsZero( mat )
  168. ! --- in/out ------------------------------
  169. type(TFullMatrix), intent(in) :: mat
  170. ! --- begin -------------------------------
  171. mat_IsZero = mat%zero
  172. end function mat_IsZero
  173. ! =========================================================
  174. subroutine mat_SetFull_range( mat, m, n )
  175. ! --- in/out ------------------------------
  176. type(TFullMatrix), intent(inout) :: mat
  177. integer, intent(in) :: m, n
  178. ! --- const ----------------------------------
  179. character(len=*), parameter :: name = mname//', mat_SetFull_range'
  180. ! --- begin -------------------------------
  181. ! memory allocated ?
  182. if ( .not. associated(mat%a) ) then
  183. write (*,'("ERROR - no storage allocated")')
  184. write (*,'("ERROR in ",a)') name; stop
  185. end if
  186. ! check ...
  187. if ( (m < 1) .or. (n < 1) .or. &
  188. (m > mat%am) .or. (n > mat%an) ) then
  189. write (*,'("ERROR - strange full matrix definition:")')
  190. write (*,'("ERROR - matrix shape : ",2i6)') m, n
  191. write (*,'("ERROR - storage : ",2i6)') mat%am, mat%an
  192. write (*,'("ERROR in ",a)') name; stop
  193. end if
  194. ! logical shape of the matrix:
  195. mat%m = m
  196. mat%n = n
  197. end subroutine mat_SetFull_range
  198. ! ***
  199. subroutine mat_SetFull_array( mat, A, transA )
  200. ! --- in/out ------------------------------
  201. type(TFullMatrix), intent(inout) :: mat
  202. real, intent(in) :: A(:,:)
  203. character(len=1), intent(in) :: transA
  204. ! --- const ----------------------------------
  205. character(len=*), parameter :: name = mname//', mat_SetFull_array'
  206. ! --- local --------------------------------
  207. integer :: m, n
  208. ! --- begin -------------------------------
  209. ! extract shape
  210. m = size(A,1)
  211. n = size(A,2)
  212. if ( transA == 'N' ) then
  213. ! set shape etc, checks included:
  214. call SetFull( mat, m, n )
  215. ! fill contents
  216. mat%a(1:mat%m,1:mat%n) = A
  217. else if ( transA == 'T' ) then
  218. ! set shape etc, checks included:
  219. call SetFull( mat, n, m )
  220. ! fill contents
  221. mat%a(1:mat%m,1:mat%n) = transpose(A)
  222. else
  223. write (*,'("ERROR - unknown key for normal/transposed : ",a)') transA
  224. write (*,'("ERROR in ",a)') name; stop
  225. end if
  226. ! not zero anymore
  227. mat%zero = .false.
  228. end subroutine mat_SetFull_array
  229. end module num_matrix_full