Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
06bfe4b
templated BLAS/LAPACK initials
perazz Apr 25, 2024
a2afe6b
base implementation
perazz Apr 25, 2024
d929077
exclude `xdp`
perazz Apr 25, 2024
5c817c8
`pure` interfaces
perazz Apr 25, 2024
4cef2ac
cleanup names
perazz Apr 25, 2024
7b7c051
submodule
perazz Apr 25, 2024
0be918e
`real` and `complex` tests
perazz Apr 25, 2024
9906c93
add `real` and `complex` examples
perazz Apr 26, 2024
a5d1b8a
add specs
perazz Apr 26, 2024
c1365ff
document interface
perazz Apr 26, 2024
af70ff9
Merge branch 'master' into linalg_solve
perazz Apr 26, 2024
3de6834
fix resolve conflict
perazz Apr 26, 2024
04f126d
Update doc/specs/stdlib_linalg.md
perazz Apr 27, 2024
7ae0510
Update doc/specs/stdlib_linalg.md
perazz Apr 27, 2024
ed135d9
Update doc/specs/stdlib_linalg.md
perazz Apr 30, 2024
e9bf020
Update doc/specs/stdlib_linalg.md
perazz Apr 30, 2024
3265f8f
Update src/stdlib_linalg.fypp
perazz Apr 30, 2024
77fc5bd
Update doc/specs/stdlib_linalg.md
perazz Apr 30, 2024
b04b3d9
Update doc/specs/stdlib_linalg.md
perazz Apr 30, 2024
8d5e682
Update src/stdlib_linalg_solve.fypp
perazz Apr 30, 2024
4458b88
fix test
perazz Apr 30, 2024
bc13246
Merge branch 'linalg_solve' of github.com:perazz/stdlib into linalg_s…
perazz Apr 30, 2024
316c44a
implement `subroutine` interface
perazz Apr 30, 2024
04f1465
Merge branch 'fortran-lang:master' into linalg_solve
perazz May 8, 2024
5e0620c
specify full-rank
perazz May 9, 2024
c9f5f0c
document `solve_lu`
perazz May 9, 2024
e75bb2f
add `solve_lu` test
perazz May 9, 2024
449d0a2
add pivot
perazz May 9, 2024
b288520
cleanup subroutine example; add preallocated pivot
perazz May 9, 2024
7aab844
document `solve_lu` interface
perazz May 9, 2024
da16d0f
Merge branch 'master' into linalg_solve
perazz May 9, 2024
a05809e
typo
perazz May 9, 2024
5832df5
avoid 128-bit random numbers
perazz May 9, 2024
File filter

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
real and complex tests
  • Loading branch information
perazz committed Apr 25, 2024
commit 0be918eb873c540213dae5c985659d2bd84afd52
2 changes: 2 additions & 0 deletions test/linalg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ set(
fppFiles
"test_linalg.fypp"
"test_blas_lapack.fypp"
"test_linalg_solve.fypp"
"test_linalg_matrix_property_checks.fypp"
)
fypp_f90("${fyppFlags}" "${fppFiles}" outFiles)

ADDTEST(linalg)
ADDTEST(linalg_matrix_property_checks)
ADDTEST(linalg_solve)
ADDTEST(blas_lapack)
190 changes: 190 additions & 0 deletions test/linalg/test_linalg_solve.fypp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#:include "common.fypp"
#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
! Test linear system solver
module test_linalg_solve
use stdlib_linalg_constants
use stdlib_linalg_state
use stdlib_linalg, only: solve
use testdrive, only: error_type, check, new_unittest, unittest_type

implicit none (type,external)
private

public :: test_linear_systems

contains

!> Solve real and complex linear systems
subroutine test_linear_systems(tests)
!> Collection of tests
type(unittest_type), allocatable, intent(out) :: tests(:)

allocate(tests(0))

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if rk!="xdp"
tests = [tests,new_unittest("solve_${ri}$",test_${ri}$_solve), &
new_unittest("solve_${ri}$_multiple",test_${ri}$_solve_multiple)]
#:endif
#:endfor

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if ck!="xdp"
tests = [tests,new_unittest("solve_complex_${ci}$",test_${ci}$_solve), &
new_unittest("solve_2x2_complex_${ci}$",test_2x2_${ci}$_solve)]
#:endif
#:endfor

end subroutine test_linear_systems

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if rk!="xdp"
!> Simple linear system
subroutine test_${ri}$_solve(error)
type(error_type), allocatable, intent(out) :: error

type(linalg_state_type) :: state

${rt}$ :: A(3,3) = transpose(reshape([${rt}$ :: 1, 3, 3, &
1, 3, 4, &
1, 4, 3], [3,3]))
${rt}$ :: b (3) = [${rt}$ :: 1, 4, -1]
${rt}$ :: res(3) = [${rt}$ :: -2, -2, 3]
${rt}$ :: x(3)

x = solve(a,b,err=state)

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

call check(error, all(abs(x-res)<abs(res*epsilon(0.0_${rk}$))), 'results match expected')
if (allocated(error)) return

end subroutine test_${ri}$_solve

!> Simple linear system with multiple right hand sides
subroutine test_${ri}$_solve_multiple(error)
type(error_type), allocatable, intent(out) :: error

type(linalg_state_type) :: state

${rt}$ :: A(3,3) = transpose(reshape([${rt}$ :: 1,-1, 2, &
0, 1, 1, &
1,-1, 3], [3,3]))
${rt}$ :: b(3,3) = transpose(reshape([${rt}$ :: 0, 1, 2, &
1,-2,-1, &
2, 3,-1], [3,3]))
${rt}$ :: res(3,3) = transpose(reshape([${rt}$ ::-5,-7,10, &
-1,-4, 2, &
2, 2,-3], [3,3]))
${rt}$ :: x(3,3)

x = solve(a,b,err=state)

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

call check(error, all(abs(x-res)<abs(res*epsilon(0.0_${rk}$))), 'results match expected')
if (allocated(error)) return

end subroutine test_${ri}$_solve_multiple
#:endif
#:endfor

#:for rk,rt,ri in CMPLX_KINDS_TYPES
#:if rk!="xdp"
!> Complex linear system
!> Militaru, Popa, "On the numerical solving of complex linear systems",
!> Int J Pure Appl Math 76(1), 113-122, 2012.
subroutine test_${ri}$_solve(error)
type(error_type), allocatable, intent(out) :: error

type(linalg_state_type) :: state

${rt}$ :: A(5,5), b(5), res(5), x(5)
integer(ilp) :: i

! Fill in linear system
A = (0.0_${rk}$,0.0_${rk}$)

A(1:2,1) = [(19.73_${rk}$,0.0_${rk}$),(0.0_${rk}$,-0.51_${rk}$)]
A(1:3,2) = [(12.11_${rk}$,-1.0_${rk}$),(32.3_${rk}$,7.0_${rk}$),(0.0_${rk}$,-0.51_${rk}$)]
A(1:4,3) = [(0.0_${rk}$,5.0_${rk}$),(23.07_${rk}$,0.0_${rk}$),(70.0_${rk}$,7.3_${rk}$),(1.0_${rk}$,1.1_${rk}$)]
A(2:5,4) = [(0.0_${rk}$,1.0_${rk}$),(3.95_${rk}$,0.0_${rk}$),(50.17_${rk}$,0.0_${rk}$),(0.0_${rk}$,-9.351_${rk}$)]
A(3:5,5) = [(19.0_${rk}$,31.83_${rk}$),(45.51_${rk}$,0.0_${rk}$),(55.0_${rk}$,0.0_${rk}$)]

b = [(77.38_${rk}$,8.82_${rk}$),(157.48_${rk}$,19.8_${rk}$),(1175.62_${rk}$,20.69_${rk}$),(912.12_${rk}$,-801.75_${rk}$),(550.0_${rk}$,-1060.4_${rk}$)]

! Exact result
res = [(3.3_${rk}$,-1.0_${rk}$),(1.0_${rk}$,0.17_${rk}$),(5.5_${rk}$,0.0_${rk}$),(9.0_${rk}$,0.0_${rk}$),(10.0_${rk}$,-17.75_${rk}$)]

x = solve(a,b,err=state)

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

call check(error, all(abs(x-res)<abs(res)*1.0e-3_${rk}$), 'results match expected')
if (allocated(error)) return

end subroutine test_${ri}$_solve

!> 2x2 Complex linear system
!> https://math.stackexchange.com/questions/1996540/solving-linear-equation-systems-with-complex-coefficients-and-variables
subroutine test_2x2_${ri}$_solve(error)
type(error_type), allocatable, intent(out) :: error

type(linalg_state_type) :: state

${rt}$ :: A(2,2), b(2), res(2), x(2)
integer(ilp) :: i

! Fill in linear system
A(1,:) = [(+1.0_${rk}$,+1.0_${rk}$),(-1.0_${rk}$,0.0_${rk}$)]
A(2,:) = [(+1.0_${rk}$,-1.0_${rk}$),(+1.0_${rk}$,1.0_${rk}$)]

b = [(0.0_${rk}$,1.0_${rk}$),(1.0_${rk}$,0.0_${rk}$)]

! Exact result
res = [(0.5_${rk}$,0.5_${rk}$),(0.0_${rk}$,0.0_${rk}$)]

x = solve(a,b,err=state)

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

call check(error, all(abs(x-res)<max(tiny(0.0_${rk}$),abs(res)*epsilon(0.0_${rk}$))), 'results match expected')
if (allocated(error)) return


end subroutine test_2x2_${ri}$_solve
#:endif
#:endfor

end module test_linalg_solve

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

stat = 0

testsuites = [ &
new_testsuite("linalg_solve", test_linear_systems) &
]

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 test_solve