Commit c64a05f8a6b6da9ac2fb4f115f7ea401387f12c3
1 parent
2b83390c62
Exists in
master
and in
3 other branches
Sparse Determinant : use of mantisse + exponent
git-svn-id: https://lxsd.femto-st.fr/svn/fvn@65 b657c933-2333-4658-acf2-d3c7c2708721
Showing 5 changed files with 28 additions and 43 deletions Inline Diff
fvn_sparse/fvn_sparse.f90
module fvn_sparse | 1 | 1 | module fvn_sparse | |
use fvn_common | 2 | 2 | use fvn_common | |
implicit none | 3 | 3 | implicit none | |
4 | 4 | |||
! Sparse solving | 5 | 5 | ! Sparse solving | |
interface fvn_sparse_solve | 6 | 6 | interface fvn_sparse_solve | |
module procedure fvn_zl_sparse_solve,fvn_zi_sparse_solve,fvn_dl_sparse_solve,fvn_di_sparse_solve | 7 | 7 | module procedure fvn_zl_sparse_solve,fvn_zi_sparse_solve,fvn_dl_sparse_solve,fvn_di_sparse_solve | |
end interface fvn_sparse_solve | 8 | 8 | end interface fvn_sparse_solve | |
9 | 9 | |||
interface fvn_sparse_det | 10 | 10 | interface fvn_sparse_det | |
module procedure fvn_zl_sparse_det,fvn_zi_sparse_det,fvn_dl_sparse_det,fvn_di_sparse_det | 11 | 11 | module procedure fvn_zl_sparse_det,fvn_zi_sparse_det,fvn_dl_sparse_det,fvn_di_sparse_det | |
end interface fvn_sparse_det | 12 | 12 | end interface fvn_sparse_det | |
contains | 13 | 13 | contains | |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 14 | 14 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! | 15 | 15 | ! | |
! SPARSE RESOLUTION | 16 | 16 | ! SPARSE RESOLUTION | |
! | 17 | 17 | ! | |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 18 | 18 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! | 19 | 19 | ! | |
! Sparse resolution is done by interfaçing Tim Davi's UMFPACK | 20 | 20 | ! Sparse resolution is done by interfaçing Tim Davi's UMFPACK | |
! http://www.cise.ufl.edu/research/sparse/SuiteSparse/ | 21 | 21 | ! http://www.cise.ufl.edu/research/sparse/SuiteSparse/ | |
! Used packages from SuiteSparse : AMD,UMFPACK,UFconfig | 22 | 22 | ! Used packages from SuiteSparse : AMD,UMFPACK,UFconfig | |
! | 23 | 23 | ! | |
! Solve Ax=B using UMFPACK | 24 | 24 | ! Solve Ax=B using UMFPACK | |
! | 25 | 25 | ! | |
! Where A is a sparse matrix given in its triplet form | 26 | 26 | ! Where A is a sparse matrix given in its triplet form | |
! T -> non zero elements | 27 | 27 | ! T -> non zero elements | |
! Ti,Tj -> row and column index (1-based) of the given elt | 28 | 28 | ! Ti,Tj -> row and column index (1-based) of the given elt | |
! n : rank of matrix A | 29 | 29 | ! n : rank of matrix A | |
! nz : number of non zero elts | 30 | 30 | ! nz : number of non zero elts | |
! | 31 | 31 | ! | |
! fvn_*_sparse_solve | 32 | 32 | ! fvn_*_sparse_solve | |
! * = zl : double complex + integer(kind=dp_kind) | 33 | 33 | ! * = zl : double complex + integer(kind=dp_kind) | |
! * = zi : double complex + integer(kind=sp_kind) | 34 | 34 | ! * = zi : double complex + integer(kind=sp_kind) | |
! | 35 | 35 | ! | |
subroutine fvn_zl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | 36 | 36 | subroutine fvn_zl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
implicit none | 37 | 37 | implicit none | |
integer(kind=dp_kind), intent(in) :: n,nz | 38 | 38 | integer(kind=dp_kind), intent(in) :: n,nz | |
complex(kind=dp_kind),dimension(nz),intent(in) :: T | 39 | 39 | complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | 40 | 40 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | |
complex(kind=dp_kind),dimension(n),intent(in) :: B | 41 | 41 | complex(kind=dp_kind),dimension(n),intent(in) :: B | |
complex(kind=dp_kind),dimension(n),intent(out) :: x | 42 | 42 | complex(kind=dp_kind),dimension(n),intent(out) :: x | |
integer(kind=dp_kind), intent(out) :: status | 43 | 43 | integer(kind=dp_kind), intent(out) :: status | |
complex(kind=dp_kind), optional, intent(out) :: det | 44 | 44 | real(kind=dp_kind), dimension(3), optional, intent(out) :: det | |
45 | 45 | |||
integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | 46 | 46 | integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | 47 | 47 | real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 48 | 48 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | 49 | 49 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | |
integer(kind=dp_kind) :: symbolic,numeric | 50 | 50 | integer(kind=dp_kind) :: symbolic,numeric | |
real(kind=dp_kind),dimension(:),allocatable :: xx,xz,bx,bz | 51 | 51 | real(kind=dp_kind),dimension(:),allocatable :: xx,xz,bx,bz | |
real(kind=dp_kind),dimension(90) :: info | 52 | 52 | real(kind=dp_kind),dimension(90) :: info | |
real(kind=dp_kind),dimension(20) :: control | 53 | 53 | real(kind=dp_kind),dimension(20) :: control | |
integer(kind=dp_kind) :: sys | 54 | 54 | integer(kind=dp_kind) :: sys | |
real(kind=dp_kind) :: Mx,Mz,Ex | 55 | |||
56 | 55 | |||
57 | 56 | |||
status=0 | 58 | 57 | status=0 | |
59 | 58 | |||
! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | 60 | 59 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
! Tx and Tz are the real and imaginary parts of T | 61 | 60 | ! Tx and Tz are the real and imaginary parts of T | |
allocate(wTi(nz),wTj(nz)) | 62 | 61 | allocate(wTi(nz),wTj(nz)) | |
allocate(Tx(nz),Tz(nz)) | 63 | 62 | allocate(Tx(nz),Tz(nz)) | |
Tx=dble(T) | 64 | 63 | Tx=dble(T) | |
Tz=aimag(T) | 65 | 64 | Tz=aimag(T) | |
wTi=Ti-1 | 66 | 65 | wTi=Ti-1 | |
wTj=Tj-1 | 67 | 66 | wTj=Tj-1 | |
allocate(Ax(nz),Az(nz)) | 68 | 67 | allocate(Ax(nz),Az(nz)) | |
allocate(Ap(n+1),Ai(nz)) | 69 | 68 | allocate(Ap(n+1),Ai(nz)) | |
70 | 69 | |||
! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 71 | 70 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
call umfpack_zl_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | 72 | 71 | call umfpack_zl_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
! if status is not zero a problem has occured | 73 | 72 | ! if status is not zero a problem has occured | |
if (status /= 0) then | 74 | 73 | if (status /= 0) then | |
write(*,*) "Problem during umfpack_zl_triplet_to_col" | 75 | 74 | write(*,*) "Problem during umfpack_zl_triplet_to_col" | |
endif | 76 | 75 | endif | |
77 | 76 | |||
! Define defaults control values | 78 | 77 | ! Define defaults control values | |
call umfpack_zl_defaults(control) | 79 | 78 | call umfpack_zl_defaults(control) | |
80 | 79 | |||
! Symbolic analysis | 81 | 80 | ! Symbolic analysis | |
call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 82 | 81 | call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
! info(1) should be zero | 83 | 82 | ! info(1) should be zero | |
if (info(1) /= 0) then | 84 | 83 | if (info(1) /= 0) then | |
write(*,*) "Problem during symbolic analysis" | 85 | 84 | write(*,*) "Problem during symbolic analysis" | |
status=info(1) | 86 | 85 | status=info(1) | |
endif | 87 | 86 | endif | |
88 | 87 | |||
! Numerical factorization | 89 | 88 | ! Numerical factorization | |
call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 90 | 89 | call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
! info(1) should be zero | 91 | 90 | ! info(1) should be zero | |
if (info(1) /= 0) then | 92 | 91 | if (info(1) /= 0) then | |
write(*,*) "Problem during numerical factorization" | 93 | 92 | write(*,*) "Problem during numerical factorization" | |
status=info(1) | 94 | 93 | status=info(1) | |
endif | 95 | 94 | endif | |
96 | 95 | |||
! free the C symbolic pointer | 97 | 96 | ! free the C symbolic pointer | |
call umfpack_zl_free_symbolic (symbolic) | 98 | 97 | call umfpack_zl_free_symbolic (symbolic) | |
99 | 98 | |||
! if parameter det is present, the determinant of the matrix is calculated | 100 | 99 | ! if parameter det is present, the determinant of the matrix is calculated | |
if (present(det) ) then | 101 | 100 | if (present(det) ) then | |
call umfpack_zl_get_determinant(Mx,Mz,Ex,numeric,info,status) | 102 | 101 | call umfpack_zl_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
det=cmplx(Mx,Mz,kind=dp_kind)*10**Ex | 103 | |||
! info(1) should be zero | 104 | 102 | ! info(1) should be zero | |
if (info(1) /= 0) then | 105 | 103 | if (info(1) /= 0) then | |
write(*,*) "Problem during sparse determinant, returned code : ",info(1) | 106 | 104 | write(*,*) "Problem during sparse determinant, returned code : ",info(1) | |
status=info(1) | 107 | 105 | status=info(1) | |
endif | 108 | 106 | endif | |
endif | 109 | 107 | endif | |
110 | 108 | |||
111 | 109 | |||
112 | 110 | |||
allocate(bx(n),bz(n),xx(n),xz(n)) | 113 | 111 | allocate(bx(n),bz(n),xx(n),xz(n)) | |
bx=dble(B) | 114 | 112 | bx=dble(B) | |
bz=aimag(B) | 115 | 113 | bz=aimag(B) | |
sys=0 | 116 | 114 | sys=0 | |
! sys may be used to define type of solving -> see umfpack.h | 117 | 115 | ! sys may be used to define type of solving -> see umfpack.h | |
118 | 116 | |||
! Solving | 119 | 117 | ! Solving | |
call umfpack_zl_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | 120 | 118 | call umfpack_zl_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | |
! info(1) should be zero | 121 | 119 | ! info(1) should be zero | |
if (info(1) /= 0) then | 122 | 120 | if (info(1) /= 0) then | |
write(*,*) "Problem during solving" | 123 | 121 | write(*,*) "Problem during solving" | |
status=info(1) | 124 | 122 | status=info(1) | |
endif | 125 | 123 | endif | |
126 | 124 | |||
127 | 125 | |||
! free the C numeric pointer | 128 | 126 | ! free the C numeric pointer | |
call umfpack_zl_free_numeric (numeric) | 129 | 127 | call umfpack_zl_free_numeric (numeric) | |
130 | 128 | |||
x=cmplx(xx,xz,dp_kind) | 131 | 129 | x=cmplx(xx,xz,dp_kind) | |
132 | 130 | |||
deallocate(bx,bz,xx,xz) | 133 | 131 | deallocate(bx,bz,xx,xz) | |
deallocate(Ax,Az) | 134 | 132 | deallocate(Ax,Az) | |
deallocate(Tx,Tz) | 135 | 133 | deallocate(Tx,Tz) | |
deallocate(wTi,wTj) | 136 | 134 | deallocate(wTi,wTj) | |
end subroutine | 137 | 135 | end subroutine | |
138 | 136 | |||
139 | 137 | |||
140 | 138 | |||
141 | 139 | |||
142 | 140 | |||
subroutine fvn_zi_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | 143 | 141 | subroutine fvn_zi_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
implicit none | 144 | 142 | implicit none | |
integer(kind=sp_kind), intent(in) :: n,nz | 145 | 143 | integer(kind=sp_kind), intent(in) :: n,nz | |
complex(kind=dp_kind),dimension(nz),intent(in) :: T | 146 | 144 | complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | 147 | 145 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | |
complex(kind=dp_kind),dimension(n),intent(in) :: B | 148 | 146 | complex(kind=dp_kind),dimension(n),intent(in) :: B | |
complex(kind=dp_kind),dimension(n),intent(out) :: x | 149 | 147 | complex(kind=dp_kind),dimension(n),intent(out) :: x | |
integer(kind=sp_kind), intent(out) :: status | 150 | 148 | integer(kind=sp_kind), intent(out) :: status | |
complex(kind=dp_kind), optional, intent(out) :: det | 151 | 149 | real(kind=dp_kind), dimension(3), optional, intent(out) :: det | |
152 | 150 | |||
integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | 153 | 151 | integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | |
real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | 154 | 152 | real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 155 | 153 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | 156 | 154 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | |
!integer(kind=dp_kind) :: symbolic,numeric | 157 | 155 | !integer(kind=dp_kind) :: symbolic,numeric | |
integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 158 | 156 | integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
! As symbolic and numeric are used to store a C pointer, it is necessary to | 159 | 157 | ! As symbolic and numeric are used to store a C pointer, it is necessary to | |
! still use an integer(kind=dp_kind) for 64bits machines | 160 | 158 | ! still use an integer(kind=dp_kind) for 64bits machines | |
! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 161 | 159 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
real(kind=dp_kind),dimension(:),allocatable :: xx,xz,bx,bz | 162 | 160 | real(kind=dp_kind),dimension(:),allocatable :: xx,xz,bx,bz | |
real(kind=dp_kind),dimension(90) :: info | 163 | 161 | real(kind=dp_kind),dimension(90) :: info | |
real(kind=dp_kind),dimension(20) :: control | 164 | 162 | real(kind=dp_kind),dimension(20) :: control | |
integer(kind=sp_kind) :: sys | 165 | 163 | integer(kind=sp_kind) :: sys | |
real(kind=dp_kind) :: Mx,Mz,Ex | 166 | |||
167 | 164 | |||
status=0 | 168 | 165 | status=0 | |
! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | 169 | 166 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
! Tx and Tz are the real and imaginary parts of T | 170 | 167 | ! Tx and Tz are the real and imaginary parts of T | |
allocate(wTi(nz),wTj(nz)) | 171 | 168 | allocate(wTi(nz),wTj(nz)) | |
allocate(Tx(nz),Tz(nz)) | 172 | 169 | allocate(Tx(nz),Tz(nz)) | |
Tx=dble(T) | 173 | 170 | Tx=dble(T) | |
Tz=aimag(T) | 174 | 171 | Tz=aimag(T) | |
wTi=Ti-1 | 175 | 172 | wTi=Ti-1 | |
wTj=Tj-1 | 176 | 173 | wTj=Tj-1 | |
allocate(Ax(nz),Az(nz)) | 177 | 174 | allocate(Ax(nz),Az(nz)) | |
allocate(Ap(n+1),Ai(nz)) | 178 | 175 | allocate(Ap(n+1),Ai(nz)) | |
179 | 176 | |||
! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 180 | 177 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
call umfpack_zi_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | 181 | 178 | call umfpack_zi_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
! if status is not zero a problem has occured | 182 | 179 | ! if status is not zero a problem has occured | |
if (status /= 0) then | 183 | 180 | if (status /= 0) then | |
write(*,*) "Problem during umfpack_zl_triplet_to_col" | 184 | 181 | write(*,*) "Problem during umfpack_zl_triplet_to_col" | |
endif | 185 | 182 | endif | |
186 | 183 | |||
! Define defaults control values | 187 | 184 | ! Define defaults control values | |
call umfpack_zi_defaults(control) | 188 | 185 | call umfpack_zi_defaults(control) | |
189 | 186 | |||
! Symbolic analysis | 190 | 187 | ! Symbolic analysis | |
call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 191 | 188 | call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
! info(1) should be zero | 192 | 189 | ! info(1) should be zero | |
if (info(1) /= 0) then | 193 | 190 | if (info(1) /= 0) then | |
write(*,*) "Problem during symbolic analysis" | 194 | 191 | write(*,*) "Problem during symbolic analysis" | |
status=info(1) | 195 | 192 | status=info(1) | |
endif | 196 | 193 | endif | |
197 | 194 | |||
! Numerical factorization | 198 | 195 | ! Numerical factorization | |
call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 199 | 196 | call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
! info(1) should be zero | 200 | 197 | ! info(1) should be zero | |
if (info(1) /= 0) then | 201 | 198 | if (info(1) /= 0) then | |
write(*,*) "Problem during numerical factorization" | 202 | 199 | write(*,*) "Problem during numerical factorization" | |
status=info(1) | 203 | 200 | status=info(1) | |
endif | 204 | 201 | endif | |
205 | 202 | |||
! free the C symbolic pointer | 206 | 203 | ! free the C symbolic pointer | |
call umfpack_zi_free_symbolic (symbolic) | 207 | 204 | call umfpack_zi_free_symbolic (symbolic) | |
208 | 205 | |||
! if parameter det is present, the determinant of the matrix is calculated | 209 | 206 | ! if parameter det is present, the determinant of the matrix is calculated | |
if (present(det) ) then | 210 | 207 | if (present(det) ) then | |
call umfpack_zi_get_determinant(Mx,Mz,Ex,numeric,info,status) | 211 | 208 | call umfpack_zi_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
det=cmplx(Mx,Mz,kind=dp_kind)*10**Ex | 212 | |||
! info(1) should be zero | 213 | 209 | ! info(1) should be zero | |
if (info(1) /= 0) then | 214 | 210 | if (info(1) /= 0) then | |
write(*,*) "Problem during sparse determinant, returned code : ",info(1) | 215 | 211 | write(*,*) "Problem during sparse determinant, returned code : ",info(1) | |
status=info(1) | 216 | 212 | status=info(1) | |
endif | 217 | 213 | endif | |
endif | 218 | 214 | endif | |
219 | 215 | |||
220 | 216 | |||
221 | 217 | |||
222 | 218 | |||
allocate(bx(n),bz(n),xx(n),xz(n)) | 223 | 219 | allocate(bx(n),bz(n),xx(n),xz(n)) | |
bx=dble(B) | 224 | 220 | bx=dble(B) | |
bz=aimag(B) | 225 | 221 | bz=aimag(B) | |
sys=0 | 226 | 222 | sys=0 | |
! sys may be used to define type of solving -> see umfpack.h | 227 | 223 | ! sys may be used to define type of solving -> see umfpack.h | |
228 | 224 | |||
! Solving | 229 | 225 | ! Solving | |
call umfpack_zi_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | 230 | 226 | call umfpack_zi_solve (sys, Ap, Ai, Ax,Az, xx,xz, bx,bz, numeric, control, info) | |
! info(1) should be zero | 231 | 227 | ! info(1) should be zero | |
if (info(1) /= 0) then | 232 | 228 | if (info(1) /= 0) then | |
write(*,*) "Problem during solving" | 233 | 229 | write(*,*) "Problem during solving" | |
status=info(1) | 234 | 230 | status=info(1) | |
endif | 235 | 231 | endif | |
236 | 232 | |||
! free the C numeric pointer | 237 | 233 | ! free the C numeric pointer | |
call umfpack_zi_free_numeric (numeric) | 238 | 234 | call umfpack_zi_free_numeric (numeric) | |
239 | 235 | |||
x=cmplx(xx,xz,dp_kind) | 240 | 236 | x=cmplx(xx,xz,dp_kind) | |
241 | 237 | |||
deallocate(bx,bz,xx,xz) | 242 | 238 | deallocate(bx,bz,xx,xz) | |
deallocate(Ax,Az) | 243 | 239 | deallocate(Ax,Az) | |
deallocate(Tx,Tz) | 244 | 240 | deallocate(Tx,Tz) | |
deallocate(wTi,wTj) | 245 | 241 | deallocate(wTi,wTj) | |
end subroutine | 246 | 242 | end subroutine | |
247 | 243 | |||
248 | 244 | |||
249 | 245 | |||
250 | 246 | |||
251 | 247 | |||
252 | 248 | |||
subroutine fvn_dl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | 253 | 249 | subroutine fvn_dl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
implicit none | 254 | 250 | implicit none | |
integer(kind=dp_kind), intent(in) :: n,nz | 255 | 251 | integer(kind=dp_kind), intent(in) :: n,nz | |
real(kind=dp_kind),dimension(nz),intent(in) :: T | 256 | 252 | real(kind=dp_kind),dimension(nz),intent(in) :: T | |
integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | 257 | 253 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | |
real(kind=dp_kind),dimension(n),intent(in) :: B | 258 | 254 | real(kind=dp_kind),dimension(n),intent(in) :: B | |
real(kind=dp_kind),dimension(n),intent(out) :: x | 259 | 255 | real(kind=dp_kind),dimension(n),intent(out) :: x | |
integer(kind=dp_kind), intent(out) :: status | 260 | 256 | integer(kind=dp_kind), intent(out) :: status | |
real(kind=dp_kind), optional, intent(out) :: det | 261 | 257 | real(kind=dp_kind), dimension(2), optional, intent(out) :: det | |
262 | 258 | |||
integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | 263 | 259 | integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
real(kind=dp_kind),dimension(:),allocatable :: A | 264 | 260 | real(kind=dp_kind),dimension(:),allocatable :: A | |
integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | 265 | 261 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | |
!integer(kind=dp_kind) :: symbolic,numeric | 266 | 262 | !integer(kind=dp_kind) :: symbolic,numeric | |
integer(kind=dp_kind) :: symbolic,numeric | 267 | 263 | integer(kind=dp_kind) :: symbolic,numeric | |
real(kind=dp_kind),dimension(90) :: info | 268 | 264 | real(kind=dp_kind),dimension(90) :: info | |
real(kind=dp_kind),dimension(20) :: control | 269 | 265 | real(kind=dp_kind),dimension(20) :: control | |
integer(kind=dp_kind) :: sys | 270 | 266 | integer(kind=dp_kind) :: sys | |
real(kind=dp_kind) :: Mx,Ex | 271 | |||
272 | 267 | |||
status=0 | 273 | 268 | status=0 | |
! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | 274 | 269 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
allocate(wTi(nz),wTj(nz)) | 275 | 270 | allocate(wTi(nz),wTj(nz)) | |
wTi=Ti-1 | 276 | 271 | wTi=Ti-1 | |
wTj=Tj-1 | 277 | 272 | wTj=Tj-1 | |
allocate(A(nz)) | 278 | 273 | allocate(A(nz)) | |
allocate(Ap(n+1),Ai(nz)) | 279 | 274 | allocate(Ap(n+1),Ai(nz)) | |
280 | 275 | |||
! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 281 | 276 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
call umfpack_dl_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | 282 | 277 | call umfpack_dl_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
! if status is not zero a problem has occured | 283 | 278 | ! if status is not zero a problem has occured | |
if (status /= 0) then | 284 | 279 | if (status /= 0) then | |
write(*,*) "Problem during umfpack_dl_triplet_to_col" | 285 | 280 | write(*,*) "Problem during umfpack_dl_triplet_to_col" | |
endif | 286 | 281 | endif | |
287 | 282 | |||
! Define defaults control values | 288 | 283 | ! Define defaults control values | |
call umfpack_dl_defaults(control) | 289 | 284 | call umfpack_dl_defaults(control) | |
290 | 285 | |||
! Symbolic analysis | 291 | 286 | ! Symbolic analysis | |
call umfpack_dl_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | 292 | 287 | call umfpack_dl_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | |
! info(1) should be zero | 293 | 288 | ! info(1) should be zero | |
if (info(1) /= 0) then | 294 | 289 | if (info(1) /= 0) then | |
write(*,*) "Problem during symbolic analysis" | 295 | 290 | write(*,*) "Problem during symbolic analysis" | |
status=info(1) | 296 | 291 | status=info(1) | |
endif | 297 | 292 | endif | |
298 | 293 | |||
! Numerical factorization | 299 | 294 | ! Numerical factorization | |
call umfpack_dl_numeric (Ap, Ai, A, symbolic, numeric, control, info) | 300 | 295 | call umfpack_dl_numeric (Ap, Ai, A, symbolic, numeric, control, info) | |
! info(1) should be zero | 301 | 296 | ! info(1) should be zero | |
if (info(1) /= 0) then | 302 | 297 | if (info(1) /= 0) then | |
write(*,*) "Problem during numerical factorization" | 303 | 298 | write(*,*) "Problem during numerical factorization" | |
status=info(1) | 304 | 299 | status=info(1) | |
endif | 305 | 300 | endif | |
306 | 301 | |||
! free the C symbolic pointer | 307 | 302 | ! free the C symbolic pointer | |
call umfpack_dl_free_symbolic (symbolic) | 308 | 303 | call umfpack_dl_free_symbolic (symbolic) | |
309 | 304 | |||
! if parameter det is present, the determinant of the matrix is calculated | 310 | 305 | ! if parameter det is present, the determinant of the matrix is calculated | |
if (present(det) ) then | 311 | 306 | if (present(det) ) then | |
call umfpack_dl_get_determinant(Mx,Ex,numeric,info,status) | 312 | 307 | call umfpack_dl_get_determinant(det(1),det(2),numeric,info,status) | |
det=Mx*10**Ex | 313 | |||
! info(1) should be zero | 314 | 308 | ! info(1) should be zero | |
if (info(1) /= 0) then | 315 | 309 | if (info(1) /= 0) then | |
write(*,*) "Problem during sparse determinant, returned code : ",info(1) | 316 | 310 | write(*,*) "Problem during sparse determinant, returned code : ",info(1) | |
status=info(1) | 317 | 311 | status=info(1) | |
endif | 318 | 312 | endif | |
endif | 319 | 313 | endif | |
320 | 314 | |||
321 | 315 | |||
sys=0 | 322 | 316 | sys=0 | |
! sys may be used to define type of solving -> see umfpack.h | 323 | 317 | ! sys may be used to define type of solving -> see umfpack.h | |
324 | 318 | |||
! Solving | 325 | 319 | ! Solving | |
call umfpack_dl_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | 326 | 320 | call umfpack_dl_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | |
! info(1) should be zero | 327 | 321 | ! info(1) should be zero | |
if (info(1) /= 0) then | 328 | 322 | if (info(1) /= 0) then | |
write(*,*) "Problem during solving" | 329 | 323 | write(*,*) "Problem during solving" | |
status=info(1) | 330 | 324 | status=info(1) | |
endif | 331 | 325 | endif | |
332 | 326 | |||
! free the C numeric pointer | 333 | 327 | ! free the C numeric pointer | |
call umfpack_dl_free_numeric (numeric) | 334 | 328 | call umfpack_dl_free_numeric (numeric) | |
335 | 329 | |||
deallocate(A) | 336 | 330 | deallocate(A) | |
deallocate(wTi,wTj) | 337 | 331 | deallocate(wTi,wTj) | |
end subroutine | 338 | 332 | end subroutine | |
339 | 333 | |||
340 | 334 | |||
341 | 335 | |||
342 | 336 | |||
343 | 337 | |||
344 | 338 | |||
subroutine fvn_di_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | 345 | 339 | subroutine fvn_di_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
implicit none | 346 | 340 | implicit none | |
integer(kind=sp_kind), intent(in) :: n,nz | 347 | 341 | integer(kind=sp_kind), intent(in) :: n,nz | |
real(kind=dp_kind),dimension(nz),intent(in) :: T | 348 | 342 | real(kind=dp_kind),dimension(nz),intent(in) :: T | |
integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | 349 | 343 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | |
real(kind=dp_kind),dimension(n),intent(in) :: B | 350 | 344 | real(kind=dp_kind),dimension(n),intent(in) :: B | |
real(kind=dp_kind),dimension(n),intent(out) :: x | 351 | 345 | real(kind=dp_kind),dimension(n),intent(out) :: x | |
integer(kind=sp_kind), intent(out) :: status | 352 | 346 | integer(kind=sp_kind), intent(out) :: status | |
real(kind=dp_kind), optional, intent(out) :: det | 353 | 347 | real(kind=dp_kind), dimension(2), optional, intent(out) :: det | |
354 | 348 | |||
integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | 355 | 349 | integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | |
real(kind=dp_kind),dimension(:),allocatable :: A | 356 | 350 | real(kind=dp_kind),dimension(:),allocatable :: A | |
integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | 357 | 351 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | |
!integer(kind=dp_kind) :: symbolic,numeric | 358 | 352 | !integer(kind=dp_kind) :: symbolic,numeric | |
integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 359 | 353 | integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
! As symbolic and numeric are used to store a C pointer, it is necessary to | 360 | 354 | ! As symbolic and numeric are used to store a C pointer, it is necessary to | |
! still use an integer(kind=dp_kind) for 64bits machines | 361 | 355 | ! still use an integer(kind=dp_kind) for 64bits machines | |
! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 362 | 356 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
real(kind=dp_kind),dimension(90) :: info | 363 | 357 | real(kind=dp_kind),dimension(90) :: info | |
real(kind=dp_kind),dimension(20) :: control | 364 | 358 | real(kind=dp_kind),dimension(20) :: control | |
integer(kind=sp_kind) :: sys | 365 | 359 | integer(kind=sp_kind) :: sys | |
real(kind=dp_kind) :: Mx,Ex | 366 | |||
367 | 360 | |||
status=0 | 368 | 361 | status=0 | |
! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | 369 | 362 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
allocate(wTi(nz),wTj(nz)) | 370 | 363 | allocate(wTi(nz),wTj(nz)) | |
wTi=Ti-1 | 371 | 364 | wTi=Ti-1 | |
wTj=Tj-1 | 372 | 365 | wTj=Tj-1 | |
allocate(A(nz)) | 373 | 366 | allocate(A(nz)) | |
allocate(Ap(n+1),Ai(nz)) | 374 | 367 | allocate(Ap(n+1),Ai(nz)) | |
375 | 368 | |||
! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 376 | 369 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
call umfpack_di_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | 377 | 370 | call umfpack_di_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
! if status is not zero a problem has occured | 378 | 371 | ! if status is not zero a problem has occured | |
if (status /= 0) then | 379 | 372 | if (status /= 0) then | |
write(*,*) "Problem during umfpack_di_triplet_to_col" | 380 | 373 | write(*,*) "Problem during umfpack_di_triplet_to_col" | |
endif | 381 | 374 | endif | |
382 | 375 | |||
! Define defaults control values | 383 | 376 | ! Define defaults control values | |
call umfpack_di_defaults(control) | 384 | 377 | call umfpack_di_defaults(control) | |
385 | 378 | |||
! Symbolic analysis | 386 | 379 | ! Symbolic analysis | |
call umfpack_di_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | 387 | 380 | call umfpack_di_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | |
! info(1) should be zero | 388 | 381 | ! info(1) should be zero | |
if (info(1) /= 0) then | 389 | 382 | if (info(1) /= 0) then | |
write(*,*) "Problem during symbolic analysis" | 390 | 383 | write(*,*) "Problem during symbolic analysis" | |
status=info(1) | 391 | 384 | status=info(1) | |
endif | 392 | 385 | endif | |
393 | 386 | |||
! Numerical factorization | 394 | 387 | ! Numerical factorization | |
call umfpack_di_numeric (Ap, Ai, A, symbolic, numeric, control, info) | 395 | 388 | call umfpack_di_numeric (Ap, Ai, A, symbolic, numeric, control, info) | |
! info(1) should be zero | 396 | 389 | ! info(1) should be zero | |
if (info(1) /= 0) then | 397 | 390 | if (info(1) /= 0) then | |
write(*,*) "Problem during numerical factorization" | 398 | 391 | write(*,*) "Problem during numerical factorization" | |
status=info(1) | 399 | 392 | status=info(1) | |
endif | 400 | 393 | endif | |
401 | 394 | |||
! free the C symbolic pointer | 402 | 395 | ! free the C symbolic pointer | |
call umfpack_di_free_symbolic (symbolic) | 403 | 396 | call umfpack_di_free_symbolic (symbolic) | |
404 | 397 | |||
! if parameter det is present, the determinant of the matrix is calculated | 405 | 398 | ! if parameter det is present, the determinant of the matrix is calculated | |
if (present(det) ) then | 406 | 399 | if (present(det) ) then | |
call umfpack_di_get_determinant(Mx,Ex,numeric,info,status) | 407 | 400 | call umfpack_di_get_determinant(det(1),det(2),numeric,info,status) | |
det=Mx*10**Ex | 408 | |||
! info(1) should be zero | 409 | 401 | ! info(1) should be zero | |
if (info(1) /= 0) then | 410 | 402 | if (info(1) /= 0) then | |
write(*,*) "Problem during sparse determinant, returned code : ",info(1) | 411 | 403 | write(*,*) "Problem during sparse determinant, returned code : ",info(1) | |
status=info(1) | 412 | 404 | status=info(1) | |
endif | 413 | 405 | endif | |
endif | 414 | 406 | endif | |
415 | 407 | |||
sys=0 | 416 | 408 | sys=0 | |
! sys may be used to define type of solving -> see umfpack.h | 417 | 409 | ! sys may be used to define type of solving -> see umfpack.h | |
! Solving | 418 | 410 | ! Solving | |
call umfpack_di_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | 419 | 411 | call umfpack_di_solve (sys, Ap, Ai, A, x, B, numeric, control, info) | |
! info(1) should be zero | 420 | 412 | ! info(1) should be zero | |
if (info(1) /= 0) then | 421 | 413 | if (info(1) /= 0) then | |
write(*,*) "Problem during solving" | 422 | 414 | write(*,*) "Problem during solving" | |
status=info(1) | 423 | 415 | status=info(1) | |
endif | 424 | 416 | endif | |
425 | 417 | |||
! free the C numeric pointer | 426 | 418 | ! free the C numeric pointer | |
call umfpack_di_free_numeric (numeric) | 427 | 419 | call umfpack_di_free_numeric (numeric) | |
428 | 420 | |||
deallocate(A) | 429 | 421 | deallocate(A) | |
deallocate(wTi,wTj) | 430 | 422 | deallocate(wTi,wTj) | |
end subroutine | 431 | 423 | end subroutine | |
432 | 424 | |||
433 | 425 | |||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 434 | 426 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
! | 435 | 427 | ! | |
! SPARSE DETERMINANT | 436 | 428 | ! SPARSE DETERMINANT | |
! | 437 | 429 | ! | |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 438 | 430 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
subroutine fvn_zl_sparse_det(n,nz,T,Ti,Tj,det,status) | 439 | 431 | subroutine fvn_zl_sparse_det(n,nz,T,Ti,Tj,det,status) | |
implicit none | 440 | 432 | implicit none | |
integer(kind=dp_kind), intent(in) :: n,nz | 441 | 433 | integer(kind=dp_kind), intent(in) :: n,nz | |
complex(kind=dp_kind),dimension(nz),intent(in) :: T | 442 | 434 | complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | 443 | 435 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | |
complex(kind=dp_kind),intent(out) :: det | 444 | 436 | real(kind=dp_kind), dimension(3), intent(out) :: det | |
integer(kind=dp_kind), intent(out) :: status | 445 | 437 | integer(kind=dp_kind), intent(out) :: status | |
446 | 438 | |||
integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | 447 | 439 | integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | 448 | 440 | real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 449 | 441 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | 450 | 442 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | |
integer(kind=dp_kind) :: symbolic,numeric | 451 | 443 | integer(kind=dp_kind) :: symbolic,numeric | |
real(kind=dp_kind),dimension(90) :: info | 452 | 444 | real(kind=dp_kind),dimension(90) :: info | |
real(kind=dp_kind),dimension(20) :: control | 453 | 445 | real(kind=dp_kind),dimension(20) :: control | |
real(kind=dp_kind) :: Mx,Mz,Ex | 454 | 446 | real(kind=dp_kind) :: Mx,Mz,Ex | |
455 | 447 | |||
456 | 448 | |||
status=0 | 457 | 449 | status=0 | |
458 | 450 | |||
! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | 459 | 451 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
! Tx and Tz are the real and imaginary parts of T | 460 | 452 | ! Tx and Tz are the real and imaginary parts of T | |
allocate(wTi(nz),wTj(nz)) | 461 | 453 | allocate(wTi(nz),wTj(nz)) | |
allocate(Tx(nz),Tz(nz)) | 462 | 454 | allocate(Tx(nz),Tz(nz)) | |
Tx=dble(T) | 463 | 455 | Tx=dble(T) | |
Tz=aimag(T) | 464 | 456 | Tz=aimag(T) | |
wTi=Ti-1 | 465 | 457 | wTi=Ti-1 | |
wTj=Tj-1 | 466 | 458 | wTj=Tj-1 | |
allocate(Ax(nz),Az(nz)) | 467 | 459 | allocate(Ax(nz),Az(nz)) | |
allocate(Ap(n+1),Ai(nz)) | 468 | 460 | allocate(Ap(n+1),Ai(nz)) | |
469 | 461 | |||
! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 470 | 462 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
call umfpack_zl_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | 471 | 463 | call umfpack_zl_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
! if status is not zero a problem has occured | 472 | 464 | ! if status is not zero a problem has occured | |
if (status /= 0) then | 473 | 465 | if (status /= 0) then | |
write(*,*) "Problem during umfpack_zl_triplet_to_col" | 474 | 466 | write(*,*) "Problem during umfpack_zl_triplet_to_col" | |
endif | 475 | 467 | endif | |
476 | 468 | |||
! Define defaults control values | 477 | 469 | ! Define defaults control values | |
call umfpack_zl_defaults(control) | 478 | 470 | call umfpack_zl_defaults(control) | |
479 | 471 | |||
! Symbolic analysis | 480 | 472 | ! Symbolic analysis | |
call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 481 | 473 | call umfpack_zl_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
! info(1) should be zero | 482 | 474 | ! info(1) should be zero | |
if (info(1) /= 0) then | 483 | 475 | if (info(1) /= 0) then | |
write(*,*) "Problem during symbolic analysis" | 484 | 476 | write(*,*) "Problem during symbolic analysis" | |
status=info(1) | 485 | 477 | status=info(1) | |
endif | 486 | 478 | endif | |
487 | 479 | |||
! Numerical factorization | 488 | 480 | ! Numerical factorization | |
call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 489 | 481 | call umfpack_zl_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
! info(1) should be zero | 490 | 482 | ! info(1) should be zero | |
if (info(1) /= 0) then | 491 | 483 | if (info(1) /= 0) then | |
write(*,*) "Problem during numerical factorization" | 492 | 484 | write(*,*) "Problem during numerical factorization" | |
status=info(1) | 493 | 485 | status=info(1) | |
endif | 494 | 486 | endif | |
495 | 487 | |||
! free the C symbolic pointer | 496 | 488 | ! free the C symbolic pointer | |
call umfpack_zl_free_symbolic (symbolic) | 497 | 489 | call umfpack_zl_free_symbolic (symbolic) | |
498 | 490 | |||
call umfpack_zl_get_determinant(Mx,Mz,Ex,numeric,info,status) | 499 | 491 | call umfpack_zl_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
! info(1) should be zero | 500 | 492 | ! info(1) should be zero | |
if (info(1) /= 0) then | 501 | 493 | if (info(1) /= 0) then | |
write(*,*) "Problem during sparse determinant, returned code : ",info(1) | 502 | 494 | write(*,*) "Problem during sparse determinant, returned code : ",info(1) | |
status=info(1) | 503 | 495 | status=info(1) | |
endif | 504 | 496 | endif | |
det=cmplx(Mx,Mz,kind=dp_kind)*10**Ex | 505 | |||
506 | 497 | |||
! free the C numeric pointer | 507 | 498 | ! free the C numeric pointer | |
call umfpack_zl_free_numeric (numeric) | 508 | 499 | call umfpack_zl_free_numeric (numeric) | |
509 | 500 | |||
deallocate(Ax,Az) | 510 | 501 | deallocate(Ax,Az) | |
deallocate(Tx,Tz) | 511 | 502 | deallocate(Tx,Tz) | |
deallocate(wTi,wTj) | 512 | 503 | deallocate(wTi,wTj) | |
end subroutine | 513 | 504 | end subroutine | |
514 | 505 | |||
515 | 506 | |||
subroutine fvn_zi_sparse_det(n,nz,T,Ti,Tj,det,status) | 516 | 507 | subroutine fvn_zi_sparse_det(n,nz,T,Ti,Tj,det,status) | |
implicit none | 517 | 508 | implicit none | |
integer(kind=sp_kind), intent(in) :: n,nz | 518 | 509 | integer(kind=sp_kind), intent(in) :: n,nz | |
complex(kind=dp_kind),dimension(nz),intent(in) :: T | 519 | 510 | complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | 520 | 511 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj | |
integer(kind=sp_kind), intent(out) :: status | 521 | 512 | integer(kind=sp_kind), intent(out) :: status | |
complex(kind=dp_kind), intent(out) :: det | 522 | 513 | real(kind=dp_kind), dimension(3), intent(out) :: det | |
523 | 514 | |||
integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | 524 | 515 | integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | |
real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | 525 | 516 | real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | 526 | 517 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az | |
integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | 527 | 518 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai | |
!integer(kind=dp_kind) :: symbolic,numeric | 528 | 519 | !integer(kind=dp_kind) :: symbolic,numeric | |
integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 529 | 520 | integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
! As symbolic and numeric are used to store a C pointer, it is necessary to | 530 | 521 | ! As symbolic and numeric are used to store a C pointer, it is necessary to | |
! still use an integer(kind=dp_kind) for 64bits machines | 531 | 522 | ! still use an integer(kind=dp_kind) for 64bits machines | |
! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | 532 | 523 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
real(kind=dp_kind),dimension(90) :: info | 533 | 524 | real(kind=dp_kind),dimension(90) :: info | |
real(kind=dp_kind),dimension(20) :: control | 534 | 525 | real(kind=dp_kind),dimension(20) :: control | |
real(kind=dp_kind) :: Mx,Mz,Ex | 535 | |||
536 | 526 | |||
status=0 | 537 | 527 | status=0 | |
! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | 538 | 528 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
! Tx and Tz are the real and imaginary parts of T | 539 | 529 | ! Tx and Tz are the real and imaginary parts of T | |
allocate(wTi(nz),wTj(nz)) | 540 | 530 | allocate(wTi(nz),wTj(nz)) | |
allocate(Tx(nz),Tz(nz)) | 541 | 531 | allocate(Tx(nz),Tz(nz)) | |
Tx=dble(T) | 542 | 532 | Tx=dble(T) | |
Tz=aimag(T) | 543 | 533 | Tz=aimag(T) | |
wTi=Ti-1 | 544 | 534 | wTi=Ti-1 | |
wTj=Tj-1 | 545 | 535 | wTj=Tj-1 | |
allocate(Ax(nz),Az(nz)) | 546 | 536 | allocate(Ax(nz),Az(nz)) | |
allocate(Ap(n+1),Ai(nz)) | 547 | 537 | allocate(Ap(n+1),Ai(nz)) | |
548 | 538 | |||
! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 549 | 539 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
call umfpack_zi_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | 550 | 540 | call umfpack_zi_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
! if status is not zero a problem has occured | 551 | 541 | ! if status is not zero a problem has occured | |
if (status /= 0) then | 552 | 542 | if (status /= 0) then | |
write(*,*) "Problem during umfpack_zl_triplet_to_col" | 553 | 543 | write(*,*) "Problem during umfpack_zl_triplet_to_col" | |
endif | 554 | 544 | endif | |
555 | 545 | |||
! Define defaults control values | 556 | 546 | ! Define defaults control values | |
call umfpack_zi_defaults(control) | 557 | 547 | call umfpack_zi_defaults(control) | |
558 | 548 | |||
! Symbolic analysis | 559 | 549 | ! Symbolic analysis | |
call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | 560 | 550 | call umfpack_zi_symbolic(n,n,Ap,Ai,Ax,Az,symbolic, control, info) | |
! info(1) should be zero | 561 | 551 | ! info(1) should be zero | |
if (info(1) /= 0) then | 562 | 552 | if (info(1) /= 0) then | |
write(*,*) "Problem during symbolic analysis" | 563 | 553 | write(*,*) "Problem during symbolic analysis" | |
status=info(1) | 564 | 554 | status=info(1) | |
endif | 565 | 555 | endif | |
566 | 556 | |||
! Numerical factorization | 567 | 557 | ! Numerical factorization | |
call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | 568 | 558 | call umfpack_zi_numeric (Ap, Ai, Ax, Az, symbolic, numeric, control, info) | |
! info(1) should be zero | 569 | 559 | ! info(1) should be zero | |
if (info(1) /= 0) then | 570 | 560 | if (info(1) /= 0) then | |
write(*,*) "Problem during numerical factorization" | 571 | 561 | write(*,*) "Problem during numerical factorization" | |
status=info(1) | 572 | 562 | status=info(1) | |
endif | 573 | 563 | endif | |
574 | 564 | |||
! free the C symbolic pointer | 575 | 565 | ! free the C symbolic pointer | |
call umfpack_zi_free_symbolic (symbolic) | 576 | 566 | call umfpack_zi_free_symbolic (symbolic) | |
577 | 567 | |||
call umfpack_zi_get_determinant(Mx,Mz,Ex,numeric,info,status) | 578 | 568 | call umfpack_zi_get_determinant(det(1),det(2),det(3),numeric,info,status) | |
! info(1) should be zero | 579 | 569 | ! info(1) should be zero | |
if (info(1) /= 0) then | 580 | 570 | if (info(1) /= 0) then | |
write(*,*) "Problem during sparse determinant, returned code : ",info(1) | 581 | 571 | write(*,*) "Problem during sparse determinant, returned code : ",info(1) | |
status=info(1) | 582 | 572 | status=info(1) | |
endif | 583 | 573 | endif | |
det=cmplx(Mx,Mz,kind=dp_kind)*10**Ex | 584 | |||
585 | 574 | |||
! free the C numeric pointer | 586 | 575 | ! free the C numeric pointer | |
call umfpack_zi_free_numeric (numeric) | 587 | 576 | call umfpack_zi_free_numeric (numeric) | |
588 | 577 | |||
deallocate(Ax,Az) | 589 | 578 | deallocate(Ax,Az) | |
deallocate(Tx,Tz) | 590 | 579 | deallocate(Tx,Tz) | |
deallocate(wTi,wTj) | 591 | 580 | deallocate(wTi,wTj) | |
end subroutine | 592 | 581 | end subroutine | |
593 | 582 | |||
subroutine fvn_dl_sparse_det(n,nz,T,Ti,Tj,det,status) | 594 | 583 | subroutine fvn_dl_sparse_det(n,nz,T,Ti,Tj,det,status) | |
implicit none | 595 | 584 | implicit none | |
integer(kind=dp_kind), intent(in) :: n,nz | 596 | 585 | integer(kind=dp_kind), intent(in) :: n,nz | |
real(kind=dp_kind),dimension(nz),intent(in) :: T | 597 | 586 | real(kind=dp_kind),dimension(nz),intent(in) :: T | |
integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | 598 | 587 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj | |
integer(kind=dp_kind), intent(out) :: status | 599 | 588 | integer(kind=dp_kind), intent(out) :: status | |
real(kind=dp_kind), intent(out) :: det | 600 | 589 | real(kind=dp_kind), dimension(2), intent(out) :: det | |
601 | 590 | |||
integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | 602 | 591 | integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
real(kind=dp_kind),dimension(:),allocatable :: A | 603 | 592 | real(kind=dp_kind),dimension(:),allocatable :: A | |
integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | 604 | 593 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai | |
!integer(kind=dp_kind) :: symbolic,numeric | 605 | 594 | !integer(kind=dp_kind) :: symbolic,numeric | |
integer(kind=dp_kind) :: symbolic,numeric | 606 | 595 | integer(kind=dp_kind) :: symbolic,numeric | |
real(kind=dp_kind),dimension(90) :: info | 607 | 596 | real(kind=dp_kind),dimension(90) :: info | |
real(kind=dp_kind),dimension(20) :: control | 608 | 597 | real(kind=dp_kind),dimension(20) :: control | |
real(kind=dp_kind) :: Mx,Ex | 609 | |||
610 | 598 | |||
status=0 | 611 | 599 | status=0 | |
! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | 612 | 600 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
allocate(wTi(nz),wTj(nz)) | 613 | 601 | allocate(wTi(nz),wTj(nz)) | |
wTi=Ti-1 | 614 | 602 | wTi=Ti-1 | |
wTj=Tj-1 | 615 | 603 | wTj=Tj-1 | |
allocate(A(nz)) | 616 | 604 | allocate(A(nz)) | |
allocate(Ap(n+1),Ai(nz)) | 617 | 605 | allocate(Ap(n+1),Ai(nz)) | |
618 | 606 | |||
! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | 619 | 607 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
call umfpack_dl_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | 620 | 608 | call umfpack_dl_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
! if status is not zero a problem has occured | 621 | 609 | ! if status is not zero a problem has occured | |
if (status /= 0) then | 622 | 610 | if (status /= 0) then | |
write(*,*) "Problem during umfpack_dl_triplet_to_col" | 623 | 611 | write(*,*) "Problem during umfpack_dl_triplet_to_col" | |
endif | 624 | 612 | endif | |
625 | 613 | |||
! Define defaults control values | 626 | 614 | ! Define defaults control values |
fvn_test/test_sparse_di.f90
program test_sparse | 1 | 1 | program test_sparse | |
! test sparse routine di, real(8) and integer(4) | 2 | 2 | ! test sparse routine di, real(8) and integer(4) | |
use fvn | 3 | 3 | use fvn | |
implicit none | 4 | 4 | implicit none | |
integer(kind=sp_kind), parameter :: nz=12 | 5 | 5 | integer(kind=sp_kind), parameter :: nz=12 | |
integer(kind=sp_kind), parameter :: n=5 | 6 | 6 | integer(kind=sp_kind), parameter :: n=5 | |
real(kind=dp_kind),dimension(nz) :: A | 7 | 7 | real(kind=dp_kind),dimension(nz) :: A | |
real(kind=dp_kind),dimension(n,n) :: As | 8 | 8 | real(kind=dp_kind),dimension(n,n) :: As | |
integer(kind=sp_kind),dimension(nz) :: Ti,Tj | 9 | 9 | integer(kind=sp_kind),dimension(nz) :: Ti,Tj | |
real(kind=dp_kind),dimension(n) :: B,x | 10 | 10 | real(kind=dp_kind),dimension(n) :: B,x | |
integer(kind=sp_kind) :: status,i | 11 | 11 | integer(kind=sp_kind) :: status,i | |
real(kind=dp_kind) :: det | 12 | 12 | real(kind=dp_kind),dimension(2) :: det | |
! Description of the matrix in triplet form | 13 | 13 | ! Description of the matrix in triplet form | |
A = (/ 2.,3.,3.,-1.,4.,4.,-3.,1.,2.,2.,6.,1. /) | 14 | 14 | A = (/ 2.,3.,3.,-1.,4.,4.,-3.,1.,2.,2.,6.,1. /) | |
B = (/ 8., 45., -3., 3., 19./) | 15 | 15 | B = (/ 8., 45., -3., 3., 19./) | |
Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | 16 | 16 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | |
Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | 17 | 17 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | |
18 | 18 | |||
! Reconstruction of the matrix in standard form | 19 | 19 | ! Reconstruction of the matrix in standard form | |
! just needed for printing the matrix here | 20 | 20 | ! just needed for printing the matrix here | |
As=0. | 21 | 21 | As=0. | |
do i=1,nz | 22 | 22 | do i=1,nz | |
As(Ti(i),Tj(i))=A(i) | 23 | 23 | As(Ti(i),Tj(i))=A(i) | |
end do | 24 | 24 | end do | |
write(*,*) "Matrix in standard representation :" | 25 | 25 | write(*,*) "Matrix in standard representation :" | |
do i=1,5 | 26 | 26 | do i=1,5 | |
write(*,'(5f8.4)') As(i,:) | 27 | 27 | write(*,'(5f8.4)') As(i,:) | |
end do | 28 | 28 | end do | |
write(*,*) | 29 | 29 | write(*,*) | |
write(*,*) "Standard determinant =", fvn_det(5,As) | 30 | 30 | write(*,*) "Standard determinant =", fvn_det(5,As) | |
write(*,*) | 31 | 31 | write(*,*) | |
write(*,'("Right hand side :",5f8.4)') B | 32 | 32 | write(*,'("Right hand side :",5f8.4)') B | |
33 | 33 | |||
! can use either specific interface, fvn_di_sparse_det | 34 | 34 | ! can use either specific interface, fvn_di_sparse_det | |
! either generic one fvn_sparse_det | 35 | 35 | ! either generic one fvn_sparse_det | |
call fvn_di_sparse_det(n,nz,A,Ti,Tj,det,status) | 36 | 36 | call fvn_di_sparse_det(n,nz,A,Ti,Tj,det,status) | |
write(*,*) | 37 | 37 | write(*,*) | |
write(*,*) "Sparse Det = ",det | 38 | 38 | write(*,*) "Sparse Det = ",det(1)*10**det(2) | |
! can use either specific interface fvn_di_sparse_solve | 39 | 39 | ! can use either specific interface fvn_di_sparse_solve | |
! either generic one fvn_sparse_solve | 40 | 40 | ! either generic one fvn_sparse_solve | |
! parameter det is optional | 41 | 41 | ! parameter det is optional | |
call fvn_di_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | 42 | 42 | call fvn_di_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | |
write(*,*) | 43 | 43 | write(*,*) | |
write(*,*) "Sparse Det as solve option = ",det | 44 | 44 | write(*,*) "Sparse Det as solve option = ",det(1)*10**det(2) | |
write(*,*) | 45 | 45 | write(*,*) | |
write(*,'("Solution :",5f8.4)') x | 46 | 46 | write(*,'("Solution :",5f8.4)') x | |
write(*,*) | 47 | 47 | write(*,*) | |
write(*,'("Product matrix Solution :",5f8.4)') matmul(As,x) | 48 | 48 | write(*,'("Product matrix Solution :",5f8.4)') matmul(As,x) | |
end program | 49 | 49 | end program | |
50 | 50 |
fvn_test/test_sparse_dl.f90
program test_sparse | 1 | 1 | program test_sparse | |
! test sparse routine dl, real(8) and integer(8) | 2 | 2 | ! test sparse routine dl, real(8) and integer(8) | |
use fvn | 3 | 3 | use fvn | |
implicit none | 4 | 4 | implicit none | |
integer(kind=dp_kind), parameter :: nz=12 | 5 | 5 | integer(kind=dp_kind), parameter :: nz=12 | |
integer(kind=dp_kind), parameter :: n=5 | 6 | 6 | integer(kind=dp_kind), parameter :: n=5 | |
real(kind=dp_kind),dimension(nz) :: A | 7 | 7 | real(kind=dp_kind),dimension(nz) :: A | |
real(kind=dp_kind),dimension(n,n) :: As | 8 | 8 | real(kind=dp_kind),dimension(n,n) :: As | |
integer(kind=dp_kind),dimension(nz) :: Ti,Tj | 9 | 9 | integer(kind=dp_kind),dimension(nz) :: Ti,Tj | |
real(kind=dp_kind),dimension(n) :: B,x | 10 | 10 | real(kind=dp_kind),dimension(n) :: B,x | |
integer(kind=dp_kind) :: status,i | 11 | 11 | integer(kind=dp_kind) :: status,i | |
real(kind=dp_kind) :: det | 12 | 12 | real(kind=dp_kind),dimension(2) :: det | |
! Description of the matrix in triplet form | 13 | 13 | ! Description of the matrix in triplet form | |
A = (/ 2.,3.,3.,-1.,4.,4.,-3.,1.,2.,2.,6.,1. /) | 14 | 14 | A = (/ 2.,3.,3.,-1.,4.,4.,-3.,1.,2.,2.,6.,1. /) | |
B = (/ 8., 45., -3., 3., 19./) | 15 | 15 | B = (/ 8., 45., -3., 3., 19./) | |
Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | 16 | 16 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | |
Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | 17 | 17 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | |
18 | 18 | |||
! Reconstruction of the matrix in standard form | 19 | 19 | ! Reconstruction of the matrix in standard form | |
! just needed for printing the matrix here | 20 | 20 | ! just needed for printing the matrix here | |
As=0. | 21 | 21 | As=0. | |
do i=1,nz | 22 | 22 | do i=1,nz | |
As(Ti(i),Tj(i))=A(i) | 23 | 23 | As(Ti(i),Tj(i))=A(i) | |
end do | 24 | 24 | end do | |
write(*,*) "Matrix in standard representation :" | 25 | 25 | write(*,*) "Matrix in standard representation :" | |
do i=1,5 | 26 | 26 | do i=1,5 | |
write(*,'(5f8.4)') As(i,:) | 27 | 27 | write(*,'(5f8.4)') As(i,:) | |
end do | 28 | 28 | end do | |
write(*,*) | 29 | 29 | write(*,*) | |
write(*,*) "Standard determinant =", fvn_det(5,As) | 30 | 30 | write(*,*) "Standard determinant =", fvn_det(5,As) | |
write(*,*) | 31 | 31 | write(*,*) | |
write(*,'("Right hand side :",5f8.4)') B | 32 | 32 | write(*,'("Right hand side :",5f8.4)') B | |
33 | 33 | |||
! can use either specific interface, fvn_dl_sparse_det | 34 | 34 | ! can use either specific interface, fvn_dl_sparse_det | |
! either generic one fvn_sparse_det | 35 | 35 | ! either generic one fvn_sparse_det | |
call fvn_dl_sparse_det(n,nz,A,Ti,Tj,det,status) | 36 | 36 | call fvn_dl_sparse_det(n,nz,A,Ti,Tj,det,status) | |
write(*,*) | 37 | 37 | write(*,*) | |
write(*,*) "Sparse Det = ",det | 38 | 38 | write(*,*) "Sparse Det = ",det(1)*10**det(2) | |
! can use either specific interface fvn_dl_sparse_solve | 39 | 39 | ! can use either specific interface fvn_dl_sparse_solve | |
! either generic one fvn_sparse_solve | 40 | 40 | ! either generic one fvn_sparse_solve | |
! parameter det is optional | 41 | 41 | ! parameter det is optional | |
call fvn_dl_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | 42 | 42 | call fvn_dl_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | |
write(*,*) | 43 | 43 | write(*,*) | |
write(*,*) "Sparse Det as solve option = ",det | 44 | 44 | write(*,*) "Sparse Det as solve option = ",det(1)*10**det(2) | |
write(*,*) | 45 | 45 | write(*,*) | |
write(*,'("Solution :",5f8.4)') x | 46 | 46 | write(*,'("Solution :",5f8.4)') x | |
write(*,*) | 47 | 47 | write(*,*) | |
write(*,'("Product matrix Solution :",5f8.4)') matmul(As,x) | 48 | 48 | write(*,'("Product matrix Solution :",5f8.4)') matmul(As,x) | |
end program | 49 | 49 | end program | |
50 | 50 |
fvn_test/test_sparse_zi.f90
program test_sparse | 1 | 1 | program test_sparse | |
use fvn | 2 | 2 | use fvn | |
implicit none | 3 | 3 | implicit none | |
integer(kind=sp_kind), parameter :: nz=12 | 4 | 4 | integer(kind=sp_kind), parameter :: nz=12 | |
integer(kind=sp_kind), parameter :: n=5 | 5 | 5 | integer(kind=sp_kind), parameter :: n=5 | |
complex(kind=dp_kind),dimension(nz) :: A | 6 | 6 | complex(kind=dp_kind),dimension(nz) :: A | |
complex(kind=dp_kind),dimension(n,n) :: As | 7 | 7 | complex(kind=dp_kind),dimension(n,n) :: As | |
integer(kind=sp_kind),dimension(nz) :: Ti,Tj | 8 | 8 | integer(kind=sp_kind),dimension(nz) :: Ti,Tj | |
complex(kind=dp_kind),dimension(n) :: B,x | 9 | 9 | complex(kind=dp_kind),dimension(n) :: B,x | |
integer(kind=sp_kind) :: status,i | 10 | 10 | integer(kind=sp_kind) :: status,i | |
complex(kind=dp_kind) :: det | 11 | 11 | real(kind=dp_kind),dimension(3) :: det | |
character(len=80) :: fmcmplx | 12 | 12 | character(len=80) :: fmcmplx | |
13 | 13 | |||
fmcmplx='(5("(",f8.5,",",f8.5,") "))' | 14 | 14 | fmcmplx='(5("(",f8.5,",",f8.5,") "))' | |
15 | 15 | |||
! Description of the matrix in triplet form | 16 | 16 | ! Description of the matrix in triplet form | |
A = (/ (2.,-1.),(3.,2.),(3.,1.),(-1.,5.),(4.,-7.),(4.,0.),(-3.,-4.),(1.,3.),(2.,0.),(2.,-2.),(6.,4.),(1.,0.) /) | 17 | 17 | A = (/ (2.,-1.),(3.,2.),(3.,1.),(-1.,5.),(4.,-7.),(4.,0.),(-3.,-4.),(1.,3.),(2.,0.),(2.,-2.),(6.,4.),(1.,0.) /) | |
B = (/ (8.,3.), (45.,1.), (-3.,-2.), (3.,0.), (19.,2.) /) | 18 | 18 | B = (/ (8.,3.), (45.,1.), (-3.,-2.), (3.,0.), (19.,2.) /) | |
Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | 19 | 19 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | |
Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | 20 | 20 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | |
21 | 21 | |||
! Reconstruction of the matrix in standard form | 22 | 22 | ! Reconstruction of the matrix in standard form | |
As=0. | 23 | 23 | As=0. | |
do i=1,nz | 24 | 24 | do i=1,nz | |
As(Ti(i),Tj(i))=A(i) | 25 | 25 | As(Ti(i),Tj(i))=A(i) | |
end do | 26 | 26 | end do | |
27 | 27 | |||
write(*,*) "Matrix in standard representation :" | 28 | 28 | write(*,*) "Matrix in standard representation :" | |
do i=1,5 | 29 | 29 | do i=1,5 | |
write(*,fmcmplx) As(i,:) | 30 | 30 | write(*,fmcmplx) As(i,:) | |
end do | 31 | 31 | end do | |
write(*,*) | 32 | 32 | write(*,*) | |
write(*,*) "Standard determinant : ",fvn_det(5,As) | 33 | 33 | write(*,*) "Standard determinant : ",fvn_det(5,As) | |
write(*,*) | 34 | 34 | write(*,*) | |
write(*,*) "Right hand side :" | 35 | 35 | write(*,*) "Right hand side :" | |
write(*,fmcmplx) B | 36 | 36 | write(*,fmcmplx) B | |
37 | 37 | |||
! can use either specific interface, fvn_zi_sparse_det | 38 | 38 | ! can use either specific interface, fvn_zi_sparse_det | |
! either generic one fvn_sparse_det | 39 | 39 | ! either generic one fvn_sparse_det | |
call fvn_zi_sparse_det(n,nz,A,Ti,Tj,det,status) | 40 | 40 | call fvn_zi_sparse_det(n,nz,A,Ti,Tj,det,status) | |
write(*,*) | 41 | 41 | write(*,*) | |
write(*,*) "Sparse Det = ",det | 42 | 42 | write(*,*) "Sparse Det = ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) | |
! can use either specific interface fvn_zi_sparse_solve | 43 | 43 | ! can use either specific interface fvn_zi_sparse_solve | |
! either generic one fvn_sparse_solve | 44 | 44 | ! either generic one fvn_sparse_solve | |
! parameter det is optional | 45 | 45 | ! parameter det is optional | |
call fvn_zi_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | 46 | 46 | call fvn_zi_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | |
write(*,*) | 47 | 47 | write(*,*) | |
write(*,*) "Sparse Det as solve option= ",det | 48 | 48 | write(*,*) "Sparse Det as solve option= ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) | |
write(*,*) | 49 | 49 | write(*,*) | |
write(*,*) "Solution :" | 50 | 50 | write(*,*) "Solution :" | |
write(*,fmcmplx) x | 51 | 51 | write(*,fmcmplx) x | |
write(*,*) | 52 | 52 | write(*,*) | |
write(*,*) "Product matrix Solution :" | 53 | 53 | write(*,*) "Product matrix Solution :" |
fvn_test/test_sparse_zl.f90
program test_sparse | 1 | 1 | program test_sparse | |
! test sparse routine zl, complex(8) and integer(8) | 2 | 2 | ! test sparse routine zl, complex(8) and integer(8) | |
use fvn | 3 | 3 | use fvn | |
implicit none | 4 | 4 | implicit none | |
integer(kind=dp_kind), parameter :: nz=12 | 5 | 5 | integer(kind=dp_kind), parameter :: nz=12 | |
integer(kind=dp_kind), parameter :: n=5 | 6 | 6 | integer(kind=dp_kind), parameter :: n=5 | |
complex(kind=dp_kind),dimension(nz) :: A | 7 | 7 | complex(kind=dp_kind),dimension(nz) :: A | |
complex(kind=dp_kind),dimension(n,n) :: As | 8 | 8 | complex(kind=dp_kind),dimension(n,n) :: As | |
integer(kind=dp_kind),dimension(nz) :: Ti,Tj | 9 | 9 | integer(kind=dp_kind),dimension(nz) :: Ti,Tj | |
complex(kind=dp_kind),dimension(n) :: B,x | 10 | 10 | complex(kind=dp_kind),dimension(n) :: B,x | |
integer(kind=dp_kind) :: status,i | 11 | 11 | integer(kind=dp_kind) :: status,i | |
complex(kind=dp_kind) :: det | 12 | 12 | real(kind=dp_kind),dimension(3) :: det | |
character(len=80) :: fmcmplx | 13 | 13 | character(len=80) :: fmcmplx | |
14 | 14 | |||
fmcmplx='(5("(",f8.5,",",f8.5,") "))' | 15 | 15 | fmcmplx='(5("(",f8.5,",",f8.5,") "))' | |
16 | 16 | |||
! Description of the matrix in triplet form | 17 | 17 | ! Description of the matrix in triplet form | |
A = (/ (2.,-1.),(3.,2.),(3.,1.),(-1.,5.),(4.,-7.),(4.,0.),(-3.,-4.),(1.,3.),(2.,0.),(2.,-2.),(6.,4.),(1.,0.) /) | 18 | 18 | A = (/ (2.,-1.),(3.,2.),(3.,1.),(-1.,5.),(4.,-7.),(4.,0.),(-3.,-4.),(1.,3.),(2.,0.),(2.,-2.),(6.,4.),(1.,0.) /) | |
B = (/ (8.,3.), (45.,1.), (-3.,-2.), (3.,0.), (19.,2.) /) | 19 | 19 | B = (/ (8.,3.), (45.,1.), (-3.,-2.), (3.,0.), (19.,2.) /) | |
Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | 20 | 20 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | |
Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | 21 | 21 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | |
22 | 22 | |||
! Reconstruction of the matrix in standard form | 23 | 23 | ! Reconstruction of the matrix in standard form | |
As=0. | 24 | 24 | As=0. | |
do i=1,nz | 25 | 25 | do i=1,nz | |
As(Ti(i),Tj(i))=A(i) | 26 | 26 | As(Ti(i),Tj(i))=A(i) | |
end do | 27 | 27 | end do | |
28 | 28 | |||
write(*,*) "Matrix in standard representation :" | 29 | 29 | write(*,*) "Matrix in standard representation :" | |
do i=1,5 | 30 | 30 | do i=1,5 | |
write(*,fmcmplx) As(i,:) | 31 | 31 | write(*,fmcmplx) As(i,:) | |
end do | 32 | 32 | end do | |
write(*,*) | 33 | 33 | write(*,*) | |
write(*,*) "Standard determinant : ",fvn_det(5,As) | 34 | 34 | write(*,*) "Standard determinant : ",fvn_det(5,As) | |
write(*,*) | 35 | 35 | write(*,*) | |
write(*,*) "Right hand side :" | 36 | 36 | write(*,*) "Right hand side :" | |
write(*,fmcmplx) B | 37 | 37 | write(*,fmcmplx) B | |
! can use either specific interface, fvn_zl_sparse_det | 38 | 38 | ! can use either specific interface, fvn_zl_sparse_det | |
! either generic one fvn_sparse_det | 39 | 39 | ! either generic one fvn_sparse_det | |
call fvn_zl_sparse_det(n,nz,A,Ti,Tj,det,status) | 40 | 40 | call fvn_zl_sparse_det(n,nz,A,Ti,Tj,det,status) | |
write(*,*) | 41 | 41 | write(*,*) | |
write(*,*) "Sparse Det = ",det | 42 | 42 | write(*,*) "Sparse Det = ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) | |
! can use either specific interface fvn_zl_sparse_solve | 43 | 43 | ! can use either specific interface fvn_zl_sparse_solve | |
! either generic one fvn_sparse_solve | 44 | 44 | ! either generic one fvn_sparse_solve | |
! parameter det is optional | 45 | 45 | ! parameter det is optional | |
call fvn_zl_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | 46 | 46 | call fvn_zl_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | |
write(*,*) | 47 | 47 | write(*,*) | |
write(*,*) "Sparse Det as solve option= ",det | 48 | 48 | write(*,*) "Sparse Det as solve option= ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) | |
write(*,*) | 49 | 49 | write(*,*) | |
write(*,*) "Solution :" | 50 | 50 | write(*,*) "Solution :" | |
write(*,fmcmplx) x | 51 | 51 | write(*,fmcmplx) x | |
write(*,*) | 52 | 52 | write(*,*) | |
write(*,*) "Product matrix Solution :" | 53 | 53 | write(*,*) "Product matrix Solution :" | |
write(*,fmcmplx) matmul(As,x) | 54 | 54 | write(*,fmcmplx) matmul(As,x) |