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 |