77submodule (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