Skip to content

linalg: Eigenvalues and Eigenvectors #816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Jun 30, 2024
Merged
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
7d390f7
add source
perazz May 16, 2024
430c89c
remove `goto`s
perazz May 16, 2024
7645a45
exclude unsupported `xdp`
perazz May 16, 2024
6ce5172
submodule
perazz May 16, 2024
2d58c68
add tests
perazz May 16, 2024
15b73fc
test: remove `xdp`
perazz May 16, 2024
b5f7f21
add examples: `eig`, `eigh`, `eigvals`, `eigvalsh`
perazz May 16, 2024
892308f
fix: `module` procedures
perazz May 16, 2024
1ebf374
add documentation
perazz May 16, 2024
f9279b3
specs: `eig`, `eigh`
perazz May 16, 2024
56d89a8
specs: `eigvals`, `eigvalsh`
perazz May 16, 2024
f13e75d
clarify svd
perazz Jun 5, 2024
34bb7d7
Update doc/specs/stdlib_linalg.md
perazz Jun 5, 2024
cdef45f
remove `(sp)` from the examples
perazz Jun 5, 2024
fe1c89e
Update doc/specs/stdlib_linalg.md
perazz Jun 5, 2024
65099e3
Update doc/specs/stdlib_linalg.md
perazz Jun 5, 2024
0e13fe5
kind -> precision
perazz Jun 5, 2024
d0f385a
Update doc/specs/stdlib_linalg.md
perazz Jun 5, 2024
acd93b9
Merge branch 'eigenvalues' of github.com:perazz/stdlib into eigenvalues
perazz Jun 5, 2024
36c8d5a
fix `sp` in example
perazz Jun 5, 2024
e6aa0f5
Option to output `real` eigenvalues only
perazz Jun 5, 2024
17ebed2
reorganize `if(present(x))`
perazz Jun 21, 2024
bac3187
no negated checks
perazz Jun 21, 2024
4f503f7
copy_a: simplify
perazz Jun 21, 2024
34284cb
Merge branch 'master' into eigenvalues
perazz Jun 21, 2024
f232a76
typo
perazz Jun 21, 2024
d19425a
fix intel `module subroutine` error
perazz Jun 21, 2024
cc95fc4
Update doc/specs/stdlib_linalg.md
perazz Jun 26, 2024
18b95af
Update doc/specs/stdlib_linalg.md
perazz Jun 26, 2024
1fb2ba9
Update doc/specs/stdlib_linalg.md
perazz Jun 26, 2024
f5303bf
Update doc/specs/stdlib_linalg.md
perazz Jun 26, 2024
66f1f17
Update doc/specs/stdlib_linalg.md
perazz Jun 26, 2024
5501b83
example_eigh: v->vectors
perazz Jun 26, 2024
59f3b34
Merge branch 'eigenvalues' of github.com:perazz/stdlib into eigenvalues
perazz Jun 26, 2024
d433869
fix vectors
perazz Jun 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix intel module subroutine error
  • Loading branch information
perazz committed Jun 21, 2024
commit d19425ab99d8f9e912bf6707f08ff893b54297d7
82 changes: 41 additions & 41 deletions src/stdlib_linalg_eigenvalues.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -309,47 +309,6 @@ submodule (stdlib_linalg) stdlib_linalg_eigenvalues

end subroutine stdlib_linalg_eig_${ri}$

module subroutine stdlib_linalg_real_eig_${ri}$(a,lambda,right,left,overwrite_a,err)
!! Eigendecomposition of matrix A returning an array `lambda` of real eigenvalues,
!! and optionally right or left eigenvectors. Returns an error if the eigenvalues had
!! non-trivial imaginary parts.
!> Input matrix A[m,n]
${rt}$, intent(inout), target :: a(:,:)
!> Array of real eigenvalues
real(${rk}$), intent(out) :: lambda(:)
!> The columns of RIGHT contain the right eigenvectors of A
complex(${rk}$), optional, intent(out), target :: right(:,:)
!> The columns of LEFT contain the left eigenvectors of A
complex(${rk}$), optional, intent(out), target :: left(:,:)
!> [optional] Can A data be overwritten and destroyed?
logical(lk), optional, intent(in) :: overwrite_a
!> [optional] state return flag. On error if not requested, the code will stop
type(linalg_state_type), optional, intent(out) :: err

type(linalg_state_type) :: err0
integer(ilp) :: n
complex(${rk}$), allocatable :: clambda(:)
real(${rk}$), parameter :: rtol = epsilon(0.0_${rk}$)
real(${rk}$), parameter :: atol = tiny(0.0_${rk}$)

n = size(lambda,dim=1,kind=ilp)
allocate(clambda(n))

call stdlib_linalg_eig_${ri}$(a,clambda,right,left,overwrite_a,err0)

! Check that no eigenvalues have meaningful imaginary part
if (err0%ok() .and. any(aimag(clambda)>atol+rtol*abs(abs(clambda)))) then
err0 = linalg_state_type(this,LINALG_VALUE_ERROR, &
'complex eigenvalues detected: max(imag(lambda))=',maxval(aimag(clambda)))
endif

! Return real components only
lambda(:n) = real(clambda,kind=${rk}$)

call linalg_error_handling(err0,err)

end subroutine stdlib_linalg_real_eig_${ri}$

module function stdlib_linalg_eigvalsh_${ri}$(a,upper_a,err) result(lambda)
!! Return an array of eigenvalues of real symmetric / complex hermitian A
!> Input matrix A[m,n]
Expand Down Expand Up @@ -566,6 +525,47 @@ submodule (stdlib_linalg) stdlib_linalg_eigenvalues

end subroutine assign_real_eigenvectors_${rk}$

module subroutine stdlib_linalg_real_eig_${ri}$(a,lambda,right,left,overwrite_a,err)
!! Eigendecomposition of matrix A returning an array `lambda` of real eigenvalues,
!! and optionally right or left eigenvectors. Returns an error if the eigenvalues had
!! non-trivial imaginary parts.
!> Input matrix A[m,n]
${rt}$, intent(inout), target :: a(:,:)
!> Array of real eigenvalues
real(${rk}$), intent(out) :: lambda(:)
!> The columns of RIGHT contain the right eigenvectors of A
complex(${rk}$), optional, intent(out), target :: right(:,:)
!> The columns of LEFT contain the left eigenvectors of A
complex(${rk}$), optional, intent(out), target :: left(:,:)
!> [optional] Can A data be overwritten and destroyed?
logical(lk), optional, intent(in) :: overwrite_a
!> [optional] state return flag. On error if not requested, the code will stop
type(linalg_state_type), optional, intent(out) :: err

type(linalg_state_type) :: err0
integer(ilp) :: n
complex(${rk}$), allocatable :: clambda(:)
real(${rk}$), parameter :: rtol = epsilon(0.0_${rk}$)
real(${rk}$), parameter :: atol = tiny(0.0_${rk}$)

n = size(lambda,dim=1,kind=ilp)
allocate(clambda(n))

call stdlib_linalg_eig_${ri}$(a,clambda,right,left,overwrite_a,err0)

! Check that no eigenvalues have meaningful imaginary part
if (err0%ok() .and. any(aimag(clambda)>atol+rtol*abs(abs(clambda)))) then
err0 = linalg_state_type(this,LINALG_VALUE_ERROR, &
'complex eigenvalues detected: max(imag(lambda))=',maxval(aimag(clambda)))
endif

! Return real components only
lambda(:n) = real(clambda,kind=${rk}$)

call linalg_error_handling(err0,err)

end subroutine stdlib_linalg_real_eig_${ri}$

#:endif
#:endfor

Expand Down
Loading