Skip to content

Commit 95a4900

Browse files
committed
overwrite_a option
1 parent 81e5583 commit 95a4900

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

src/stdlib_linalg.fypp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ module stdlib_linalg
623623
!! are implemented using LAPACK's eigenvalue sorting mechanism.
624624
!!
625625
#:for rk,rt,ri in RC_KINDS_TYPES
626-
module subroutine stdlib_linalg_${ri}$_schur(a, t, z, eigvals, storage, err)
626+
module subroutine stdlib_linalg_${ri}$_schur(a, t, z, eigvals, overwrite_a, storage, err)
627627
!> Input matrix a[m,m]
628628
${rt}$, intent(inout), target :: a(:,:)
629629
!> Schur form of A: upper-triangular or quasi-upper-triangular matrix T
@@ -632,7 +632,9 @@ module stdlib_linalg
632632
${rt}$, optional, intent(out), contiguous, target :: z(:,:)
633633
!> [optional] Output eigenvalues that appear on the diagonal of T
634634
complex(${rk}$), optional, intent(out), contiguous, target :: eigvals(:)
635-
!> [optional] Provide pre-allocated workspace, size to be checked with schur_space
635+
!> [optional] Can A data be overwritten and destroyed?
636+
logical(lk), optional, intent(in) :: overwrite_a
637+
!> [optional] Provide pre-allocated workspace, size to be checked with schur_space
636638
${rt}$, optional, intent(inout), target :: storage(:)
637639
!> [optional] State return flag. On error if not requested, the code will stop
638640
type(linalg_state_type), optional, intent(out) :: err

src/stdlib_linalg_schur.fypp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ submodule (stdlib_linalg) stdlib_linalg_schur
7979

8080
#:for rk, rt, ri in RC_KINDS_TYPES
8181
!> Workspace query
82-
subroutine get_schur_${ri}$_workspace(a,lwork,err)
82+
module subroutine get_schur_${ri}$_workspace(a,lwork,err)
8383
!> Input matrix a[m,m]
8484
${rt}$, intent(in), target :: a(:,:)
8585
!> Minimum workspace size for the decomposition operation
@@ -126,7 +126,7 @@ submodule (stdlib_linalg) stdlib_linalg_schur
126126
end subroutine get_schur_${ri}$_workspace
127127

128128
! Schur decomposition subroutine
129-
subroutine stdlib_linalg_${ri}$_schur(a, t, z, eigvals, storage, err)
129+
module subroutine stdlib_linalg_${ri}$_schur(a,t,z,eigvals,overwrite_a,storage,err)
130130
!> Input matrix a[m,m]
131131
${rt}$, intent(inout), target :: a(:,:)
132132
!> Schur form of A: upper-triangular or quasi-upper-triangular matrix T
@@ -137,11 +137,14 @@ submodule (stdlib_linalg) stdlib_linalg_schur
137137
complex(${rk}$), optional, intent(out), contiguous, target :: eigvals(:)
138138
!> [optional] Provide pre-allocated workspace, size to be checked with schur_space
139139
${rt}$, optional, intent(inout), target :: storage(:)
140+
!> [optional] Can A data be overwritten and destroyed?
141+
logical(lk), optional, intent(in) :: overwrite_a
140142
!> [optional] State return flag. On error if not requested, the code will stop
141143
type(linalg_state), optional, intent(out) :: err
142144

143145
! Local variables
144146
integer(ilp) :: m,n,mt,nt,ldvs,nvs,lde,lwork,sdim,info
147+
logical(lk) :: overwrite_a_
145148
logical(lk), target :: bwork_dummy(1),local_eigs
146149
logical(lk), pointer :: bwork(:)
147150
real(${rk}$), allocatable :: rwork(:)
@@ -172,6 +175,13 @@ submodule (stdlib_linalg) stdlib_linalg_schur
172175
!> Copy data into the output array
173176
t = a
174177

178+
! Can A be overwritten? By default, do not overwrite
179+
if (present(overwrite_a)) then
180+
overwrite_a_ = overwrite_a .and. n>=2
181+
else
182+
overwrite_a_ = .false._lk
183+
endif
184+
175185
!> SORTING: no sorting options are currently supported
176186
sort = gees_sort_eigs(.false.)
177187
sdim = 0_ilp
@@ -230,13 +240,26 @@ submodule (stdlib_linalg) stdlib_linalg_schur
230240
eigs => eigvals
231241
local_eigs = .false.
232242
#:else
233-
allocate(eigs(n),eigi(n))
243+
! use A storage if possible
244+
if (overwrite_a_) then
245+
eigs => a(:,1)
246+
eigi => a(:,2)
247+
else
248+
allocate(eigs(n),eigi(n))
249+
end if
234250
local_eigs = .true.
235251
#:endif
236252

237253
else
238254

239-
allocate(eigs(n)#{if rt.startswith('r')}#,eigi(n)#{endif}#)
255+
! Use A storage if possible
256+
if (overwrite_a_) then
257+
eigs => a(:,1)
258+
eigi => a(:,2)
259+
else
260+
allocate(eigs(n)#{if rt.startswith('r')}#,eigi(n)#{endif}#)
261+
end if
262+
240263
local_eigs = .true.
241264
lde = n
242265

@@ -261,10 +284,8 @@ submodule (stdlib_linalg) stdlib_linalg_schur
261284
#:if rt.startswith('r')
262285
! Build complex eigenvalues
263286
eigvals = cmplx(eigs,eigi,kind=${rk}$)
264-
deallocate(eigs,eigi)
265-
#:else
266-
deallocate(eigs)
267287
#:endif
288+
if (.not.overwrite_a_) deallocate(eigs#{if rt.startswith('r')}#,eigi#{endif}#)
268289
endif eigenvalue_output
269290
if (.not.present(storage)) deallocate(work)
270291
1 if (sort/=GEES_NOT) deallocate(bwork)

0 commit comments

Comments
 (0)