Skip to content

linalg: determinant #798

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 29 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4a4b899
import files
perazz Apr 13, 2024
d54cfa3
add `pure` interface
perazz Apr 13, 2024
c987fa1
add operator interface
perazz Apr 13, 2024
b9a3b0e
add tests
perazz Apr 13, 2024
4a29219
make `pure`
perazz Apr 13, 2024
3d05cc3
remove `xdp`
perazz Apr 13, 2024
4beab1f
Documentation
perazz Apr 13, 2024
15023e1
`submodule version`
perazz Apr 14, 2024
5923a54
Update src/stdlib_linalg.fypp
perazz Apr 15, 2024
31cdc84
Update src/stdlib_linalg.fypp
perazz Apr 15, 2024
45a606f
add `det` example
perazz Apr 15, 2024
cacb585
Update src/stdlib_linalg_determinant.fypp
perazz Apr 15, 2024
5c16ff8
Update src/stdlib_linalg_determinant.fypp
perazz Apr 15, 2024
ab030c5
Update src/stdlib_linalg_determinant.fypp
perazz Apr 15, 2024
13bd98a
warn about `xdp`
perazz Apr 15, 2024
7bf7141
Merge branch 'determinant' of github.com:perazz/stdlib into determinant
perazz Apr 15, 2024
504d90d
cleanup xdp notes
perazz Apr 15, 2024
e80b508
spacing
perazz Apr 15, 2024
c6076ea
relax error thresholds
perazz Apr 15, 2024
eaebe5c
restore `pure` attribute
perazz Apr 15, 2024
5d52d48
Update test/linalg/test_linalg_determinant.fypp
perazz Apr 15, 2024
cff995d
add docs
perazz Apr 21, 2024
2fe2428
link to specs
perazz Apr 21, 2024
45447a8
Update doc/specs/stdlib_linalg.md
perazz Apr 21, 2024
3ee20ad
Update doc/specs/stdlib_linalg.md
perazz Apr 21, 2024
1e50115
Update doc/specs/stdlib_linalg.md
perazz Apr 21, 2024
fe933ad
Update doc/specs/stdlib_linalg.md
perazz Apr 21, 2024
59dae89
Update doc/specs/stdlib_linalg.md
perazz Apr 21, 2024
3c72b06
Update doc/specs/stdlib_linalg.md
perazz Apr 21, 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
add tests
add tests

add test file
  • Loading branch information
perazz committed Apr 13, 2024
commit b9a3b0e939c49b1a38166dcee744c0c89180fd4d
2 changes: 1 addition & 1 deletion test/linalg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ set(
fypp_f90("${fyppFlags}" "${fppFiles}" outFiles)

ADDTEST(linalg)
ADDTEST(linalg_determinant)
ADDTEST(linalg_matrix_property_checks)
ADDTEST(blas_lapack)
ADDTEST(linalg_determinant)
121 changes: 75 additions & 46 deletions test/linalg/test_linalg_determinant.fypp
Original file line number Diff line number Diff line change
@@ -1,47 +1,42 @@
#:include "common.fypp"
#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
! Test matrix determinant
module test_linalg_determinant
use stdlib_linalg_interface
use testdrive, only: error_type, check, new_unittest, unittest_type
use stdlib_linalg_constants
use stdlib_linalg, only: eye, det, linalg_state_type

implicit none (type,external)
private

public :: test_matrix_determinant

contains


!> Matrix inversion tests
subroutine test_matrix_determinant(error)
logical, intent(out) :: error

real :: t0,t1

call cpu_time(t0)

#:for rk,rt,ri in ALL_KINDS_TYPES
call test_${ri}$_eye_determinant(error)
if (error) return

call test_${ri}$_eye_multiple(error)
if (error) return
#: endfor

#:for ck,ct,ci in CMPL_KINDS_TYPES
call test_${ci}$_complex_determinant(error)
if (error) return
subroutine test_matrix_determinant(tests)
!> Collection of tests
type(unittest_type), allocatable, intent(out) :: tests(:)

allocate(tests(0))

#:for rk,rt in RC_KINDS_TYPES
tests = [tests,new_unittest("$eye_det_${rt[0]}$${rk}$",test_${rt[0]}$${rk}$_eye_determinant)]
tests = [tests,new_unittest("$eye_det_multiple_${rt[0]}$${rk}$",test_${rt[0]}$${rk}$_eye_multiple)]
#:endfor
#:for ck,ct in CMPLX_KINDS_TYPES
tests = [tests,new_unittest("$complex_det_${rt[0]}$${rk}$",test_${ct[0]}$${ck}$_complex_determinant)]
#: endfor

call cpu_time(t1)

print 1, 1000*(t1-t0), merge('SUCCESS','ERROR ',.not.error)

1 format('Determinant tests completed in ',f9.4,' milliseconds, result=',a)

end subroutine test_matrix_determinant

!> Determinant of identity matrix
#:for rk,rt,ri in ALL_KINDS_TYPES
subroutine test_${ri}$_eye_determinant(error)
logical, intent(out) :: error
#:for rk,rt in RC_KINDS_TYPES
subroutine test_${rt[0]}$${rk}$_eye_determinant(error)
type(error_type), allocatable, intent(out) :: error

type(linalg_state) :: state
type(linalg_state_type) :: state

integer(ilp) :: i
integer(ilp), parameter :: n = 128_ilp
Expand All @@ -52,16 +47,19 @@ module test_linalg_determinant

!> Determinant function
deta = det(a,err=state)
error = state%error() .or. .not.abs(deta-1.0_${rk}$)<tiny(0.0_${rk}$)
if (error) return

end subroutine test_${ri}$_eye_determinant

call check(error,state%ok(),state%print())
if (allocated(error)) return

call check(error, abs(deta-1.0_${rk}$)<tiny(0.0_${rk}$), 'det(eye(n))==1')

end subroutine test_${rt[0]}$${rk}$_eye_determinant

!> Determinant of identity matrix multiplier
subroutine test_${ri}$_eye_multiple(error)
logical, intent(out) :: error
subroutine test_${rt[0]}$${rk}$_eye_multiple(error)
type(error_type), allocatable, intent(out) :: error

type(linalg_state) :: state
type(linalg_state_type) :: state

integer(ilp), parameter :: n = 10_ilp
real(${rk}$), parameter :: coef = 0.0001_${rk}$
Expand All @@ -76,19 +74,22 @@ module test_linalg_determinant

!> Determinant: small, but a is not singular, because it is a multiple of the identity.
deta = det(a,err=state)
error = state%error() .or. .not.abs(deta-coef**n)<max(tiny(0.0_${rk}$),epsilon(0.0_${rk}$)*coef**n)
if (error) return
call check(error,state%ok(),state%print())
if (allocated(error)) return

call check(error, abs(deta-coef**n)<max(tiny(0.0_${rk}$),epsilon(0.0_${rk}$)*coef**n), &
'det(0.0001*eye(n))==0.0001^n')

end subroutine test_${ri}$_eye_multiple
end subroutine test_${rt[0]}$${rk}$_eye_multiple

#:endfor

!> Determinant of complex identity matrix
#:for ck,ct,ci in CMPL_KINDS_TYPES
subroutine test_${ci}$_complex_determinant(error)
logical, intent(out) :: error
#:for ck,ct in CMPLX_KINDS_TYPES
subroutine test_${ct[0]}$${ck}$_complex_determinant(error)
type(error_type), allocatable, intent(out) :: error

type(linalg_state) :: state
type(linalg_state_type) :: state

integer(ilp) :: i,j,n
integer(ilp), parameter :: nmax = 10_ilp
Expand Down Expand Up @@ -116,12 +117,40 @@ module test_linalg_determinant

end do matrix_size

error = state%error() .or. any(.not.abs(res-deta)<=tiny(0.0_${ck}$))
call check(error,state%ok(),state%print())
if (allocated(error)) return

call check(error, all(abs(res-deta)<=tiny(0.0_${ck}$)), &
'det((1+i)*eye(n)) does not match result')

end subroutine test_${ci}$_complex_determinant
end subroutine test_${ct[0]}$${ck}$_complex_determinant

#:endfor

end module test_linalg_determinant


program test_det
use, intrinsic :: iso_fortran_env, only : error_unit
use testdrive, only : run_testsuite, new_testsuite, testsuite_type
use test_linalg_determinant, only : test_matrix_determinant
implicit none
integer :: stat, is
type(testsuite_type), allocatable :: testsuites(:)
character(len=*), parameter :: fmt = '("#", *(1x, a))'

stat = 0

testsuites = [ &
new_testsuite("linalg_determinant", test_matrix_determinant) &
]

do is = 1, size(testsuites)
write(error_unit, fmt) "Testing:", testsuites(is)%name
call run_testsuite(testsuites(is)%collect, error_unit, stat)
end do

if (stat > 0) then
write(error_unit, '(i0, 1x, a)') stat, "test(s) failed!"
error stop
end if
end program