1
1
#:include "common.fypp"
2
+ #:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
2
3
! Test matrix determinant
3
4
module test_linalg_determinant
4
- use stdlib_linalg_interface
5
+ use testdrive, only: error_type, check, new_unittest, unittest_type
6
+ use stdlib_linalg_constants
7
+ use stdlib_linalg, only: eye, det, linalg_state_type
5
8
6
9
implicit none (type,external)
10
+ private
11
+
12
+ public :: test_matrix_determinant
7
13
8
14
contains
15
+
9
16
10
17
!> Matrix inversion tests
11
- subroutine test_matrix_determinant(error)
12
- logical, intent(out) :: error
13
-
14
- real :: t0,t1
15
-
16
- call cpu_time(t0)
17
-
18
- #:for rk,rt,ri in ALL_KINDS_TYPES
19
- call test_${ri}$_eye_determinant(error)
20
- if (error) return
21
-
22
- call test_${ri}$_eye_multiple(error)
23
- if (error) return
24
- #: endfor
25
-
26
- #:for ck,ct,ci in CMPL_KINDS_TYPES
27
- call test_${ci}$_complex_determinant(error)
28
- if (error) return
18
+ subroutine test_matrix_determinant(tests)
19
+ !> Collection of tests
20
+ type(unittest_type), allocatable, intent(out) :: tests(:)
21
+
22
+ allocate(tests(0))
23
+
24
+ #:for rk,rt in RC_KINDS_TYPES
25
+ tests = [tests,new_unittest("$eye_det_${rt[0]}$${rk}$",test_${rt[0]}$${rk}$_eye_determinant)]
26
+ tests = [tests,new_unittest("$eye_det_multiple_${rt[0]}$${rk}$",test_${rt[0]}$${rk}$_eye_multiple)]
27
+ #:endfor
28
+ #:for ck,ct in CMPLX_KINDS_TYPES
29
+ tests = [tests,new_unittest("$complex_det_${rt[0]}$${rk}$",test_${ct[0]}$${ck}$_complex_determinant)]
29
30
#: endfor
30
31
31
- call cpu_time(t1)
32
-
33
- print 1, 1000*(t1-t0), merge('SUCCESS','ERROR ',.not.error)
34
-
35
- 1 format('Determinant tests completed in ',f9.4,' milliseconds, result=',a)
36
-
37
32
end subroutine test_matrix_determinant
38
33
39
34
!> Determinant of identity matrix
40
- #:for rk,rt,ri in ALL_KINDS_TYPES
41
- subroutine test_${ri }$_eye_determinant(error)
42
- logical , intent(out) :: error
35
+ #:for rk,rt in RC_KINDS_TYPES
36
+ subroutine test_${rt[0]}$${rk }$_eye_determinant(error)
37
+ type(error_type), allocatable , intent(out) :: error
43
38
44
- type(linalg_state ) :: state
39
+ type(linalg_state_type ) :: state
45
40
46
41
integer(ilp) :: i
47
42
integer(ilp), parameter :: n = 128_ilp
@@ -52,16 +47,19 @@ module test_linalg_determinant
52
47
53
48
!> Determinant function
54
49
deta = det(a,err=state)
55
- error = state%error() .or. .not.abs(deta-1.0_${rk}$)<tiny(0.0_${rk}$)
56
- if (error) return
57
-
58
- end subroutine test_${ri}$_eye_determinant
50
+
51
+ call check(error,state%ok(),state%print())
52
+ if (allocated(error)) return
53
+
54
+ call check(error, abs(deta-1.0_${rk}$)<tiny(0.0_${rk}$), 'det(eye(n))==1')
55
+
56
+ end subroutine test_${rt[0]}$${rk}$_eye_determinant
59
57
60
58
!> Determinant of identity matrix multiplier
61
- subroutine test_${ri }$_eye_multiple(error)
62
- logical , intent(out) :: error
59
+ subroutine test_${rt[0]}$${rk }$_eye_multiple(error)
60
+ type(error_type), allocatable , intent(out) :: error
63
61
64
- type(linalg_state ) :: state
62
+ type(linalg_state_type ) :: state
65
63
66
64
integer(ilp), parameter :: n = 10_ilp
67
65
real(${rk}$), parameter :: coef = 0.0001_${rk}$
@@ -76,19 +74,22 @@ module test_linalg_determinant
76
74
77
75
!> Determinant: small, but a is not singular, because it is a multiple of the identity.
78
76
deta = det(a,err=state)
79
- error = state%error() .or. .not.abs(deta-coef**n)<max(tiny(0.0_${rk}$),epsilon(0.0_${rk}$)*coef**n)
80
- if (error) return
77
+ call check(error,state%ok(),state%print())
78
+ if (allocated(error)) return
79
+
80
+ call check(error, abs(deta-coef**n)<max(tiny(0.0_${rk}$),epsilon(0.0_${rk}$)*coef**n), &
81
+ 'det(0.0001*eye(n))==0.0001^n')
81
82
82
- end subroutine test_${ri }$_eye_multiple
83
+ end subroutine test_${rt[0]}$${rk }$_eye_multiple
83
84
84
85
#:endfor
85
86
86
87
!> Determinant of complex identity matrix
87
- #:for ck,ct,ci in CMPL_KINDS_TYPES
88
- subroutine test_${ci }$_complex_determinant(error)
89
- logical , intent(out) :: error
88
+ #:for ck,ct in CMPLX_KINDS_TYPES
89
+ subroutine test_${ct[0]}$${ck }$_complex_determinant(error)
90
+ type(error_type), allocatable , intent(out) :: error
90
91
91
- type(linalg_state ) :: state
92
+ type(linalg_state_type ) :: state
92
93
93
94
integer(ilp) :: i,j,n
94
95
integer(ilp), parameter :: nmax = 10_ilp
@@ -116,12 +117,40 @@ module test_linalg_determinant
116
117
117
118
end do matrix_size
118
119
119
- error = state%error() .or. any(.not.abs(res-deta)<=tiny(0.0_${ck}$))
120
+ call check(error,state%ok(),state%print())
121
+ if (allocated(error)) return
122
+
123
+ call check(error, all(abs(res-deta)<=tiny(0.0_${ck}$)), &
124
+ 'det((1+i)*eye(n)) does not match result')
120
125
121
- end subroutine test_${ci }$_complex_determinant
126
+ end subroutine test_${ct[0]}$${ck }$_complex_determinant
122
127
123
128
#:endfor
124
129
125
130
end module test_linalg_determinant
126
131
127
-
132
+ program test_det
133
+ use, intrinsic :: iso_fortran_env, only : error_unit
134
+ use testdrive, only : run_testsuite, new_testsuite, testsuite_type
135
+ use test_linalg_determinant, only : test_matrix_determinant
136
+ implicit none
137
+ integer :: stat, is
138
+ type(testsuite_type), allocatable :: testsuites(:)
139
+ character(len=*), parameter :: fmt = '("#", *(1x, a))'
140
+
141
+ stat = 0
142
+
143
+ testsuites = [ &
144
+ new_testsuite("linalg_determinant", test_matrix_determinant) &
145
+ ]
146
+
147
+ do is = 1, size(testsuites)
148
+ write(error_unit, fmt) "Testing:", testsuites(is)%name
149
+ call run_testsuite(testsuites(is)%collect, error_unit, stat)
150
+ end do
151
+
152
+ if (stat > 0) then
153
+ write(error_unit, '(i0, 1x, a)') stat, "test(s) failed!"
154
+ error stop
155
+ end if
156
+ end program
0 commit comments