Commit 4bd2122857ff6d0fa38dcdb157799912272ea76c
1 parent
7dc628d158
Exists in
master
and in
2 other branches
Changed sparse routine interface to avoid duplicating datas in the routines,
which causes problems with larges systems. 1) Complex inputs must be splitted into 2 arrays : real and imaginary parts 2) Ti and Tj must now be 0-based git-svn-id: https://lxsd.femto-st.fr/svn/fvn@75 b657c933-2333-4658-acf2-d3c7c2708721
Showing 7 changed files with 2189 additions and 2218 deletions Side-by-side Diff
doc/fvn.pdf
No preview for this file type
doc/fvn.tex
... | ... | @@ -283,17 +283,20 @@ |
283 | 283 | \subsubsection{Sparse solving} |
284 | 284 | The provided routines solves the equation $Ax=B$ where A is sparse and given in its triplet form. |
285 | 285 | |
286 | +Note that interface has changed from previous versions, splitting complex inputs into real and imaginary part and using 0-based indices, to fit umfpack routines inputs and avoid duplicating datas inside the routines. | |
287 | + | |
286 | 288 | \begin{verbatim} |
287 | 289 | Module : fvn_sparse |
288 | 290 | call fvn_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) |
291 | +call fvn_sparse_solve(n,nz,Tx,Tz,Ti,Tj,Bx,Bz,x,status,det) | |
289 | 292 | \end{verbatim} |
290 | 293 | \begin{itemize} |
291 | 294 | \item For this family of subroutines the two letters (zl,zi,dl,di) of the specific interface name decribe the arguments's type. z is for complex(8), d for real(8), l for integer(8) and i for integer(4) |
292 | 295 | \item \texttt{n} (in) is an integer equal to the matrix rank |
293 | 296 | \item \texttt{nz} (in) is an integer equal to the number of non-zero elements |
294 | - \item \texttt{T(nz)} (in) is a complex/real array containing the non-zero elements | |
295 | - \item \textt{Ti(nz)},\texttt{Tj(nz)} (in) are the indexes of the corresponding element of \texttt{T} in the original matrix. | |
296 | - \item \texttt{B(n)} (in) is a complex/real array containing the second member of the equation. | |
297 | + \item \texttt{T(nz) or Tx(nz),Tz(nz)} (in) is a real array (or two real arrays for real/imaginary in case of a complex system) containing the non-zero elements | |
298 | + \item \textt{Ti(nz)},\texttt{Tj(nz)} (in) are the indexes of the corresponding element of \texttt{T} in the original matrix, this has to be 0-based as in C. | |
299 | + \item \texttt{B(n) or Bx(n),Bz(n)} (in) is a real array or two real arrays for real/imaginary in case of a complex system) containing the second member of the equation. | |
297 | 300 | \item \texttt{x(n)} (out) is a complex/real array containing the solution |
298 | 301 | \item \texttt{status} (out) is an integer which contain non-zero is something went wrong |
299 | 302 | \item \texttt{det} (out), is an optional real(8) array of dimension 2 for dl and di specific interface (real systems) and dimension 3 for zl and zi interface (complex systems) |
300 | 303 | |
... | ... | @@ -310,8 +313,10 @@ |
310 | 313 | integer(8), parameter :: nz=12 |
311 | 314 | integer(8), parameter :: n=5 |
312 | 315 | complex(8),dimension(nz) :: A |
316 | + real(8), dimension(nz) :: Ax,Az | |
313 | 317 | integer(8),dimension(nz) :: Ti,Tj |
314 | 318 | complex(8),dimension(n) :: B,x |
319 | + real(8), dimension(n) :: Bx,Bz | |
315 | 320 | integer(8) :: status |
316 | 321 | |
317 | 322 | A = (/ (2.,0.),(3.,0.),(3.,0.),(-1.,0.),(4.,0.),(4.,0.),(-3.,0.),& |
318 | 323 | |
319 | 324 | |
... | ... | @@ -319,10 +324,18 @@ |
319 | 324 | B = (/ (8.,0.), (45.,0.), (-3.,0.), (3.,0.), (19.,0.)/) |
320 | 325 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) |
321 | 326 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) |
327 | + Ax=real(A) | |
328 | + Az=aimag(A) | |
329 | + Bx=real(B) | |
330 | + Bz=aimag(B) | |
322 | 331 | |
332 | + ! 1-based to 0-based translation | |
333 | + Ti=Ti-1 | |
334 | + Tj=Tj-1 | |
335 | + | |
323 | 336 | !specific routine that will be used here |
324 | - !call fvn_zl_sparse_solve(n,nz,A,Ti,Tj,B,x,status) | |
325 | - call fvn_sparse_solve(n,nz,A,Ti,Tj,B,x,status) | |
337 | + !call fvn_zl_sparse_solve(n,nz,Ax,Az,Ti,Tj,Bx,Bz,x,status) | |
338 | + call fvn_sparse_solve(n,nz,Ax,Az,Ti,Tj,Bx,Bz,x,status) | |
326 | 339 | write(*,*) x |
327 | 340 | |
328 | 341 | end program |
... | ... | @@ -345,6 +358,10 @@ |
345 | 358 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) |
346 | 359 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) |
347 | 360 | |
361 | +! 1-based to 0-based translation | |
362 | +Ti=Ti-1 | |
363 | +Tj=Tj-1 | |
364 | + | |
348 | 365 | !specific routine that will be used here |
349 | 366 | !call fvn_di_sparse_solve(n,nz,A,Ti,Tj,B,x,status) |
350 | 367 | call fvn_sparse_solve(n,nz,A,Ti,Tj,B,x,status) |
351 | 368 | |
... | ... | @@ -362,14 +379,15 @@ |
362 | 379 | \begin{verbatim} |
363 | 380 | Module : fvn_sparse |
364 | 381 | call fvn_sparse_det(n,nz,T,Ti,Tj,det,status) |
382 | +call fvn_sparse_det(n,nz,Tx,Tz,Ti,Tj,det,status) | |
365 | 383 | \end{verbatim} |
366 | 384 | |
367 | 385 | \begin{itemize} |
368 | 386 | \item For this family of subroutines the two letters (zl,zi,dl,di) of the specific interface name decribe the arguments's type. z is for complex(8), d for real(8), l for integer(8) and i for integer(4) |
369 | 387 | \item \texttt{n} (in) is an integer equal to the matrix rank |
370 | 388 | \item \texttt{nz} (in) is an integer equal to the number of non-zero elements |
371 | - \item \texttt{T(nz)} (in) is a complex/real array containing the non-zero elements | |
372 | - \item \textt{Ti(nz)},\texttt{Tj(nz)} (in) are the indexes of the corresponding element of \texttt{T} in the original matrix. | |
389 | + \item \texttt{T(nz) or Tx(nz),Tz(nz)} (in) is a real array (or two real arrays for real/imaginary in case of a complex system) containing the non-zero elements | |
390 | + \item \textt{Ti(nz)},\texttt{Tj(nz)} (in) are the indexes of the corresponding element of \texttt{T} in the original matrix, it has to be 0-based as in C. | |
373 | 391 | \item \texttt{det} (out), a real(8) array of dimension 2 for dl and di specific interface (real systems) and dimension 3 for zl and zi interface (complex systems) |
374 | 392 | \item \texttt{status} (out) is an integer which contain non-zero is something went wrong |
375 | 393 | \end{itemize} |
376 | 394 | |
... | ... | @@ -395,9 +413,11 @@ |
395 | 413 | integer(kind=sp_kind), parameter :: nz=12 |
396 | 414 | integer(kind=sp_kind), parameter :: n=5 |
397 | 415 | complex(kind=dp_kind),dimension(nz) :: A |
416 | +real(kind=dp_kind), dimension(nz) :: Ax,Az | |
398 | 417 | complex(kind=dp_kind),dimension(n,n) :: As |
399 | 418 | integer(kind=sp_kind),dimension(nz) :: Ti,Tj |
400 | 419 | complex(kind=dp_kind),dimension(n) :: B,x |
420 | +real(kind=dp_kind), dimension(n) :: Bx,Bz | |
401 | 421 | integer(kind=sp_kind) :: status,i |
402 | 422 | real(kind=dp_kind),dimension(3) :: det |
403 | 423 | character(len=80) :: fmcmplx |
... | ... | @@ -410,6 +430,11 @@ |
410 | 430 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) |
411 | 431 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) |
412 | 432 | |
433 | +Ax=real(A) | |
434 | +Az=aimag(A) | |
435 | +Bx=real(B) | |
436 | +Bz=aimag(B) | |
437 | + | |
413 | 438 | ! Reconstruction of the matrix in standard form |
414 | 439 | As=0. |
415 | 440 | do i=1,nz |
416 | 441 | |
... | ... | @@ -428,13 +453,13 @@ |
428 | 453 | |
429 | 454 | ! can use either specific interface, fvn_zi_sparse_det |
430 | 455 | ! either generic one fvn_sparse_det |
431 | -call fvn_zi_sparse_det(n,nz,A,Ti,Tj,det,status) | |
456 | +call fvn_zi_sparse_det(n,nz,Ax,Az,Ti,Tj,det,status) | |
432 | 457 | write(*,*) |
433 | 458 | write(*,*) "Sparse Det = ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) |
434 | 459 | ! can use either specific interface fvn_zi_sparse_solve |
435 | 460 | ! either generic one fvn_sparse_solve |
436 | 461 | ! parameter det is optional |
437 | -call fvn_zi_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | |
462 | +call fvn_zi_sparse_solve(n,nz,Ax,Az,Ti,Tj,Bx,Bz,x,status,det) | |
438 | 463 | write(*,*) |
439 | 464 | write(*,*) "Sparse Det as solve option= ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) |
440 | 465 | write(*,*) |
fvn_sparse/fvn_sparse.f90
... | ... | @@ -65,8 +65,8 @@ |
65 | 65 | ! Solve Ax=B using UMFPACK |
66 | 66 | ! |
67 | 67 | ! Where A is a sparse matrix given in its triplet form |
68 | -! T -> non zero elements | |
69 | -! Ti,Tj -> row and column index (1-based) of the given elt | |
68 | +! T -> non zero elements (Tx and Tz for real and imaginary part if complex) | |
69 | +! Ti,Tj -> row and column index (0-based) of the given elt | |
70 | 70 | ! n : rank of matrix A |
71 | 71 | ! nz : number of non zero elts |
72 | 72 | ! |
73 | 73 | |
74 | 74 | |
75 | 75 | |
76 | 76 | |
... | ... | @@ -74,22 +74,20 @@ |
74 | 74 | ! * = zl : double complex + integer(kind=dp_kind) |
75 | 75 | ! * = zi : double complex + integer(kind=sp_kind) |
76 | 76 | ! |
77 | -subroutine fvn_zl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
77 | +subroutine fvn_zl_sparse_solve(n,nz,Tx,Tz,Ti,Tj,Bx,Bz,x,status,det) | |
78 | 78 | implicit none |
79 | 79 | integer(kind=dp_kind), intent(in) :: n,nz |
80 | -complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
80 | +real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
81 | 81 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj |
82 | -complex(kind=dp_kind),dimension(n),intent(in) :: B | |
82 | +real(kind=dp_kind),dimension(n),intent(in) :: Bx,Bz | |
83 | 83 | complex(kind=dp_kind),dimension(n),intent(out) :: x |
84 | 84 | integer(kind=dp_kind), intent(out) :: status |
85 | 85 | real(kind=dp_kind), dimension(3), optional, intent(out) :: det |
86 | 86 | |
87 | -integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
88 | -real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
89 | 87 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az |
90 | 88 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai |
91 | 89 | integer(kind=dp_kind) :: symbolic,numeric |
92 | -real(kind=dp_kind),dimension(:),allocatable :: xx,xz,bx,bz | |
90 | +real(kind=dp_kind),dimension(:),allocatable :: xx,xz | |
93 | 91 | real(kind=dp_kind),dimension(90) :: info |
94 | 92 | real(kind=dp_kind),dimension(20) :: control |
95 | 93 | integer(kind=dp_kind) :: sys |
96 | 94 | |
... | ... | @@ -97,19 +95,11 @@ |
97 | 95 | |
98 | 96 | status=0 |
99 | 97 | |
100 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
101 | -! Tx and Tz are the real and imaginary parts of T | |
102 | -allocate(wTi(nz),wTj(nz)) | |
103 | -allocate(Tx(nz),Tz(nz)) | |
104 | -Tx=dble(T) | |
105 | -Tz=aimag(T) | |
106 | -wTi=Ti-1 | |
107 | -wTj=Tj-1 | |
108 | 98 | allocate(Ax(nz),Az(nz)) |
109 | 99 | allocate(Ap(n+1),Ai(nz)) |
110 | 100 | |
111 | 101 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
112 | -call umfpack_zl_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
102 | +call umfpack_zl_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
113 | 103 | ! if status is not zero a problem has occured |
114 | 104 | if (status /= 0) then |
115 | 105 | write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(int(status,kind=sp_kind))) |
... | ... | @@ -151,9 +141,7 @@ |
151 | 141 | |
152 | 142 | |
153 | 143 | |
154 | -allocate(bx(n),bz(n),xx(n),xz(n)) | |
155 | -bx=dble(B) | |
156 | -bz=aimag(B) | |
144 | +allocate(xx(n),xz(n)) | |
157 | 145 | sys=0 |
158 | 146 | ! sys may be used to define type of solving -> see umfpack.h |
159 | 147 | |
160 | 148 | |
161 | 149 | |
162 | 150 | |
163 | 151 | |
164 | 152 | |
... | ... | @@ -171,28 +159,24 @@ |
171 | 159 | |
172 | 160 | x=cmplx(xx,xz,dp_kind) |
173 | 161 | |
174 | -deallocate(bx,bz,xx,xz) | |
162 | +deallocate(xx,xz) | |
175 | 163 | deallocate(Ax,Az) |
176 | -deallocate(Tx,Tz) | |
177 | -deallocate(wTi,wTj) | |
178 | 164 | end subroutine |
179 | 165 | |
180 | 166 | |
181 | 167 | |
182 | 168 | |
183 | 169 | |
184 | -subroutine fvn_zi_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
170 | +subroutine fvn_zi_sparse_solve(n,nz,Tx,Tz,Ti,Tj,Bx,Bz,x,status,det) | |
185 | 171 | implicit none |
186 | 172 | integer(kind=sp_kind), intent(in) :: n,nz |
187 | -complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
173 | +real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
188 | 174 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj |
189 | -complex(kind=dp_kind),dimension(n),intent(in) :: B | |
175 | +real(kind=dp_kind),dimension(n),intent(in) :: Bx,Bz | |
190 | 176 | complex(kind=dp_kind),dimension(n),intent(out) :: x |
191 | 177 | integer(kind=sp_kind), intent(out) :: status |
192 | 178 | real(kind=dp_kind), dimension(3), optional, intent(out) :: det |
193 | 179 | |
194 | -integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | |
195 | -real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
196 | 180 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az |
197 | 181 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai |
198 | 182 | !integer(kind=dp_kind) :: symbolic,numeric |
199 | 183 | |
200 | 184 | |
... | ... | @@ -200,25 +184,17 @@ |
200 | 184 | ! As symbolic and numeric are used to store a C pointer, it is necessary to |
201 | 185 | ! still use an integer(kind=dp_kind) for 64bits machines |
202 | 186 | ! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric |
203 | -real(kind=dp_kind),dimension(:),allocatable :: xx,xz,bx,bz | |
187 | +real(kind=dp_kind),dimension(:),allocatable :: xx,xz | |
204 | 188 | real(kind=dp_kind),dimension(90) :: info |
205 | 189 | real(kind=dp_kind),dimension(20) :: control |
206 | 190 | integer(kind=sp_kind) :: sys |
207 | 191 | |
208 | 192 | status=0 |
209 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
210 | -! Tx and Tz are the real and imaginary parts of T | |
211 | -allocate(wTi(nz),wTj(nz)) | |
212 | -allocate(Tx(nz),Tz(nz)) | |
213 | -Tx=dble(T) | |
214 | -Tz=aimag(T) | |
215 | -wTi=Ti-1 | |
216 | -wTj=Tj-1 | |
217 | 193 | allocate(Ax(nz),Az(nz)) |
218 | 194 | allocate(Ap(n+1),Ai(nz)) |
219 | 195 | |
220 | 196 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
221 | -call umfpack_zi_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
197 | +call umfpack_zi_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
222 | 198 | ! if status is not zero a problem has occured |
223 | 199 | if (status /= 0) then |
224 | 200 | write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(status)) |
... | ... | @@ -261,9 +237,7 @@ |
261 | 237 | |
262 | 238 | |
263 | 239 | |
264 | -allocate(bx(n),bz(n),xx(n),xz(n)) | |
265 | -bx=dble(B) | |
266 | -bz=aimag(B) | |
240 | +allocate(xx(n),xz(n)) | |
267 | 241 | sys=0 |
268 | 242 | ! sys may be used to define type of solving -> see umfpack.h |
269 | 243 | |
270 | 244 | |
... | ... | @@ -280,10 +254,8 @@ |
280 | 254 | |
281 | 255 | x=cmplx(xx,xz,dp_kind) |
282 | 256 | |
283 | -deallocate(bx,bz,xx,xz) | |
257 | +deallocate(xx,xz) | |
284 | 258 | deallocate(Ax,Az) |
285 | -deallocate(Tx,Tz) | |
286 | -deallocate(wTi,wTj) | |
287 | 259 | end subroutine |
288 | 260 | |
289 | 261 | |
... | ... | @@ -301,7 +273,6 @@ |
301 | 273 | integer(kind=dp_kind), intent(out) :: status |
302 | 274 | real(kind=dp_kind), dimension(2), optional, intent(out) :: det |
303 | 275 | |
304 | -integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
305 | 276 | real(kind=dp_kind),dimension(:),allocatable :: A |
306 | 277 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai |
307 | 278 | !integer(kind=dp_kind) :: symbolic,numeric |
308 | 279 | |
... | ... | @@ -311,15 +282,11 @@ |
311 | 282 | integer(kind=dp_kind) :: sys |
312 | 283 | |
313 | 284 | status=0 |
314 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
315 | -allocate(wTi(nz),wTj(nz)) | |
316 | -wTi=Ti-1 | |
317 | -wTj=Tj-1 | |
318 | 285 | allocate(A(nz)) |
319 | 286 | allocate(Ap(n+1),Ai(nz)) |
320 | 287 | |
321 | 288 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
322 | -call umfpack_dl_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
289 | +call umfpack_dl_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | |
323 | 290 | ! if status is not zero a problem has occured |
324 | 291 | if (status /= 0) then |
325 | 292 | write(*,*) "Problem during umfpack_dl_triplet_to_col : ",trim(umfpack_return_code(int(status,kind=sp_kind))) |
... | ... | @@ -375,7 +342,6 @@ |
375 | 342 | call umfpack_dl_free_numeric (numeric) |
376 | 343 | |
377 | 344 | deallocate(A) |
378 | -deallocate(wTi,wTj) | |
379 | 345 | end subroutine |
380 | 346 | |
381 | 347 | |
... | ... | @@ -393,7 +359,6 @@ |
393 | 359 | integer(kind=sp_kind), intent(out) :: status |
394 | 360 | real(kind=dp_kind), dimension(2), optional, intent(out) :: det |
395 | 361 | |
396 | -integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | |
397 | 362 | real(kind=dp_kind),dimension(:),allocatable :: A |
398 | 363 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai |
399 | 364 | !integer(kind=dp_kind) :: symbolic,numeric |
400 | 365 | |
... | ... | @@ -406,15 +371,11 @@ |
406 | 371 | integer(kind=sp_kind) :: sys |
407 | 372 | |
408 | 373 | status=0 |
409 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
410 | -allocate(wTi(nz),wTj(nz)) | |
411 | -wTi=Ti-1 | |
412 | -wTj=Tj-1 | |
413 | 374 | allocate(A(nz)) |
414 | 375 | allocate(Ap(n+1),Ai(nz)) |
415 | 376 | |
416 | 377 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
417 | -call umfpack_di_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
378 | +call umfpack_di_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | |
418 | 379 | ! if status is not zero a problem has occured |
419 | 380 | if (status /= 0) then |
420 | 381 | write(*,*) "Problem during umfpack_di_triplet_to_col : ",trim(umfpack_return_code(status)) |
... | ... | @@ -468,7 +429,6 @@ |
468 | 429 | call umfpack_di_free_numeric (numeric) |
469 | 430 | |
470 | 431 | deallocate(A) |
471 | -deallocate(wTi,wTj) | |
472 | 432 | end subroutine |
473 | 433 | |
474 | 434 | |
475 | 435 | |
476 | 436 | |
... | ... | @@ -477,16 +437,14 @@ |
477 | 437 | ! SPARSE DETERMINANT |
478 | 438 | ! |
479 | 439 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
480 | -subroutine fvn_zl_sparse_det(n,nz,T,Ti,Tj,det,status) | |
440 | +subroutine fvn_zl_sparse_det(n,nz,Tx,Tz,Ti,Tj,det,status) | |
481 | 441 | implicit none |
482 | 442 | integer(kind=dp_kind), intent(in) :: n,nz |
483 | -complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
443 | +real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
484 | 444 | integer(kind=dp_kind),dimension(nz),intent(in) :: Ti,Tj |
485 | 445 | real(kind=dp_kind), dimension(3), intent(out) :: det |
486 | 446 | integer(kind=dp_kind), intent(out) :: status |
487 | 447 | |
488 | -integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
489 | -real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
490 | 448 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az |
491 | 449 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai |
492 | 450 | integer(kind=dp_kind) :: symbolic,numeric |
493 | 451 | |
... | ... | @@ -497,19 +455,11 @@ |
497 | 455 | |
498 | 456 | status=0 |
499 | 457 | |
500 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
501 | -! Tx and Tz are the real and imaginary parts of T | |
502 | -allocate(wTi(nz),wTj(nz)) | |
503 | -allocate(Tx(nz),Tz(nz)) | |
504 | -Tx=dble(T) | |
505 | -Tz=aimag(T) | |
506 | -wTi=Ti-1 | |
507 | -wTj=Tj-1 | |
508 | 458 | allocate(Ax(nz),Az(nz)) |
509 | 459 | allocate(Ap(n+1),Ai(nz)) |
510 | 460 | |
511 | 461 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
512 | -call umfpack_zl_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
462 | +call umfpack_zl_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
513 | 463 | ! if status is not zero a problem has occured |
514 | 464 | if (status /= 0) then |
515 | 465 | write(*,*) "Problem during umfpack_zl_triplet_to_col ",trim(umfpack_return_code(int(status,kind=sp_kind))) |
516 | 466 | |
517 | 467 | |
518 | 468 | |
... | ... | @@ -550,21 +500,17 @@ |
550 | 500 | call umfpack_zl_free_numeric (numeric) |
551 | 501 | |
552 | 502 | deallocate(Ax,Az) |
553 | -deallocate(Tx,Tz) | |
554 | -deallocate(wTi,wTj) | |
555 | 503 | end subroutine |
556 | 504 | |
557 | 505 | |
558 | -subroutine fvn_zi_sparse_det(n,nz,T,Ti,Tj,det,status) | |
506 | +subroutine fvn_zi_sparse_det(n,nz,Tx,Tz,Ti,Tj,det,status) | |
559 | 507 | implicit none |
560 | 508 | integer(kind=sp_kind), intent(in) :: n,nz |
561 | -complex(kind=dp_kind),dimension(nz),intent(in) :: T | |
509 | +real(kind=dp_kind),dimension(nz),intent(in) :: Tx,Tz | |
562 | 510 | integer(kind=sp_kind),dimension(nz),intent(in) :: Ti,Tj |
563 | 511 | integer(kind=sp_kind), intent(out) :: status |
564 | 512 | real(kind=dp_kind), dimension(3), intent(out) :: det |
565 | 513 | |
566 | -integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | |
567 | -real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz | |
568 | 514 | real(kind=dp_kind),dimension(:),allocatable :: Ax,Az |
569 | 515 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai |
570 | 516 | !integer(kind=dp_kind) :: symbolic,numeric |
571 | 517 | |
... | ... | @@ -576,19 +522,11 @@ |
576 | 522 | real(kind=dp_kind),dimension(20) :: control |
577 | 523 | |
578 | 524 | status=0 |
579 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
580 | -! Tx and Tz are the real and imaginary parts of T | |
581 | -allocate(wTi(nz),wTj(nz)) | |
582 | -allocate(Tx(nz),Tz(nz)) | |
583 | -Tx=dble(T) | |
584 | -Tz=aimag(T) | |
585 | -wTi=Ti-1 | |
586 | -wTj=Tj-1 | |
587 | 525 | allocate(Ax(nz),Az(nz)) |
588 | 526 | allocate(Ap(n+1),Ai(nz)) |
589 | 527 | |
590 | 528 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
591 | -call umfpack_zi_triplet_to_col(n,n,nz,wTi,wTj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
529 | +call umfpack_zi_triplet_to_col(n,n,nz,Ti,Tj,Tx,Tz,Ap,Ai,Ax,Az,status) | |
592 | 530 | ! if status is not zero a problem has occured |
593 | 531 | if (status /= 0) then |
594 | 532 | write(*,*) "Problem during umfpack_zl_triplet_to_col : ",trim(umfpack_return_code(status)) |
... | ... | @@ -629,8 +567,6 @@ |
629 | 567 | call umfpack_zi_free_numeric (numeric) |
630 | 568 | |
631 | 569 | deallocate(Ax,Az) |
632 | -deallocate(Tx,Tz) | |
633 | -deallocate(wTi,wTj) | |
634 | 570 | end subroutine |
635 | 571 | |
636 | 572 | subroutine fvn_dl_sparse_det(n,nz,T,Ti,Tj,det,status) |
... | ... | @@ -641,7 +577,6 @@ |
641 | 577 | integer(kind=dp_kind), intent(out) :: status |
642 | 578 | real(kind=dp_kind), dimension(2), intent(out) :: det |
643 | 579 | |
644 | -integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj | |
645 | 580 | real(kind=dp_kind),dimension(:),allocatable :: A |
646 | 581 | integer(kind=dp_kind),dimension(:),allocatable :: Ap,Ai |
647 | 582 | !integer(kind=dp_kind) :: symbolic,numeric |
648 | 583 | |
... | ... | @@ -650,15 +585,11 @@ |
650 | 585 | real(kind=dp_kind),dimension(20) :: control |
651 | 586 | |
652 | 587 | status=0 |
653 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
654 | -allocate(wTi(nz),wTj(nz)) | |
655 | -wTi=Ti-1 | |
656 | -wTj=Tj-1 | |
657 | 588 | allocate(A(nz)) |
658 | 589 | allocate(Ap(n+1),Ai(nz)) |
659 | 590 | |
660 | 591 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
661 | -call umfpack_dl_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
592 | +call umfpack_dl_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | |
662 | 593 | ! if status is not zero a problem has occured |
663 | 594 | if (status /= 0) then |
664 | 595 | write(*,*) "Problem during umfpack_dl_triplet_to_col : ",trim(umfpack_return_code(int(status,kind=sp_kind))) |
... | ... | @@ -699,7 +630,6 @@ |
699 | 630 | call umfpack_dl_free_numeric (numeric) |
700 | 631 | |
701 | 632 | deallocate(A) |
702 | -deallocate(wTi,wTj) | |
703 | 633 | end subroutine |
704 | 634 | |
705 | 635 | |
... | ... | @@ -711,7 +641,6 @@ |
711 | 641 | integer(kind=sp_kind), intent(out) :: status |
712 | 642 | real(kind=dp_kind), dimension(2), intent(out) :: det |
713 | 643 | |
714 | -integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj | |
715 | 644 | real(kind=dp_kind),dimension(:),allocatable :: A |
716 | 645 | integer(kind=sp_kind),dimension(:),allocatable :: Ap,Ai |
717 | 646 | !integer(kind=dp_kind) :: symbolic,numeric |
718 | 647 | |
... | ... | @@ -725,15 +654,11 @@ |
725 | 654 | |
726 | 655 | |
727 | 656 | status=0 |
728 | -! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
729 | -allocate(wTi(nz),wTj(nz)) | |
730 | -wTi=Ti-1 | |
731 | -wTj=Tj-1 | |
732 | 657 | allocate(A(nz)) |
733 | 658 | allocate(Ap(n+1),Ai(nz)) |
734 | 659 | |
735 | 660 | ! perform the triplet to compressed column form -> Ap,Ai,Ax,Az |
736 | -call umfpack_di_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
661 | +call umfpack_di_triplet_to_col(n,n,nz,Ti,Tj,T,Ap,Ai,A,status) | |
737 | 662 | ! if status is not zero a problem has occured |
738 | 663 | if (status /= 0) then |
739 | 664 | write(*,*) "Problem during umfpack_di_triplet_to_col : ",trim(umfpack_return_code(status)) |
... | ... | @@ -775,7 +700,6 @@ |
775 | 700 | call umfpack_di_free_numeric (numeric) |
776 | 701 | |
777 | 702 | deallocate(A) |
778 | -deallocate(wTi,wTj) | |
779 | 703 | end subroutine |
780 | 704 | |
781 | 705 |
fvn_test/test_sparse_di.f90
fvn_test/test_sparse_dl.f90
fvn_test/test_sparse_zi.f90
... | ... | @@ -4,9 +4,11 @@ |
4 | 4 | integer(kind=sp_kind), parameter :: nz=12 |
5 | 5 | integer(kind=sp_kind), parameter :: n=5 |
6 | 6 | complex(kind=dp_kind),dimension(nz) :: A |
7 | +real(kind=dp_kind),dimension(nz) :: Ax,Az | |
7 | 8 | complex(kind=dp_kind),dimension(n,n) :: As |
8 | 9 | integer(kind=sp_kind),dimension(nz) :: Ti,Tj |
9 | 10 | complex(kind=dp_kind),dimension(n) :: B,x |
11 | +real(kind=dp_kind),dimension(n) :: Bx,Bz | |
10 | 12 | integer(kind=sp_kind) :: status,i |
11 | 13 | real(kind=dp_kind),dimension(3) :: det |
12 | 14 | character(len=80) :: fmcmplx |
13 | 15 | |
... | ... | @@ -19,12 +21,21 @@ |
19 | 21 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) |
20 | 22 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) |
21 | 23 | |
24 | +Ax=real(A) | |
25 | +Az=aimag(A) | |
26 | +Bx=real(B) | |
27 | +Bz=aimag(B) | |
28 | + | |
22 | 29 | ! Reconstruction of the matrix in standard form |
23 | 30 | As=0. |
24 | 31 | do i=1,nz |
25 | 32 | As(Ti(i),Tj(i))=A(i) |
26 | 33 | end do |
27 | 34 | |
35 | +! sparse routines must be fed up with 0-based indices | |
36 | +Ti=Ti-1 | |
37 | +Tj=Tj-1 | |
38 | + | |
28 | 39 | write(*,*) "Matrix in standard representation :" |
29 | 40 | do i=1,5 |
30 | 41 | write(*,fmcmplx) As(i,:) |
31 | 42 | |
... | ... | @@ -37,13 +48,13 @@ |
37 | 48 | |
38 | 49 | ! can use either specific interface, fvn_zi_sparse_det |
39 | 50 | ! either generic one fvn_sparse_det |
40 | -call fvn_zi_sparse_det(n,nz,A,Ti,Tj,det,status) | |
51 | +call fvn_zi_sparse_det(n,nz,Ax,Az,Ti,Tj,det,status) | |
41 | 52 | write(*,*) |
42 | 53 | write(*,*) "Sparse Det = ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) |
43 | 54 | ! can use either specific interface fvn_zi_sparse_solve |
44 | 55 | ! either generic one fvn_sparse_solve |
45 | 56 | ! parameter det is optional |
46 | -call fvn_zi_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | |
57 | +call fvn_zi_sparse_solve(n,nz,Ax,Az,Ti,Tj,Bx,Bz,x,status,det) | |
47 | 58 | write(*,*) |
48 | 59 | write(*,*) "Sparse Det as solve option= ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) |
49 | 60 | write(*,*) |
fvn_test/test_sparse_zl.f90
... | ... | @@ -5,9 +5,11 @@ |
5 | 5 | integer(kind=dp_kind), parameter :: nz=12 |
6 | 6 | integer(kind=dp_kind), parameter :: n=5 |
7 | 7 | complex(kind=dp_kind),dimension(nz) :: A |
8 | +real(kind=dp_kind),dimension(nz) :: Ax,Az | |
8 | 9 | complex(kind=dp_kind),dimension(n,n) :: As |
9 | 10 | integer(kind=dp_kind),dimension(nz) :: Ti,Tj |
10 | 11 | complex(kind=dp_kind),dimension(n) :: B,x |
12 | +real(kind=dp_kind),dimension(n) :: Bx,Bz | |
11 | 13 | integer(kind=dp_kind) :: status,i |
12 | 14 | real(kind=dp_kind),dimension(3) :: det |
13 | 15 | character(len=80) :: fmcmplx |
14 | 16 | |
... | ... | @@ -20,12 +22,21 @@ |
20 | 22 | Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) |
21 | 23 | Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) |
22 | 24 | |
25 | +Ax=real(A) | |
26 | +Az=aimag(A) | |
27 | +Bx=real(B) | |
28 | +Bz=aimag(B) | |
29 | + | |
23 | 30 | ! Reconstruction of the matrix in standard form |
24 | 31 | As=0. |
25 | 32 | do i=1,nz |
26 | 33 | As(Ti(i),Tj(i))=A(i) |
27 | 34 | end do |
28 | 35 | |
36 | +! sparse routines must be fed up with 0-based indices | |
37 | +Ti=Ti-1 | |
38 | +Tj=Tj-1 | |
39 | + | |
29 | 40 | write(*,*) "Matrix in standard representation :" |
30 | 41 | do i=1,5 |
31 | 42 | write(*,fmcmplx) As(i,:) |
32 | 43 | |
... | ... | @@ -37,13 +48,13 @@ |
37 | 48 | write(*,fmcmplx) B |
38 | 49 | ! can use either specific interface, fvn_zl_sparse_det |
39 | 50 | ! either generic one fvn_sparse_det |
40 | -call fvn_zl_sparse_det(n,nz,A,Ti,Tj,det,status) | |
51 | +call fvn_zl_sparse_det(n,nz,Ax,Az,Ti,Tj,det,status) | |
41 | 52 | write(*,*) |
42 | 53 | write(*,*) "Sparse Det = ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) |
43 | 54 | ! can use either specific interface fvn_zl_sparse_solve |
44 | 55 | ! either generic one fvn_sparse_solve |
45 | 56 | ! parameter det is optional |
46 | -call fvn_zl_sparse_solve(n,nz,A,Ti,Tj,B,x,status,det) | |
57 | +call fvn_zl_sparse_solve(n,nz,Ax,Az,Ti,Tj,Bx,Bz,x,status,det) | |
47 | 58 | write(*,*) |
48 | 59 | write(*,*) "Sparse Det as solve option= ",cmplx(det(1),det(2),kind=dp_kind)*10**det(3) |
49 | 60 | write(*,*) |