I’ve stumbled on a weird result of Lapack. Since the documentation states that “Wrong results from LAPACK routines are most often caused by incorrect usage” I am assuming that the problem lies in-between the keyboard and the chair (aka nel soramanego, for the Italian audience). I’m here using stdlib lapack but the problem is there with standard lapack as well.
The code is the following
PROGRAM test_dtrtrs
USE stdlib_kinds
USE stdlib_linalg_lapack
implicit none
integer :: n = 25
real(dp), allocatable, dimension(:,:) :: A, L, U
real(dp), allocatable, dimension(:) :: ones, x
integer :: i,j
integer :: ierr
integer :: info
allocate( A(n,n), L(n,n), U(n,n), ones(n), x(n), stat=ierr)
! construct lower triangular factor
L = 0._dp
do j = 1, n
do i = j, n
call random_number(L(i,j))
end do
end do
! construct upper triangular factor
U = transpose(L)
! construct matrix A = L*L^T (that is thus SPD)
A = matmul( L, U )
! test array
ones = 1._dp
! generate the rhs with known solution
x = matmul( A, ones )
! forward solve
call stdlib_dtrtrs( 'L', 'N', 'N', n, 1, L, n, x, n, info )
! backward solve
call stdlib_dtrtrs( 'L', 'T', 'N', n, 1, L, n, x, n, info )
! This should be all ones
print *, x
END PROGRAM test_dtrtrs
This code produces as expected an array of ones only for small n
s. For n=50
the result is never correct. Any Idea of what is going on and where I am making my mistakes?
The idea is that I can generate a “random” SPD matrix to test a pCG, and this kernel would be a preconditioner application (that usually is triangular for CG, to preserve SPD). Since my very easy test feeds the CG with the matrix A=LL^T and K=L for the preconditioner (applied as s=(LL^T)^{-1}w) the CG should do very few iterations since my preconditioner is the exact inverse of the coefficient matrix. Needless to say that it doesn’t work that way if the procedure is incorrect.
Thanks
Edit: corrected the call, tested, still diverging
Edit2: compiled with gfortran -I/...stdlib -O3 -g -fbounds-check -Wall -Wno-uninitialized -framework Accelerate -L/...stdlib test_trisolve.F90 -lfortran_stdlib -o main