@@ -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