@@ -79,7 +79,7 @@ submodule (stdlib_linalg) stdlib_linalg_schur
79
79
80
80
#:for rk, rt, ri in RC_KINDS_TYPES
81
81
!> Workspace query
82
- subroutine get_schur_${ri}$_workspace(a,lwork,err)
82
+ module subroutine get_schur_${ri}$_workspace(a,lwork,err)
83
83
!> Input matrix a[m,m]
84
84
${rt}$, intent(in), target :: a(:,:)
85
85
!> Minimum workspace size for the decomposition operation
@@ -126,7 +126,7 @@ submodule (stdlib_linalg) stdlib_linalg_schur
126
126
end subroutine get_schur_${ri}$_workspace
127
127
128
128
! 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)
130
130
!> Input matrix a[m,m]
131
131
${rt}$, intent(inout), target :: a(:,:)
132
132
!> Schur form of A: upper-triangular or quasi-upper-triangular matrix T
@@ -137,11 +137,14 @@ submodule (stdlib_linalg) stdlib_linalg_schur
137
137
complex(${rk}$), optional, intent(out), contiguous, target :: eigvals(:)
138
138
!> [optional] Provide pre-allocated workspace, size to be checked with schur_space
139
139
${rt}$, optional, intent(inout), target :: storage(:)
140
+ !> [optional] Can A data be overwritten and destroyed?
141
+ logical(lk), optional, intent(in) :: overwrite_a
140
142
!> [optional] State return flag. On error if not requested, the code will stop
141
143
type(linalg_state), optional, intent(out) :: err
142
144
143
145
! Local variables
144
146
integer(ilp) :: m,n,mt,nt,ldvs,nvs,lde,lwork,sdim,info
147
+ logical(lk) :: overwrite_a_
145
148
logical(lk), target :: bwork_dummy(1),local_eigs
146
149
logical(lk), pointer :: bwork(:)
147
150
real(${rk}$), allocatable :: rwork(:)
@@ -172,6 +175,13 @@ submodule (stdlib_linalg) stdlib_linalg_schur
172
175
!> Copy data into the output array
173
176
t = a
174
177
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
+
175
185
!> SORTING: no sorting options are currently supported
176
186
sort = gees_sort_eigs(.false.)
177
187
sdim = 0_ilp
@@ -230,13 +240,26 @@ submodule (stdlib_linalg) stdlib_linalg_schur
230
240
eigs => eigvals
231
241
local_eigs = .false.
232
242
#: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
234
250
local_eigs = .true.
235
251
#:endif
236
252
237
253
else
238
254
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
+
240
263
local_eigs = .true.
241
264
lde = n
242
265
@@ -261,10 +284,8 @@ submodule (stdlib_linalg) stdlib_linalg_schur
261
284
#:if rt.startswith('r')
262
285
! Build complex eigenvalues
263
286
eigvals = cmplx(eigs,eigi,kind=${rk}$)
264
- deallocate(eigs,eigi)
265
- #:else
266
- deallocate(eigs)
267
287
#:endif
288
+ if (.not.overwrite_a_) deallocate(eigs#{if rt.startswith('r')}#,eigi#{endif}#)
268
289
endif eigenvalue_output
269
290
if (.not.present(storage)) deallocate(work)
270
291
1 if (sort/=GEES_NOT) deallocate(bwork)
0 commit comments