Skip to content

Commit 3d67e5f

Browse files
refactor(generalized_lstsq): use optval, cholesky subroutine, and do concurrent
1 parent d65ad0d commit 3d67e5f

1 file changed

Lines changed: 10 additions & 25 deletions

File tree

src/linalg/stdlib_linalg_least_squares.fypp

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
submodule (stdlib_linalg) stdlib_linalg_least_squares
88
!! Least-squares solution to Ax=b
99
use stdlib_linalg_constants
10-
use stdlib_linalg_lapack, only: gelsd, gglse, ggglm, potrf, stdlib_ilaenv
10+
use stdlib_linalg_lapack, only: gelsd, gglse, ggglm, stdlib_ilaenv
1111
use stdlib_linalg_lapack_aux, only: handle_gelsd_info, handle_gglse_info, handle_ggglm_info
1212
use stdlib_linalg_state, only: linalg_state_type, linalg_error_handling, LINALG_ERROR, &
1313
LINALG_INTERNAL_ERROR, LINALG_VALUE_ERROR, LINALG_SUCCESS
@@ -633,14 +633,9 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
633633
end if
634634

635635
! Process options
636-
is_prefactored = .false._lk
637-
if (present(prefactored_w)) is_prefactored = prefactored_w
636+
is_prefactored = optval(prefactored_w, .false._lk)
638637

639-
if (present(overwrite_a)) then
640-
copy_a = .not.overwrite_a
641-
else
642-
copy_a = .true._lk
643-
end if
638+
copy_a = .not. optval(overwrite_a, .false._lk)
644639

645640
! Handle A matrix
646641
if (copy_a) then
@@ -656,21 +651,19 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
656651

657652
if (.not. is_prefactored) then
658653
! Compute Cholesky factorization: W = L * L^T (real) or W = L * L^H (complex)
659-
call potrf('L', m, lmat, m, info)
660-
if (info /= 0) then
661-
if (info > 0) then
662-
err0 = linalg_state_type(this, LINALG_ERROR, &
663-
'Covariance matrix is not positive definite at position', info)
664-
else
665-
err0 = linalg_state_type(this, LINALG_VALUE_ERROR, &
666-
'Invalid argument to POTRF at position', -info)
667-
end if
654+
call cholesky(lmat, lower=.true._lk, other_zeroed=.true._lk, err=err0)
655+
if (err0%error()) then
668656
! Cleanup before early return
669657
if (copy_a) deallocate(amat_alloc)
670658
deallocate(lmat)
671659
call linalg_error_handling(err0, err)
672660
return
673661
end if
662+
else
663+
! User provided pre-factored L: zero out upper triangle for GGGLM
664+
do concurrent(i=1:m, j=1:m, i < j)
665+
lmat(i, j) = zero
666+
end do
674667
end if
675668

676669
! Prepare for GGGLM
@@ -680,14 +673,6 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
680673
lda = m
681674
ldb = m
682675

683-
! Zero out upper triangle of lmat (GGGLM reads full matrix,
684-
! but potrf only sets lower triangle)
685-
do j = 1, m
686-
do i = 1, j - 1
687-
lmat(i, j) = zero
688-
end do
689-
end do
690-
691676
! Workspace query
692677
allocate(work(1))
693678
call ggglm(m, n, p, amat, lda, lmat, ldb, d, x, y, work, -1_ilp, info)

0 commit comments

Comments
 (0)