Skip to content

Commit b233156

Browse files
committed
option for pre-allocated pivot indices
1 parent e9a3f5b commit b233156

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

src/stdlib_linalg.fypp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,9 +575,11 @@ module stdlib_linalg
575575
interface invert
576576
#:for rk,rt,ri in RC_KINDS_TYPES
577577
#:if rk!="xdp"
578-
module subroutine stdlib_linalg_invert_${ri}$(a,err)
578+
module subroutine stdlib_linalg_invert_${ri}$(a,pivot,err)
579579
!> Input matrix a[n,n]
580580
${rt}$, intent(inout) :: a(:,:)
581+
!> [optional] Storage array for the diagonal pivot indices
582+
integer(ilp), optional, intent(inout), target :: pivot(:)
581583
!> [optional] state return flag. On error if not requested, the code will stop
582584
type(linalg_state_type), optional, intent(out) :: err
583585
end subroutine stdlib_linalg_invert_${ri}$

src/stdlib_linalg_inverse.fypp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,40 @@ submodule (stdlib_linalg) stdlib_linalg_inverse
3434
#:for rk,rt,ri in RC_KINDS_TYPES
3535
#:if rk!="xdp"
3636
! Compute the in-place square matrix inverse of a
37-
module subroutine stdlib_linalg_invert_${ri}$(a,err)
38-
!> Input matrix a[n,n]
37+
module subroutine stdlib_linalg_invert_${ri}$(a,pivot,err)
38+
!> Input matrix a[n,n]. On return, A is destroyed and replaced by the inverse
3939
${rt}$, intent(inout) :: a(:,:)
40+
!> [optional] Storage array for the diagonal pivot indices
41+
integer(ilp), optional, intent(inout), target :: pivot(:)
4042
!> [optional] state return flag. On error if not requested, the code will stop
4143
type(linalg_state_type), optional, intent(out) :: err
4244

4345
!> Local variables
4446
type(linalg_state_type) :: err0
45-
integer(ilp) :: lda,n,info,nb,lwork
46-
integer(ilp), allocatable :: ipiv(:)
47+
integer(ilp) :: lda,n,info,nb,lwork,npiv
48+
integer(ilp), pointer :: ipiv(:)
4749
${rt}$, allocatable :: work(:)
4850

4951
!> Problem sizes
5052
lda = size(a,1,kind=ilp)
5153
n = size(a,2,kind=ilp)
5254

53-
if (lda<1 .or. n<1 .or. lda/=n) then
54-
err0 = linalg_state_type(this,LINALG_VALUE_ERROR,'invalid matrix size: a=[',lda,',',n,']')
55+
! Has a pre-allocated pivots storage array been provided?
56+
if (present(pivot)) then
57+
ipiv => pivot
58+
else
59+
allocate(ipiv(n))
60+
endif
61+
npiv = size(ipiv,kind=ilp)
62+
63+
if (lda<1 .or. n<1 .or. lda/=n .or. npiv<n) then
64+
err0 = linalg_state_type(this,LINALG_VALUE_ERROR,'invalid matrix size: a=',[lda,n], &
65+
', pivot=',npiv)
66+
if (.not.present(pivot)) deallocate(ipiv)
5567
call linalg_error_handling(err0,err)
5668
return
5769
end if
5870

59-
! Pivot indices
60-
allocate(ipiv(n))
61-
6271
! Factorize matrix (overwrite result)
6372
call getrf(lda,n,a,lda,ipiv,info)
6473

@@ -80,6 +89,7 @@ submodule (stdlib_linalg) stdlib_linalg_inverse
8089
call handle_getri_info(info,lda,n,err0)
8190

8291
! Process output and return
92+
if (.not.present(pivot)) deallocate(ipiv)
8393
call linalg_error_handling(err0,err)
8494

8595
end subroutine stdlib_linalg_invert_${ri}$
@@ -97,7 +107,7 @@ submodule (stdlib_linalg) stdlib_linalg_inverse
97107
allocate(inva,source=a)
98108

99109
!> Compute matrix inverse
100-
call stdlib_linalg_invert_${ri}$(inva,err)
110+
call stdlib_linalg_invert_${ri}$(inva,err=err)
101111

102112
end function stdlib_linalg_inverse_${ri}$
103113

0 commit comments

Comments
 (0)