Skip to content

Commit 2065886

Browse files
fix: resolve compilation errors in weighted/generalized lstsq
1 parent efd02d4 commit 2065886

3 files changed

Lines changed: 19 additions & 12 deletions

File tree

src/linalg/stdlib_linalg.fypp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,8 +703,8 @@ module stdlib_linalg
703703
!!
704704
#:for rk,rt,ri in RC_KINDS_TYPES
705705
module function stdlib_linalg_${ri}$_weighted_lstsq(w,a,b,cond,overwrite_a,rank,err) result(x)
706-
!> Weight vector (must be positive)
707-
${rt}$, intent(in) :: w(:)
706+
!> Weight vector (must be positive, always real)
707+
real(${rk}$), intent(in) :: w(:)
708708
!> Input matrix a[m,n]
709709
${rt}$, intent(inout), target :: a(:,:)
710710
!> Right hand side vector b[m]

src/linalg/stdlib_linalg_least_squares.fypp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

test/linalg/test_linalg_lstsq.fypp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ module test_linalg_least_squares
156156
type(linalg_state_type) :: state
157157
integer(ilp), parameter :: m = 4, n = 2
158158
real(${rk}$), parameter :: tol = 100*sqrt(epsilon(0.0_${rk}$))
159-
${rt}$ :: A(m,n), b(m), w(m)
159+
${rt}$ :: A(m,n), b(m)
160+
real(${rk}$) :: w(m)
160161
${rt}$, allocatable :: x(:)
161162

162163
! Simple test case
@@ -186,7 +187,8 @@ module test_linalg_least_squares
186187
type(linalg_state_type) :: state
187188
integer(ilp), parameter :: m = 4, n = 2
188189
real(${rk}$), parameter :: tol = 100*sqrt(epsilon(0.0_${rk}$))
189-
${rt}$ :: A(m,n), b(m), w_uniform(m), w_nonuniform(m)
190+
${rt}$ :: A(m,n), b(m)
191+
real(${rk}$) :: w_uniform(m), w_nonuniform(m)
190192
${rt}$, allocatable :: x_uniform(:), x_weighted(:)
191193

192194
! Setup problem
@@ -217,7 +219,8 @@ module test_linalg_least_squares
217219
type(error_type), allocatable, intent(out) :: error
218220

219221
type(linalg_state_type) :: state
220-
${rt}$ :: A(3,2), b(3), w(3)
222+
${rt}$ :: A(3,2), b(3)
223+
real(${rk}$) :: w(3)
221224
${rt}$, allocatable :: x(:)
222225

223226
A = 1.0_${rk}$

0 commit comments

Comments
 (0)