@@ -571,8 +571,8 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
571571 #:for rk,rt,ri in RC_KINDS_TYPES
572572 ! Weighted least-squares: minimize ||D(Ax - b)||^2 where D = diag(sqrt(w))
573573 module function stdlib_linalg_${ri}$_weighted_lstsq(w,a,b,cond,overwrite_a,rank,err) result(x)
574- !> Weight vector (must be positive)
575- ${rt}$ , intent(in) :: w(:)
574+ !> Weight vector (must be positive, always real )
575+ real(${rk}$) , intent(in) :: w(:)
576576 !> Input matrix a[m,n]
577577 ${rt}$, intent(inout), target :: a(:,:)
578578 !> Right hand side vector b[m]
@@ -593,12 +593,15 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
593593 integer(ilp) :: m, n, i
594594 logical(lk) :: copy_a
595595 ${rt}$, allocatable :: a_scaled(:,:), b_scaled(:)
596- real(${rk}$) :: sqrt_w(size(w) )
596+ real(${rk}$), allocatable :: sqrt_w(: )
597597 character(*), parameter :: this = 'weighted_lstsq'
598598
599599 m = size(a, 1, kind=ilp)
600600 n = size(a, 2, kind=ilp)
601601
602+ ! Allocate result (even on error, to prevent segfault on return)
603+ allocate(x(n))
604+
602605 ! Validate inputs
603606 if (size(w, kind=ilp) /= m) then
604607 err0 = linalg_state_type(this, LINALG_VALUE_ERROR, &
@@ -608,7 +611,7 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
608611 return
609612 end if
610613
611- if (any(w <= 0)) then
614+ if (any(w <= 0.0_${rk}$ )) then
612615 err0 = linalg_state_type(this, LINALG_VALUE_ERROR, 'Weights must be positive')
613616 call linalg_error_handling(err0, err)
614617 if (present(rank)) rank = 0
@@ -623,7 +626,8 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
623626 end if
624627
625628 ! Compute sqrt of weights
626- sqrt_w = sqrt(real(w, ${rk}$))
629+ allocate(sqrt_w(m))
630+ sqrt_w = sqrt(w)
627631
628632 ! Scale A and b
629633 if (copy_a) then
@@ -678,8 +682,8 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares
678682 integer(ilp) :: m, n, p, lda, ldb, lwork, info
679683 logical(lk) :: copy_a, is_prefactored
680684 ${rt}$, pointer :: amat(:,:)
681- ${rt}$, allocatable :: amat_alloc(:,:), lmat (:,:)
682- ${rt}$, allocatable :: d(:), y(:), work(:)
685+ ${rt}$, allocatable, target :: amat_alloc (:,:)
686+ ${rt}$, allocatable :: lmat(:,:), d(:), y(:), work(:)
683687 character(*), parameter :: this = 'generalized_lstsq'
684688
685689 m = size(a, 1, kind=ilp)
0 commit comments