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 Side-by-side Diff
fvn_sparse/fvn_sparse.f90
... | ... | @@ -7,6 +7,9 @@ |
7 | 7 | module procedure fvn_zl_sparse_solve,fvn_zi_sparse_solve,fvn_dl_sparse_solve,fvn_di_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 | |
10 | 13 | contains |
11 | 14 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
12 | 15 | ! |
... | ... | @@ -30,7 +33,7 @@ |
30 | 33 | ! * = zl : double complex + integer(kind=dp_kind) |
31 | 34 | ! * = zi : double complex + integer(kind=sp_kind) |
32 | 35 | ! |
33 | -subroutine fvn_zl_sparse_solve(n,nz,T,Ti,Tj,B,x,status) | |
36 | +subroutine fvn_zl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
34 | 37 | implicit none |
35 | 38 | integer(kind=dp_kind), intent(in) :: n,nz |
36 | 39 | complex(kind=dp_kind),dimension(nz),intent(in) :: T |
... | ... | @@ -38,6 +41,7 @@ |
38 | 41 | complex(kind=dp_kind),dimension(n),intent(in) :: B |
39 | 42 | complex(kind=dp_kind),dimension(n),intent(out) :: x |
40 | 43 | integer(kind=dp_kind), intent(out) :: status |
44 | +complex(kind=dp_kind), optional, intent(out) :: det | |
41 | 45 | |
42 | 46 | integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj |
43 | 47 | real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz |
... | ... | @@ -48,6 +52,7 @@ |
48 | 52 | real(kind=dp_kind),dimension(90) :: info |
49 | 53 | real(kind=dp_kind),dimension(20) :: control |
50 | 54 | integer(kind=dp_kind) :: sys |
55 | +real(kind=dp_kind) :: Mx,Mz,Ex | |
51 | 56 | |
52 | 57 | |
53 | 58 | status=0 |
... | ... | @@ -92,6 +97,19 @@ |
92 | 97 | ! free the C symbolic pointer |
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 | + | |
95 | 113 | allocate(bx(n),bz(n),xx(n),xz(n)) |
96 | 114 | bx=dble(B) |
97 | 115 | bz=aimag(B) |
... | ... | @@ -122,7 +140,7 @@ |
122 | 140 | |
123 | 141 | |
124 | 142 | |
125 | -subroutine fvn_zi_sparse_solve(n,nz,T,Ti,Tj,B,x,status) | |
143 | +subroutine fvn_zi_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
126 | 144 | implicit none |
127 | 145 | integer(kind=sp_kind), intent(in) :: n,nz |
128 | 146 | complex(kind=dp_kind),dimension(nz),intent(in) :: T |
... | ... | @@ -130,6 +148,7 @@ |
130 | 148 | complex(kind=dp_kind),dimension(n),intent(in) :: B |
131 | 149 | complex(kind=dp_kind),dimension(n),intent(out) :: x |
132 | 150 | integer(kind=sp_kind), intent(out) :: status |
151 | +complex(kind=dp_kind), optional, intent(out) :: det | |
133 | 152 | |
134 | 153 | integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj |
135 | 154 | real(kind=dp_kind),dimension(:),allocatable :: Tx,Tz |
... | ... | @@ -144,6 +163,7 @@ |
144 | 163 | real(kind=dp_kind),dimension(90) :: info |
145 | 164 | real(kind=dp_kind),dimension(20) :: control |
146 | 165 | integer(kind=sp_kind) :: sys |
166 | +real(kind=dp_kind) :: Mx,Mz,Ex | |
147 | 167 | |
148 | 168 | status=0 |
149 | 169 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation |
... | ... | @@ -186,6 +206,20 @@ |
186 | 206 | ! free the C symbolic pointer |
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 | + | |
189 | 223 | allocate(bx(n),bz(n),xx(n),xz(n)) |
190 | 224 | bx=dble(B) |
191 | 225 | bz=aimag(B) |
... | ... | @@ -216,7 +250,7 @@ |
216 | 250 | |
217 | 251 | |
218 | 252 | |
219 | -subroutine fvn_dl_sparse_solve(n,nz,T,Ti,Tj,B,x,status) | |
253 | +subroutine fvn_dl_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
220 | 254 | implicit none |
221 | 255 | integer(kind=dp_kind), intent(in) :: n,nz |
222 | 256 | real(kind=dp_kind),dimension(nz),intent(in) :: T |
... | ... | @@ -224,6 +258,7 @@ |
224 | 258 | real(kind=dp_kind),dimension(n),intent(in) :: B |
225 | 259 | real(kind=dp_kind),dimension(n),intent(out) :: x |
226 | 260 | integer(kind=dp_kind), intent(out) :: status |
261 | +real(kind=dp_kind), optional, intent(out) :: det | |
227 | 262 | |
228 | 263 | integer(kind=dp_kind),dimension(:),allocatable :: wTi,wTj |
229 | 264 | real(kind=dp_kind),dimension(:),allocatable :: A |
... | ... | @@ -233,6 +268,7 @@ |
233 | 268 | real(kind=dp_kind),dimension(90) :: info |
234 | 269 | real(kind=dp_kind),dimension(20) :: control |
235 | 270 | integer(kind=dp_kind) :: sys |
271 | +real(kind=dp_kind) :: Mx,Ex | |
236 | 272 | |
237 | 273 | status=0 |
238 | 274 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation |
... | ... | @@ -271,6 +307,18 @@ |
271 | 307 | ! free the C symbolic pointer |
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 | + | |
274 | 322 | sys=0 |
275 | 323 | ! sys may be used to define type of solving -> see umfpack.h |
276 | 324 | |
... | ... | @@ -294,7 +342,7 @@ |
294 | 342 | |
295 | 343 | |
296 | 344 | |
297 | -subroutine fvn_di_sparse_solve(n,nz,T,Ti,Tj,B,x,status) | |
345 | +subroutine fvn_di_sparse_solve(n,nz,T,Ti,Tj,B,x,status,det) | |
298 | 346 | implicit none |
299 | 347 | integer(kind=sp_kind), intent(in) :: n,nz |
300 | 348 | real(kind=dp_kind),dimension(nz),intent(in) :: T |
... | ... | @@ -302,6 +350,7 @@ |
302 | 350 | real(kind=dp_kind),dimension(n),intent(in) :: B |
303 | 351 | real(kind=dp_kind),dimension(n),intent(out) :: x |
304 | 352 | integer(kind=sp_kind), intent(out) :: status |
353 | +real(kind=dp_kind), optional, intent(out) :: det | |
305 | 354 | |
306 | 355 | integer(kind=sp_kind),dimension(:),allocatable :: wTi,wTj |
307 | 356 | real(kind=dp_kind),dimension(:),allocatable :: A |
... | ... | @@ -314,6 +363,7 @@ |
314 | 363 | real(kind=dp_kind),dimension(90) :: info |
315 | 364 | real(kind=dp_kind),dimension(20) :: control |
316 | 365 | integer(kind=sp_kind) :: sys |
366 | +real(kind=dp_kind) :: Mx,Ex | |
317 | 367 | |
318 | 368 | status=0 |
319 | 369 | ! we use a working copy of Ti and Tj to perform 1-based to 0-based translation |
320 | 370 | |
... | ... | @@ -352,9 +402,19 @@ |
352 | 402 | ! free the C symbolic pointer |
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 | + | |
355 | 416 | sys=0 |
356 | 417 | ! sys may be used to define type of solving -> see umfpack.h |
357 | - | |
358 | 418 | ! Solving |
359 | 419 | call umfpack_di_solve (sys, Ap, Ai, A, x, B, numeric, control, info) |
360 | 420 | ! info(1) should be zero |
... | ... | @@ -369,6 +429,315 @@ |
369 | 429 | deallocate(A) |
370 | 430 | deallocate(wTi,wTj) |
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 | |
678 | +! still use an integer(kind=dp_kind) for 64bits machines | |
679 | +! An other possibility : integer(kind=sp_kind),dimension(2) :: symbolic,numeric | |
680 | +real(kind=dp_kind),dimension(90) :: info | |
681 | +real(kind=dp_kind),dimension(20) :: control | |
682 | +integer(kind=sp_kind) :: sys | |
683 | +real(kind=dp_kind) :: Mx,Ex | |
684 | + | |
685 | + | |
686 | +status=0 | |
687 | +! we use a working copy of Ti and Tj to perform 1-based to 0-based translation | |
688 | +allocate(wTi(nz),wTj(nz)) | |
689 | +wTi=Ti-1 | |
690 | +wTj=Tj-1 | |
691 | +allocate(A(nz)) | |
692 | +allocate(Ap(n+1),Ai(nz)) | |
693 | + | |
694 | +! perform the triplet to compressed column form -> Ap,Ai,Ax,Az | |
695 | +call umfpack_di_triplet_to_col(n,n,nz,wTi,wTj,T,Ap,Ai,A,status) | |
696 | +! if status is not zero a problem has occured | |
697 | +if (status /= 0) then | |
698 | + write(*,*) "Problem during umfpack_di_triplet_to_col" | |
699 | +endif | |
700 | + | |
701 | +! Define defaults control values | |
702 | +call umfpack_di_defaults(control) | |
703 | + | |
704 | +! Symbolic analysis | |
705 | +call umfpack_di_symbolic(n,n,Ap,Ai,A,symbolic, control, info) | |
706 | +! info(1) should be zero | |
707 | +if (info(1) /= 0) then | |
708 | + write(*,*) "Problem during symbolic analysis" | |
709 | + status=info(1) | |
710 | +endif | |
711 | + | |
712 | +! Numerical factorization | |
713 | +call umfpack_di_numeric (Ap, Ai, A, symbolic, numeric, control, info) | |
714 | +! info(1) should be zero | |
715 | +if (info(1) /= 0) then | |
716 | + write(*,*) "Problem during numerical factorization" | |
717 | + status=info(1) | |
718 | +endif | |
719 | + | |
720 | + | |
721 | +! free the C symbolic pointer | |
722 | +call umfpack_di_free_symbolic (symbolic) | |
723 | + | |
724 | +call umfpack_di_get_determinant(Mx,Ex,numeric,info,status) | |
725 | +det=Mx*10**Ex | |
726 | +! info(1) should be zero | |
727 | +if (info(1) /= 0) then | |
728 | + write(*,*) "Problem during sparse determinant, returned code : ",info(1) | |
729 | + status=info(1) | |
730 | +endif | |
731 | + | |
732 | +! free the C numeric pointer | |
733 | +call umfpack_di_free_numeric (numeric) | |
734 | + | |
735 | +deallocate(A) | |
736 | +deallocate(wTi,wTj) | |
737 | +end subroutine | |
738 | + | |
739 | + | |
740 | + | |
372 | 741 | |
373 | 742 | |
374 | 743 | end module fvn_sparse |
fvn_sparse/umfpack_wrapper.c
... | ... | @@ -72,6 +72,11 @@ |
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 | |
77 | 82 | /* complex(8) and integer(4) */ |
... | ... | @@ -131,6 +136,14 @@ |
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 | + | |
134 | 147 | /* real(8) and integer(8) */ |
135 | 148 | |
136 | 149 | /* defaults */ |
... | ... | @@ -178,6 +191,14 @@ |
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 | + | |
181 | 202 | /* real(8) and integer(4) */ |
182 | 203 | |
183 | 204 | /* defaults */ |
... | ... | @@ -223,5 +244,11 @@ |
223 | 244 | double A [ ], int *status) |
224 | 245 | { |
225 | 246 | *status = umfpack_di_triplet_to_col (*m, *n, *nz, Ti, Tj, T, Ap, Ai, A, (int *) NULL); |
247 | +} | |
248 | + | |
249 | +/* get determinant */ | |
250 | +void umfpack_di_get_determinant_ ( double *Mx, double *Ex, void **Numeric, double Info [UMFPACK_INFO], int *status ) | |
251 | +{ | |
252 | + *status = umfpack_di_get_determinant (Mx,Ex,*Numeric, Info); | |
226 | 253 | } |
fvn_test/Makefile
... | ... | @@ -2,10 +2,11 @@ |
2 | 2 | include $(BTREE)/Make.inc |
3 | 3 | |
4 | 4 | programs = test_fac$(exext) test_matinv$(exext) test_specfunc$(exext) \ |
5 | -test_det$(exext) test_matcon$(exext) test_matev$(exext) test_sparse$(exext) test_inter1d$(exext) \ | |
5 | +test_det$(exext) test_matcon$(exext) test_matev$(exext) test_inter1d$(exext) \ | |
6 | 6 | test_inter2d$(exext) test_inter3d$(exext) test_akima$(exext) test_lsp$(exext) test_muller$(exext) \ |
7 | 7 | test_integ$(exext) test_bsyn$(exext) test_bsjn$(exext) test_bskn$(exext) test_bsin$(exext) test_operators$(exext) test_ze1$(exext) \ |
8 | -test_besri$(exext) test_besrj$(exext) test_bestime$(exext) | |
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 | |
10 | 11 | prog:$(programs) |
11 | 12 |
fvn_test/test_sparse.f90
1 | -program test_sparse | |
2 | -use fvn_sparse | |
3 | -implicit none | |
4 | -integer(kind=ip_kind), parameter :: nz=12 | |
5 | -integer(kind=ip_kind), parameter :: n=5 | |
6 | -real(kind=dp_kind),dimension(nz) :: A | |
7 | -real(kind=dp_kind),dimension(n,n) :: As | |
8 | -integer(kind=ip_kind),dimension(nz) :: Ti,Tj | |
9 | -real(kind=dp_kind),dimension(n) :: B,x | |
10 | -integer(kind=ip_kind) :: status,i | |
11 | -! Description of the matrix in triplet form | |
12 | -A = (/ 2.,3.,3.,-1.,4.,4.,-3.,1.,2.,2.,6.,1. /) | |
13 | -B = (/ 8., 45., -3., 3., 19./) | |
14 | -Ti = (/ 1,2,1,3,5,2,3,4,5,3,2,5 /) | |
15 | -Tj = (/ 1,1,2,2,2,3,3,3,3,4,5,5 /) | |
16 | - | |
17 | -! Reconstruction of the matrix in standard form | |
18 | -! just needed for printing the matrix here | |
19 | -As=0. | |
20 | -do i=1,nz | |
21 | - As(Ti(i),Tj(i))=A(i) | |
22 | -end do | |
23 | -write(*,*) "Matrix in standard representation :" | |
24 | -do i=1,5 | |
25 | - write(*,'(5f8.4)') As(i,:) | |
26 | -end do | |
27 | -write(*,*) | |
28 | -write(*,'("Right hand side :",5f8.4)') B | |
29 | - | |
30 | -!specific routine that will be used here | |
31 | -!call fvn_di_sparse_solve(n,nz,A,Ti,Tj,B,x,status) | |
32 | -call fvn_di_sparse_solve(n,nz,A,Ti,Tj,B,x,status) | |
33 | -write(*,'("Solution :",5f8.4)') x | |
34 | -write(*,'("Product matrix Solution :",5f8.4)') matmul(As,x) | |
35 | -end program |
fvn_test/test_sparse_di.f90
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(*,*) | |
48 | +write(*,'("Product matrix Solution :",5f8.4)') matmul(As,x) | |
49 | +end program |
fvn_test/test_sparse_dl.f90
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(*,*) | |
48 | +write(*,'("Product matrix Solution :",5f8.4)') matmul(As,x) | |
49 | +end program |
fvn_test/test_sparse_zi.f90
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 :" | |
51 | +write(*,fmcmplx) x | |
52 | +write(*,*) | |
53 | +write(*,*) "Product matrix Solution :" | |
54 | +write(*,fmcmplx) matmul(As,x) | |
55 | +end program |
fvn_test/test_sparse_zl.f90
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 | |
52 | +write(*,*) | |
53 | +write(*,*) "Product matrix Solution :" | |
54 | +write(*,fmcmplx) matmul(As,x) | |
55 | +end program |