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