Skip to content

Commit d23b817

Browse files
committed
Fix loop variable bugs in LINPACK regression tests
Fixed multiple loop variable reuse bugs in local LINPACK implementations: - dgefa_local: Changed inner loop variable from 'l' to 'i' to avoid corrupting pivot index - dgesl_local: Same fix for inner loop variable collision - dpofa_local: Changed loop variable from 'info' to 'i' (info is output param) - dposl_local: Complete rewrite with proper loop variables (was using real 't' and integer 'k' incorrectly) All 6 LINPACK tests now pass: - DGEFA/DGESL: 3 tests (2x2 system, identity, Hilbert 3x3) - DPOFA/DPOSL: 3 tests (2x2 SPD, identity, diagonal)
1 parent 21483f4 commit d23b817

1 file changed

Lines changed: 23 additions & 25 deletions

File tree

test/level1_regression/test_l1_linear_linpack.f90.wip renamed to test/level1_regression/test_l1_linear_linpack.f90

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ subroutine dgefa_local(a, lda, n, ipvt, info)
247247
integer, intent(in) :: lda, n
248248
real(dp), intent(inout) :: a(lda,*)
249249
integer, intent(out) :: ipvt(*), info
250-
integer :: j, k, l
250+
integer :: i, j, k, l
251251
real(dp) :: t
252252

253253
info = 0
@@ -281,8 +281,8 @@ subroutine dgefa_local(a, lda, n, ipvt, info)
281281
if (l /= k) then
282282
a(l,j) = a(k,j); a(k,j) = t
283283
end if
284-
do l = k+1, n
285-
a(l,j) = a(l,j) + t * a(l,k)
284+
do i = k+1, n
285+
a(i,j) = a(i,j) + t * a(i,k)
286286
end do
287287
end do
288288
end do
@@ -296,7 +296,7 @@ subroutine dgesl_local(a, lda, n, ipvt, b, job)
296296
real(dp), intent(in) :: a(lda,*)
297297
integer, intent(in) :: ipvt(*)
298298
real(dp), intent(inout) :: b(*)
299-
integer :: k, l
299+
integer :: i, k, l
300300
real(dp) :: t
301301

302302
if (job == 0) then
@@ -308,17 +308,17 @@ subroutine dgesl_local(a, lda, n, ipvt, b, job)
308308
if (l /= k) then
309309
b(l) = b(k); b(k) = t
310310
end if
311-
do l = k+1, n
312-
b(l) = b(l) + t * a(l,k)
311+
do i = k+1, n
312+
b(i) = b(i) + t * a(i,k)
313313
end do
314314
end do
315315

316316
! Back substitution
317317
do k = n, 1, -1
318318
b(k) = b(k) / a(k,k)
319319
t = -b(k)
320-
do l = 1, k-1
321-
b(l) = b(l) + t * a(l,k)
320+
do i = 1, k-1
321+
b(i) = b(i) + t * a(i,k)
322322
end do
323323
end do
324324
end if
@@ -329,15 +329,15 @@ subroutine dpofa_local(a, lda, n, info)
329329
integer, intent(in) :: lda, n
330330
real(dp), intent(inout) :: a(lda,*)
331331
integer, intent(out) :: info
332-
integer :: j, k
332+
integer :: j, k, i
333333
real(dp) :: s, t
334334

335335
do j = 1, n
336336
s = 0.0_dp
337337
do k = 1, j-1
338338
t = a(k,j)
339-
do info = 1, k-1
340-
t = t - a(info,k) * a(info,j)
339+
do i = 1, k-1
340+
t = t - a(i,k) * a(i,j)
341341
end do
342342
t = t / a(k,k)
343343
a(k,j) = t
@@ -354,33 +354,31 @@ subroutine dpofa_local(a, lda, n, info)
354354
end subroutine
355355

356356
! DPOSL: Solve using Cholesky factorization
357+
! Solves A*x = b where A = L*L' and L is stored in upper triangle of a
357358
subroutine dposl_local(a, lda, n, b)
358359
integer, intent(in) :: lda, n
359360
real(dp), intent(in) :: a(lda,*)
360361
real(dp), intent(inout) :: b(*)
361-
integer :: k
362+
integer :: k, j
362363
real(dp) :: t
363364

364-
! Solve L*y = b
365+
! Forward substitution: Solve L*y = b
366+
! L is stored as L(j,k) = a(j,k) for j <= k
365367
do k = 1, n
366368
t = 0.0_dp
367-
do t = 1, k-1
368-
! This is wrong - need to fix
369+
do j = 1, k-1
370+
t = t + a(j,k) * b(j)
369371
end do
370-
t = b(k)
371-
do k = 1, k-1
372-
! Also wrong
373-
end do
374-
b(k) = b(k) / a(k,k)
372+
b(k) = (b(k) - t) / a(k,k)
375373
end do
376374

377-
! Solve L'*x = y
375+
! Back substitution: Solve L'*x = y
378376
do k = n, 1, -1
379-
b(k) = b(k) / a(k,k)
380-
t = -b(k)
381-
do k = 1, k-1
382-
! Fix needed
377+
t = 0.0_dp
378+
do j = k+1, n
379+
t = t + a(k,j) * b(j)
383380
end do
381+
b(k) = (b(k) - t) / a(k,k)
384382
end do
385383
end subroutine
386384

0 commit comments

Comments
 (0)