|
7 | 7 | submodule (stdlib_linalg) stdlib_linalg_least_squares |
8 | 8 | !! Least-squares solution to Ax=b |
9 | 9 | use stdlib_linalg_constants |
10 | | - use stdlib_linalg_lapack, only: gelsd, gglse, stdlib_ilaenv |
| 10 | + use stdlib_linalg_lapack, only: gelsd, gglse, stdlib_ilaenv, lascl2 |
11 | 11 | use stdlib_linalg_lapack_aux, only: handle_gelsd_info, handle_gglse_info |
12 | 12 | use stdlib_linalg_state, only: linalg_state_type, linalg_error_handling, LINALG_ERROR, & |
13 | 13 | LINALG_INTERNAL_ERROR, LINALG_VALUE_ERROR |
@@ -590,7 +590,7 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares |
590 | 590 |
|
591 | 591 | ! Local variables |
592 | 592 | type(linalg_state_type) :: err0 |
593 | | - integer(ilp) :: m, n, j |
| 593 | + integer(ilp) :: m, n |
594 | 594 | logical(lk) :: copy_a |
595 | 595 | ${rt}$, pointer :: amat(:,:) |
596 | 596 | ${rt}$, allocatable, target :: amat_alloc(:,:) |
@@ -644,22 +644,23 @@ submodule (stdlib_linalg) stdlib_linalg_least_squares |
644 | 644 |
|
645 | 645 | ! Handle A matrix: either copy or use original |
646 | 646 | if (copy_a) then |
647 | | - allocate(amat_alloc(m, n)) |
| 647 | + allocate(amat_alloc(m, n), source=a) |
648 | 648 | amat => amat_alloc |
649 | 649 | else |
650 | 650 | amat => a |
651 | 651 | end if |
652 | 652 |
|
653 | | - ! Scale A column-wise (cache-friendly: column-major order) |
654 | | - do j = 1, n |
655 | | - amat(:, j) = sqrt_w(:) * a(:, j) |
656 | | - end do |
| 653 | + ! Scale rows of A by sqrt(w) using LAPACK's lascl2 |
| 654 | + call lascl2(m, n, sqrt_w, amat, m) |
657 | 655 |
|
658 | 656 | ! Scale b |
659 | 657 | b_scaled = sqrt_w * b |
660 | 658 |
|
661 | | - ! Solve transformed OLS problem |
662 | | - call stdlib_linalg_${ri}$_solve_lstsq_one(amat, b_scaled, x, cond=cond, overwrite_a=.true., rank=rank, err=err) |
| 659 | + ! Solve transformed OLS problem using local error state |
| 660 | + call stdlib_linalg_${ri}$_solve_lstsq_one(amat, b_scaled, x, cond=cond, overwrite_a=.true., rank=rank, err=err0) |
| 661 | + |
| 662 | + ! Propagate error with updated location |
| 663 | + call linalg_error_handling(err0, err, where_at=this) |
663 | 664 |
|
664 | 665 | ! Cleanup |
665 | 666 | if (copy_a) deallocate(amat_alloc) |
|
0 commit comments