Skip to content

Commit f725160

Browse files
committed
add test
1 parent 285aed2 commit f725160

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

test/linalg/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ set(
22
fppFiles
33
"test_linalg.fypp"
44
"test_blas_lapack.fypp"
5+
"test_linalg_lstsq.fypp"
56
"test_linalg_matrix_property_checks.fypp"
67
)
78
fypp_f90("${fyppFlags}" "${fppFiles}" outFiles)
89

910
ADDTEST(linalg)
1011
ADDTEST(linalg_matrix_property_checks)
12+
ADDTEST(linalg_lstsq)
1113
ADDTEST(blas_lapack)

test/linalg/test_linalg_lstsq.fypp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#:include "common.fypp"
2+
#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
3+
! Test least squares solver
4+
module test_linalg_least_squares
5+
use testdrive, only: error_type, check, new_unittest, unittest_type
6+
use stdlib_linalg_constants
7+
use stdlib_linalg, only: lstsq
8+
use stdlib_linalg_state, only: linalg_state_type
9+
10+
implicit none (type,external)
11+
private
12+
13+
public :: test_least_squares
14+
15+
contains
16+
17+
18+
!> Solve sample least squares problems
19+
subroutine test_least_squares(tests)
20+
!> Collection of tests
21+
type(unittest_type), allocatable, intent(out) :: tests(:)
22+
23+
allocate(tests(0))
24+
25+
#:for rk,rt,ri in REAL_KINDS_TYPES
26+
#:if rk!="xdp"
27+
tests = [tests,new_unittest("lease_squares_${ri}$",test_lstsq_one_${ri}$)]
28+
#:endif
29+
#:endfor
30+
31+
end subroutine test_least_squares
32+
33+
!> Simple polynomial fit
34+
#:for rk,rt,ri in REAL_KINDS_TYPES
35+
#:if rk!="xdp"
36+
subroutine test_lstsq_one_${ri}$(error)
37+
type(error_type), allocatable, intent(out) :: error
38+
39+
type(linalg_state_type) :: state
40+
integer(ilp) :: rank
41+
42+
!> Example scattered data
43+
${rt}$, parameter :: x(*) = real([1.0, 2.5, 3.5, 4.0, 5.0, 7.0, 8.5], ${rk}$)
44+
${rt}$, parameter :: y(*) = real([0.3, 1.1, 1.5, 2.0, 3.2, 6.6, 8.6], ${rk}$)
45+
${rt}$, parameter :: ab(*) = real([0.20925829, 0.12013861], ${rk}$)
46+
47+
${rt}$ :: M(size(x),2),p(2)
48+
49+
! Coefficient matrix for polynomial y = a + b*x**2
50+
M(:,1) = x**0
51+
M(:,2) = x**2
52+
53+
! Find polynomial
54+
p = lstsq(M,y,rank=rank,err=state)
55+
56+
call check(error,state%ok(),state%print())
57+
if (allocated(error)) return
58+
59+
call check(error, all(abs(p-ab)<1.0e-6_${rk}$), 'data converged')
60+
if (allocated(error)) return
61+
62+
call check(error, rank==2, 'matrix rank == 2')
63+
if (allocated(error)) return
64+
65+
end subroutine test_lstsq_one_${ri}$
66+
67+
#:endif
68+
#:endfor
69+
70+
end module test_linalg_least_squares
71+
72+
program test_lstsq
73+
use, intrinsic :: iso_fortran_env, only : error_unit
74+
use testdrive, only : run_testsuite, new_testsuite, testsuite_type
75+
use test_linalg_least_squares, only : test_least_squares
76+
implicit none
77+
integer :: stat, is
78+
type(testsuite_type), allocatable :: testsuites(:)
79+
character(len=*), parameter :: fmt = '("#", *(1x, a))'
80+
81+
stat = 0
82+
83+
testsuites = [ &
84+
new_testsuite("linalg_least_squares", test_least_squares) &
85+
]
86+
87+
do is = 1, size(testsuites)
88+
write(error_unit, fmt) "Testing:", testsuites(is)%name
89+
call run_testsuite(testsuites(is)%collect, error_unit, stat)
90+
end do
91+
92+
if (stat > 0) then
93+
write(error_unit, '(i0, 1x, a)') stat, "test(s) failed!"
94+
error stop
95+
end if
96+
end program test_lstsq

0 commit comments

Comments
 (0)