7submodule(
linalg) linalg_solve
15 module subroutine solve_tri_mtx(lside, upper, trans, nounit, alpha, a, b, err)
17 logical,
intent(in) :: lside, upper, trans, nounit
18 real(real64),
intent(in) :: alpha
19 real(real64),
intent(in),
dimension(:,:) :: a
20 real(real64),
intent(inout),
dimension(:,:) :: b
21 class(errors),
intent(inout),
optional,
target :: err
24 character :: side, uplo, transa, diag
27 integer(int32) :: m, n, nrowa
28 class(errors),
pointer :: errmgr
29 type(errors),
target :: deferr
56 if (
present(err))
then
63 if (
size(a, 1) /= nrowa .or.
size(a, 2) /= nrowa)
then
65 call errmgr%report_error(
"solve_tri_mtx", &
66 "The input matrix must be square.", la_array_size_error)
71 call dtrsm(side, uplo, transa, diag, m, n, alpha, a, nrowa, b, m)
75 module subroutine solve_tri_mtx_cmplx(lside, upper, trans, nounit, alpha, a, b, err)
77 logical,
intent(in) :: lside, upper, trans, nounit
78 complex(real64),
intent(in) :: alpha
79 complex(real64),
intent(in),
dimension(:,:) :: a
80 complex(real64),
intent(inout),
dimension(:,:) :: b
81 class(errors),
intent(inout),
optional,
target :: err
84 character :: side, uplo, transa, diag
87 integer(int32) :: m, n, nrowa
88 class(errors),
pointer :: errmgr
89 type(errors),
target :: deferr
116 if (
present(err))
then
123 if (
size(a, 1) /= nrowa .or.
size(a, 2) /= nrowa)
then
125 call errmgr%report_error(
"solve_tri_mtx_cmplx", &
126 "The input matrix must be square.", la_array_size_error)
131 call ztrsm(side, uplo, transa, diag, m, n, alpha, a, nrowa, b, m)
135 module subroutine solve_tri_vec(upper, trans, nounit, a, x, err)
137 logical,
intent(in) :: upper, trans, nounit
138 real(real64),
intent(in),
dimension(:,:) :: a
139 real(real64),
intent(inout),
dimension(:) :: x
140 class(errors),
intent(inout),
optional,
target :: err
143 real(real64),
parameter :: zero = 0.0d0
146 character :: uplo, t, diag
148 class(errors),
pointer :: errmgr
149 type(errors),
target :: deferr
168 if (
present(err))
then
175 if (
size(a, 2) /= n)
then
177 call errmgr%report_error(
"solve_tri_vec", &
178 "The input matrix must be square.", la_array_size_error)
180 else if (
size(x) /= n)
then
182 call errmgr%report_error(
"solve_tri_vec", &
183 "The inner matrix dimensions must be equal.", &
189 call dtrsv(uplo, t, diag, n, a, n, x, 1)
193 module subroutine solve_tri_vec_cmplx(upper, trans, nounit, a, x, err)
195 logical,
intent(in) :: upper, trans, nounit
196 complex(real64),
intent(in),
dimension(:,:) :: a
197 complex(real64),
intent(inout),
dimension(:) :: x
198 class(errors),
intent(inout),
optional,
target :: err
201 real(real64),
parameter :: zero = 0.0d0
204 character :: uplo, t, diag
206 class(errors),
pointer :: errmgr
207 type(errors),
target :: deferr
226 if (
present(err))
then
233 if (
size(a, 2) /= n)
then
235 call errmgr%report_error(
"solve_tri_vec_cmplx", &
236 "The input matrix must be square.", la_array_size_error)
238 else if (
size(x) /= n)
then
240 call errmgr%report_error(
"solve_tri_vec_cmplx", &
241 "The inner matrix dimensions must be equal.", &
247 call ztrsv(uplo, t, diag, n, a, n, x, 1)
253 module subroutine solve_lu_mtx(a, ipvt, b, err)
255 real(real64),
intent(in),
dimension(:,:) :: a
256 integer(int32),
intent(in),
dimension(:) :: ipvt
257 real(real64),
intent(inout),
dimension(:,:) :: b
258 class(errors),
intent(inout),
optional,
target :: err
261 integer(int32) :: n, nrhs, flag
262 class(errors),
pointer :: errmgr
263 type(errors),
target :: deferr
264 character(len = :),
allocatable :: errmsg
269 if (
present(err))
then
277 if (
size(a, 2) /= n)
then
279 else if (
size(ipvt) /= n)
then
281 else if (
size(b, 1) /= n)
then
286 allocate(
character(len = 256) :: errmsg)
287 write(errmsg, 100)
"Input number ", flag, &
288 " is not sized correctly."
289 call errmgr%report_error(
"solve_lu_mtx", trim(errmsg), &
295 call dgetrs(
"N", n, nrhs, a, n, ipvt, b, n, flag)
302 module subroutine solve_lu_mtx_cmplx(a, ipvt, b, err)
304 complex(real64),
intent(in),
dimension(:,:) :: a
305 integer(int32),
intent(in),
dimension(:) :: ipvt
306 complex(real64),
intent(inout),
dimension(:,:) :: b
307 class(errors),
intent(inout),
optional,
target :: err
310 integer(int32) :: n, nrhs, flag
311 class(errors),
pointer :: errmgr
312 type(errors),
target :: deferr
313 character(len = :),
allocatable :: errmsg
318 if (
present(err))
then
326 if (
size(a, 2) /= n)
then
328 else if (
size(ipvt) /= n)
then
330 else if (
size(b, 1) /= n)
then
335 allocate(
character(len = 256) :: errmsg)
336 write(errmsg, 100)
"Input number ", flag, &
337 " is not sized correctly."
338 call errmgr%report_error(
"solve_lu_mtx_cmplx", trim(errmsg), &
344 call zgetrs(
"N", n, nrhs, a, n, ipvt, b, n, flag)
351 module subroutine solve_lu_vec(a, ipvt, b, err)
353 real(real64),
intent(in),
dimension(:,:) :: a
354 integer(int32),
intent(in),
dimension(:) :: ipvt
355 real(real64),
intent(inout),
dimension(:) :: b
356 class(errors),
intent(inout),
optional,
target :: err
359 integer(int32) :: n, flag
360 class(errors),
pointer :: errmgr
361 type(errors),
target :: deferr
362 character(len = :),
allocatable :: errmsg
366 if (
present(err))
then
374 if (
size(a, 2) /= n)
then
376 else if (
size(ipvt) /= n)
then
378 else if (
size(b) /= n)
then
383 allocate(
character(len = 256) :: errmsg)
384 write(errmsg, 100)
"Input number ", flag, &
385 " is not sized correctly."
386 call errmgr%report_error(
"solve_lu_vec", trim(errmsg), &
392 call dgetrs(
"N", n, 1, a, n, ipvt, b, n, flag)
399 module subroutine solve_lu_vec_cmplx(a, ipvt, b, err)
401 complex(real64),
intent(in),
dimension(:,:) :: a
402 integer(int32),
intent(in),
dimension(:) :: ipvt
403 complex(real64),
intent(inout),
dimension(:) :: b
404 class(errors),
intent(inout),
optional,
target :: err
407 integer(int32) :: n, flag
408 class(errors),
pointer :: errmgr
409 type(errors),
target :: deferr
410 character(len = :),
allocatable :: errmsg
414 if (
present(err))
then
422 if (
size(a, 2) /= n)
then
424 else if (
size(ipvt) /= n)
then
426 else if (
size(b) /= n)
then
431 allocate(
character(len = 256) :: errmsg)
432 write(errmsg, 100)
"Input number ", flag, &
433 " is not sized correctly."
434 call errmgr%report_error(
"solve_lu_vec_cmplx", trim(errmsg), &
440 call zgetrs(
"N", n, 1, a, n, ipvt, b, n, flag)
449 module subroutine solve_qr_no_pivot_mtx(a, tau, b, work, olwork, err)
451 real(real64),
intent(inout),
dimension(:,:) :: a, b
452 real(real64),
intent(in),
dimension(:) :: tau
453 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
454 integer(int32),
intent(out),
optional :: olwork
455 class(errors),
intent(inout),
optional,
target :: err
458 real(real64),
parameter :: one = 1.0d0
461 integer(int32) :: m, n, nrhs, k, lwork, flag, istat
462 real(real64),
pointer,
dimension(:) :: wptr
463 real(real64),
allocatable,
target,
dimension(:) :: wrk
464 class(errors),
pointer :: errmgr
465 type(errors),
target :: deferr
466 character(len = :),
allocatable :: errmsg
473 if (
present(err))
then
483 else if (
size(tau) /= k)
then
485 else if (
size(b, 1) /= m)
then
490 allocate(
character(len = 256) :: errmsg)
491 write(errmsg, 100)
"Input number ", flag, &
492 " is not sized correctly."
493 call errmgr%report_error(
"solve_qr_no_pivot_mtx", trim(errmsg), &
499 call mult_qr(.true., .true., a, tau, b, olwork = lwork)
500 if (
present(olwork))
then
506 if (
present(work))
then
507 if (
size(work) < lwork)
then
509 call errmgr%report_error(
"solve_qr_no_pivot_mtx", &
510 "Incorrectly sized input array WORK, argument 4.", &
514 wptr => work(1:lwork)
516 allocate(wrk(lwork), stat = istat)
519 call errmgr%report_error(
"solve_qr_no_pivot_mtx", &
520 "Insufficient memory available.", &
521 la_out_of_memory_error)
528 call mult_qr(.true., .true., a, tau, b, wptr)
531 call solve_triangular_system(.true., .true., .false., .true., one, &
532 a(1:n,1:n), b(1:n,:))
539 module subroutine solve_qr_no_pivot_mtx_cmplx(a, tau, b, work, olwork, err)
541 complex(real64),
intent(inout),
dimension(:,:) :: a, b
542 complex(real64),
intent(in),
dimension(:) :: tau
543 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
544 integer(int32),
intent(out),
optional :: olwork
545 class(errors),
intent(inout),
optional,
target :: err
548 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
551 integer(int32) :: m, n, nrhs, k, lwork, flag, istat
552 complex(real64),
pointer,
dimension(:) :: wptr
553 complex(real64),
allocatable,
target,
dimension(:) :: wrk
554 class(errors),
pointer :: errmgr
555 type(errors),
target :: deferr
556 character(len = :),
allocatable :: errmsg
563 if (
present(err))
then
573 else if (
size(tau) /= k)
then
575 else if (
size(b, 1) /= m)
then
580 allocate(
character(len = 256) :: errmsg)
581 write(errmsg, 100)
"Input number ", flag, &
582 " is not sized correctly."
583 call errmgr%report_error(
"solve_qr_no_pivot_mtx_cmplx", &
584 trim(errmsg), la_array_size_error)
589 call mult_qr(.true., .true., a, tau, b, olwork = lwork)
590 if (
present(olwork))
then
596 if (
present(work))
then
597 if (
size(work) < lwork)
then
599 call errmgr%report_error(
"solve_qr_no_pivot_mtx_cmplx", &
600 "Incorrectly sized input array WORK, argument 4.", &
604 wptr => work(1:lwork)
606 allocate(wrk(lwork), stat = istat)
609 call errmgr%report_error(
"solve_qr_no_pivot_mtx_cmplx", &
610 "Insufficient memory available.", &
611 la_out_of_memory_error)
618 call mult_qr(.true., .true., a, tau, b, wptr)
621 call solve_triangular_system(.true., .true., .false., .true., one, &
622 a(1:n,1:n), b(1:n,:))
629 module subroutine solve_qr_no_pivot_vec(a, tau, b, work, olwork, err)
631 real(real64),
intent(inout),
dimension(:,:) :: a
632 real(real64),
intent(in),
dimension(:) :: tau
633 real(real64),
intent(inout),
dimension(:) :: b
634 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
635 integer(int32),
intent(out),
optional :: olwork
636 class(errors),
intent(inout),
optional,
target :: err
639 integer(int32) :: m, n, k, flag, lwork, istat
640 real(real64),
pointer,
dimension(:) :: wptr
641 real(real64),
allocatable,
target,
dimension(:) :: wrk
642 class(errors),
pointer :: errmgr
643 type(errors),
target :: deferr
644 character(len = :),
allocatable :: errmsg
650 if (
present(err))
then
660 else if (
size(tau) /= k)
then
662 else if (
size(b) /= m)
then
667 allocate(
character(len = 256) :: errmsg)
668 write(errmsg, 100)
"Input number ", flag, &
669 " is not sized correctly."
670 call errmgr%report_error(
"solve_qr_no_pivot_vec", trim(errmsg), &
676 call mult_qr(.true., a, tau, b, olwork = lwork)
677 if (
present(olwork))
then
683 if (
present(work))
then
684 if (
size(work) < lwork)
then
686 call errmgr%report_error(
"solve_qr_no_pivot_vec", &
687 "Incorrectly sized input array WORK, argument 4.", &
691 wptr => work(1:lwork)
693 allocate(wrk(lwork), stat = istat)
696 call errmgr%report_error(
"solve_qr_no_pivot_vec", &
697 "Insufficient memory available.", &
698 la_out_of_memory_error)
705 call mult_qr(.true., a, tau, b, work = wptr)
708 call solve_triangular_system(.true., .false., .true., a(1:n,1:n), b)
715 module subroutine solve_qr_no_pivot_vec_cmplx(a, tau, b, work, olwork, err)
717 complex(real64),
intent(inout),
dimension(:,:) :: a
718 complex(real64),
intent(in),
dimension(:) :: tau
719 complex(real64),
intent(inout),
dimension(:) :: b
720 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
721 integer(int32),
intent(out),
optional :: olwork
722 class(errors),
intent(inout),
optional,
target :: err
725 integer(int32) :: m, n, k, flag, lwork, istat
726 complex(real64),
pointer,
dimension(:) :: wptr
727 complex(real64),
allocatable,
target,
dimension(:) :: wrk
728 class(errors),
pointer :: errmgr
729 type(errors),
target :: deferr
730 character(len = :),
allocatable :: errmsg
736 if (
present(err))
then
746 else if (
size(tau) /= k)
then
748 else if (
size(b) /= m)
then
753 allocate(
character(len = 256) :: errmsg)
754 write(errmsg, 100)
"Input number ", flag, &
755 " is not sized correctly."
756 call errmgr%report_error(
"solve_qr_no_pivot_vec_cmplx", &
757 trim(errmsg), la_array_size_error)
762 call mult_qr(.true., a, tau, b, olwork = lwork)
763 if (
present(olwork))
then
769 if (
present(work))
then
770 if (
size(work) < lwork)
then
772 call errmgr%report_error(
"solve_qr_no_pivot_vec_cmplx", &
773 "Incorrectly sized input array WORK, argument 4.", &
777 wptr => work(1:lwork)
779 allocate(wrk(lwork), stat = istat)
782 call errmgr%report_error(
"solve_qr_no_pivot_vec_cmplx", &
783 "Insufficient memory available.", &
784 la_out_of_memory_error)
791 call mult_qr(.true., a, tau, b, work = wptr)
794 call solve_triangular_system(.true., .false., .true., a(1:n,1:n), b)
801 module subroutine solve_qr_pivot_mtx(a, tau, jpvt, b, work, olwork, err)
803 real(real64),
intent(inout),
dimension(:,:) :: a
804 real(real64),
intent(in),
dimension(:) :: tau
805 integer(int32),
intent(in),
dimension(:) :: jpvt
806 real(real64),
intent(inout),
dimension(:,:) :: b
807 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
808 integer(int32),
intent(out),
optional :: olwork
809 class(errors),
intent(inout),
optional,
target :: err
812 integer(int32),
parameter :: imin = 2
813 integer(int32),
parameter :: imax = 1
814 real(real64),
parameter :: zero = 0.0d0
815 real(real64),
parameter :: one = 1.0d0
818 integer(int32) :: i, j, m, n, mn, nrhs, lwork, ismin, ismax, &
819 rnk, maxmn, flag, istat, lwork1, lwork2, lwork3
820 real(real64) :: rcond, smax, smin, smaxpr, sminpr, s1, c1, s2, c2
821 real(real64),
pointer,
dimension(:) :: wptr, w, tau2
822 real(real64),
allocatable,
target,
dimension(:) :: wrk
823 class(errors),
pointer :: errmgr
824 type(errors),
target :: deferr
825 character(len = :),
allocatable :: errmsg
835 rcond = epsilon(rcond)
836 if (
present(err))
then
844 if (
size(tau) /= mn)
then
846 else if (
size(jpvt) /= n)
then
848 else if (
size(b, 1) /= maxmn)
then
853 allocate(
character(len = 256) :: errmsg)
854 write(errmsg, 100)
"Input number ", flag, &
855 " is not sized correctly."
856 call errmgr%report_error(
"solve_qr_pivot_mtx", trim(errmsg), &
862 call rz_factor(a(1:mn,:), a(1:mn,1), olwork = lwork1)
863 call mult_qr(.true., .true., a, tau, b(1:m,:), olwork = lwork2)
864 call mult_rz(.true., .true., n, a(1:mn,:), a(1:mn,1), b(1:n,:), &
866 lwork = max(lwork1, lwork2, lwork3, 2 * mn + 1) + mn
867 if (
present(olwork))
then
873 if (
present(work))
then
874 if (
size(work) < lwork)
then
876 call errmgr%report_error(
"solve_qr_no_pivot_mtx", &
877 "Incorrectly sized input array WORK, argument 5.", &
881 wptr => work(1:lwork)
883 allocate(wrk(lwork), stat = istat)
886 call errmgr%report_error(
"solve_qr_pivot_mtx", &
887 "Insufficient memory available.", &
888 la_out_of_memory_error)
899 if (abs(a(1,1)) == zero)
then
909 call dlaic1(imin, rnk, wptr(ismin:ismin+rnk-1), smin, &
910 a(1:rnk-1,i), a(i,i), sminpr, s1, c1)
911 call dlaic1(imax, rnk, wptr(ismax:ismax+rnk-1), smax, &
912 a(1:rnk-1,i), a(i,i), smaxpr, s2, c2)
913 if (smaxpr * rcond <= sminpr)
then
915 wptr(ismin+i-1) = s1 * wptr(ismin+i-1)
916 wptr(ismax+i-1) = s2 * wptr(ismax+i-1)
932 w => wptr(rnk+1:lwork)
933 if (rnk < n)
call rz_factor(a(1:rnk,:), tau2, w)
936 call mult_qr(.true., .true., a, tau, b(1:m,:), w)
939 call solve_triangular_system(.true., .true., .false., .true., one, &
940 a(1:rnk,1:rnk), b(1:rnk,:))
941 if (n > rnk) b(rnk+1:n,:) = zero
945 call mult_rz(.true., .true., n - rnk, a(1:rnk,:), tau2, b(1:n,:), w)
951 wptr(jpvt(i)) = b(i,j)
961 module subroutine solve_qr_pivot_mtx_cmplx(a, tau, jpvt, b, work, olwork, err)
963 complex(real64),
intent(inout),
dimension(:,:) :: a
964 complex(real64),
intent(in),
dimension(:) :: tau
965 integer(int32),
intent(in),
dimension(:) :: jpvt
966 complex(real64),
intent(inout),
dimension(:,:) :: b
967 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
968 integer(int32),
intent(out),
optional :: olwork
969 class(errors),
intent(inout),
optional,
target :: err
972 integer(int32),
parameter :: imin = 2
973 integer(int32),
parameter :: imax = 1
974 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
975 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
978 integer(int32) :: i, j, m, n, mn, nrhs, lwork, ismin, ismax, &
979 rnk, maxmn, flag, istat, lwork1, lwork2, lwork3
980 real(real64) :: rcond, smax, smin, smaxpr, sminpr
981 complex(real64) :: s1, c1, s2, c2
982 complex(real64),
pointer,
dimension(:) :: wptr, w, tau2
983 complex(real64),
allocatable,
target,
dimension(:) :: wrk
984 class(errors),
pointer :: errmgr
985 type(errors),
target :: deferr
986 character(len = :),
allocatable :: errmsg
996 rcond = epsilon(rcond)
997 if (
present(err))
then
1005 if (
size(tau) /= mn)
then
1007 else if (
size(jpvt) /= n)
then
1009 else if (
size(b, 1) /= maxmn)
then
1014 allocate(
character(len = 256) :: errmsg)
1015 write(errmsg, 100)
"Input number ", flag, &
1016 " is not sized correctly."
1017 call errmgr%report_error(
"solve_qr_pivot_mtx_cmplx", &
1018 trim(errmsg), la_array_size_error)
1023 call rz_factor(a(1:mn,:), a(1:mn,1), olwork = lwork1)
1024 call mult_qr(.true., .true., a, tau, b(1:m,:), olwork = lwork2)
1025 call mult_rz(.true., .true., n, a(1:mn,:), a(1:mn,1), b(1:n,:), &
1027 lwork = max(lwork1, lwork2, lwork3, 2 * mn + 1) + mn
1028 if (
present(olwork))
then
1034 if (
present(work))
then
1035 if (
size(work) < lwork)
then
1037 call errmgr%report_error(
"solve_qr_no_pivot_mtx_cmplx", &
1038 "Incorrectly sized input array WORK, argument 5.", &
1039 la_array_size_error)
1042 wptr => work(1:lwork)
1044 allocate(wrk(lwork), stat = istat)
1045 if (istat /= 0)
then
1047 call errmgr%report_error(
"solve_qr_pivot_mtx_cmplx", &
1048 "Insufficient memory available.", &
1049 la_out_of_memory_error)
1060 if (abs(a(1,1)) == zero)
then
1070 call zlaic1(imin, rnk, wptr(ismin:ismin+rnk-1), smin, &
1071 a(1:rnk-1,i), a(i,i), sminpr, s1, c1)
1072 call zlaic1(imax, rnk, wptr(ismax:ismax+rnk-1), smax, &
1073 a(1:rnk-1,i), a(i,i), smaxpr, s2, c2)
1074 if (smaxpr * rcond <= sminpr)
then
1076 wptr(ismin+i-1) = s1 * wptr(ismin+i-1)
1077 wptr(ismax+i-1) = s2 * wptr(ismax+i-1)
1079 wptr(ismin+rnk) = c1
1080 wptr(ismax+rnk) = c2
1093 w => wptr(rnk+1:lwork)
1094 if (rnk < n)
call rz_factor(a(1:rnk,:), tau2, w)
1097 call mult_qr(.true., .true., a, tau, b(1:m,:), w)
1100 call solve_triangular_system(.true., .true., .false., .true., one, &
1101 a(1:rnk,1:rnk), b(1:rnk,:))
1102 if (n > rnk) b(rnk+1:n,:) = zero
1106 call mult_rz(.true., .true., n - rnk, a(1:rnk,:), tau2, b(1:n,:), w)
1112 wptr(jpvt(i)) = b(i,j)
1114 b(1:n,j) = wptr(1:n)
1122 module subroutine solve_qr_pivot_vec(a, tau, jpvt, b, work, olwork, err)
1124 real(real64),
intent(inout),
dimension(:,:) :: a
1125 real(real64),
intent(in),
dimension(:) :: tau
1126 integer(int32),
intent(in),
dimension(:) :: jpvt
1127 real(real64),
intent(inout),
dimension(:) :: b
1128 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
1129 integer(int32),
intent(out),
optional :: olwork
1130 class(errors),
intent(inout),
optional,
target :: err
1133 integer(int32),
parameter :: imin = 2
1134 integer(int32),
parameter :: imax = 1
1135 real(real64),
parameter :: zero = 0.0d0
1136 real(real64),
parameter :: one = 1.0d0
1139 integer(int32) :: i, m, n, mn, lwork, ismin, ismax, rnk, maxmn, flag, &
1140 istat, lwork1, lwork2
1141 real(real64) :: rcond, smax, smin, smaxpr, sminpr, s1, c1, s2, c2
1142 real(real64),
pointer,
dimension(:) :: wptr, w, tau2
1143 real(real64),
allocatable,
target,
dimension(:) :: wrk
1144 class(errors),
pointer :: errmgr
1145 type(errors),
target :: deferr
1146 character(len = :),
allocatable :: errmsg
1155 rcond = epsilon(rcond)
1156 if (
present(err))
then
1164 if (
size(tau) /= mn)
then
1166 else if (
size(jpvt) /= n)
then
1168 else if (
size(b) /= maxmn)
then
1173 allocate(
character(len = 256) :: errmsg)
1174 write(errmsg, 100)
"Input number ", flag, &
1175 " is not sized correctly."
1176 call errmgr%report_error(
"solve_qr_pivot_vec", trim(errmsg), &
1177 la_array_size_error)
1182 call rz_factor(a(1:mn,:), a(1:mn,1), olwork = lwork1)
1183 call mult_rz(.true., n, a(1:mn,:), a(1:mn,1), b(1:n), olwork = lwork2)
1184 lwork = max(lwork1, lwork2, 2 * mn + 1) + mn
1185 if (
present(olwork))
then
1191 if (
present(work))
then
1192 if (
size(work) < lwork)
then
1194 call errmgr%report_error(
"solve_qr_no_pivot_mtx", &
1195 "Incorrectly sized input array WORK, argument 5.", &
1196 la_array_size_error)
1199 wptr => work(1:lwork)
1201 allocate(wrk(lwork), stat = istat)
1202 if (istat /= 0)
then
1204 call errmgr%report_error(
"solve_qr_pivot_vec", &
1205 "Insufficient memory available.", &
1206 la_out_of_memory_error)
1217 if (abs(a(1,1)) == zero)
then
1227 call dlaic1(imin, rnk, wptr(ismin:ismin+rnk-1), smin, &
1228 a(1:rnk-1,i), a(i,i), sminpr, s1, c1)
1229 call dlaic1(imax, rnk, wptr(ismax:ismax+rnk-1), smax, &
1230 a(1:rnk-1,i), a(i,i), smaxpr, s2, c2)
1231 if (smaxpr * rcond <= sminpr)
then
1233 wptr(ismin+i-1) = s1 * wptr(ismin+i-1)
1234 wptr(ismax+i-1) = s2 * wptr(ismax+i-1)
1236 wptr(ismin+rnk) = c1
1237 wptr(ismax+rnk) = c2
1250 w => wptr(rnk+1:lwork)
1251 if (rnk < n)
call rz_factor(a(1:rnk,:), tau2, w)
1254 call mult_qr(.true., a, tau, b(1:m))
1257 call solve_triangular_system(.true., .false., .true., a(1:rnk,1:rnk), &
1259 if (n > rnk) b(rnk+1:n) = zero
1263 call mult_rz(.true., n - rnk, a(1:rnk,:), tau2, b(1:n), w)
1268 wptr(jpvt(i)) = b(i)
1277 module subroutine solve_qr_pivot_vec_cmplx(a, tau, jpvt, b, work, olwork, err)
1279 complex(real64),
intent(inout),
dimension(:,:) :: a
1280 complex(real64),
intent(in),
dimension(:) :: tau
1281 integer(int32),
intent(in),
dimension(:) :: jpvt
1282 complex(real64),
intent(inout),
dimension(:) :: b
1283 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
1284 integer(int32),
intent(out),
optional :: olwork
1285 class(errors),
intent(inout),
optional,
target :: err
1288 integer(int32),
parameter :: imin = 2
1289 integer(int32),
parameter :: imax = 1
1290 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
1291 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
1294 integer(int32) :: i, m, n, mn, lwork, ismin, ismax, rnk, maxmn, flag, &
1295 istat, lwork1, lwork2
1296 real(real64) :: rcond, smax, smin, smaxpr, sminpr
1297 complex(real64) :: s1, c1, s2, c2
1298 complex(real64),
pointer,
dimension(:) :: wptr, w, tau2
1299 complex(real64),
allocatable,
target,
dimension(:) :: wrk
1300 class(errors),
pointer :: errmgr
1301 type(errors),
target :: deferr
1302 character(len = :),
allocatable :: errmsg
1311 rcond = epsilon(rcond)
1312 if (
present(err))
then
1320 if (
size(tau) /= mn)
then
1322 else if (
size(jpvt) /= n)
then
1324 else if (
size(b) /= maxmn)
then
1329 allocate(
character(len = 256) :: errmsg)
1330 write(errmsg, 100)
"Input number ", flag, &
1331 " is not sized correctly."
1332 call errmgr%report_error(
"solve_qr_pivot_vec_cmplx", trim(errmsg), &
1333 la_array_size_error)
1338 call rz_factor(a(1:mn,:), a(1:mn,1), olwork = lwork1)
1339 call mult_rz(.true., n, a(1:mn,:), a(1:mn,1), b(1:n), olwork = lwork2)
1340 lwork = max(lwork1, lwork2, 2 * mn + 1) + mn
1341 if (
present(olwork))
then
1347 if (
present(work))
then
1348 if (
size(work) < lwork)
then
1350 call errmgr%report_error(
"solve_qr_no_pivot_mtx_cmplx", &
1351 "Incorrectly sized input array WORK, argument 5.", &
1352 la_array_size_error)
1355 wptr => work(1:lwork)
1357 allocate(wrk(lwork), stat = istat)
1358 if (istat /= 0)
then
1360 call errmgr%report_error(
"solve_qr_pivot_vec_cmplx", &
1361 "Insufficient memory available.", &
1362 la_out_of_memory_error)
1373 if (abs(a(1,1)) == zero)
then
1383 call zlaic1(imin, rnk, wptr(ismin:ismin+rnk-1), smin, &
1384 a(1:rnk-1,i), a(i,i), sminpr, s1, c1)
1385 call zlaic1(imax, rnk, wptr(ismax:ismax+rnk-1), smax, &
1386 a(1:rnk-1,i), a(i,i), smaxpr, s2, c2)
1387 if (smaxpr * rcond <= sminpr)
then
1389 wptr(ismin+i-1) = s1 * wptr(ismin+i-1)
1390 wptr(ismax+i-1) = s2 * wptr(ismax+i-1)
1392 wptr(ismin+rnk) = c1
1393 wptr(ismax+rnk) = c2
1406 w => wptr(rnk+1:lwork)
1407 if (rnk < n)
call rz_factor(a(1:rnk,:), tau2, w)
1410 call mult_qr(.true., a, tau, b(1:m))
1413 call solve_triangular_system(.true., .false., .true., a(1:rnk,1:rnk), &
1415 if (n > rnk) b(rnk+1:n) = zero
1419 call mult_rz(.true., n - rnk, a(1:rnk,:), tau2, b(1:n), w)
1424 wptr(jpvt(i)) = b(i)
1435 module subroutine solve_cholesky_mtx(upper, a, b, err)
1437 logical,
intent(in) :: upper
1438 real(real64),
intent(in),
dimension(:,:) :: a
1439 real(real64),
intent(inout),
dimension(:,:) :: b
1440 class(errors),
intent(inout),
optional,
target :: err
1444 integer(int32) :: n, nrhs, flag
1445 class(errors),
pointer :: errmgr
1446 type(errors),
target :: deferr
1447 character(len = :),
allocatable :: errmsg
1457 if (
present(err))
then
1465 if (
size(a, 2) /= n)
then
1467 else if (
size(b, 1) /= n)
then
1471 allocate(
character(len = 256) :: errmsg)
1472 write(errmsg, 100)
"Input number ", flag, &
1473 " is not sized correctly."
1474 call errmgr%report_error(
"solve_cholesky_mtx", trim(errmsg), &
1475 la_array_size_error)
1480 call dpotrs(uplo, n, nrhs, a, n, b, n, flag)
1487 module subroutine solve_cholesky_mtx_cmplx(upper, a, b, err)
1489 logical,
intent(in) :: upper
1490 complex(real64),
intent(in),
dimension(:,:) :: a
1491 complex(real64),
intent(inout),
dimension(:,:) :: b
1492 class(errors),
intent(inout),
optional,
target :: err
1496 integer(int32) :: n, nrhs, flag
1497 class(errors),
pointer :: errmgr
1498 type(errors),
target :: deferr
1499 character(len = :),
allocatable :: errmsg
1509 if (
present(err))
then
1517 if (
size(a, 2) /= n)
then
1519 else if (
size(b, 1) /= n)
then
1523 allocate(
character(len = 256) :: errmsg)
1524 write(errmsg, 100)
"Input number ", flag, &
1525 " is not sized correctly."
1526 call errmgr%report_error(
"solve_cholesky_mtx_cmplx", trim(errmsg), &
1527 la_array_size_error)
1532 call zpotrs(uplo, n, nrhs, a, n, b, n, flag)
1539 module subroutine solve_cholesky_vec(upper, a, b, err)
1541 logical,
intent(in) :: upper
1542 real(real64),
intent(in),
dimension(:,:) :: a
1543 real(real64),
intent(inout),
dimension(:) :: b
1544 class(errors),
intent(inout),
optional,
target :: err
1548 integer(int32) :: n, flag
1549 class(errors),
pointer :: errmgr
1550 type(errors),
target :: deferr
1551 character(len = :),
allocatable :: errmsg
1560 if (
present(err))
then
1568 if (
size(a, 2) /= n)
then
1570 else if (
size(b) /= n)
then
1574 allocate(
character(len = 256) :: errmsg)
1575 write(errmsg, 100)
"Input number ", flag, &
1576 " is not sized correctly."
1577 call errmgr%report_error(
"solve_cholesky_vec", trim(errmsg), &
1578 la_array_size_error)
1583 call dpotrs(uplo, n, 1, a, n, b, n, flag)
1590 module subroutine solve_cholesky_vec_cmplx(upper, a, b, err)
1592 logical,
intent(in) :: upper
1593 complex(real64),
intent(in),
dimension(:,:) :: a
1594 complex(real64),
intent(inout),
dimension(:) :: b
1595 class(errors),
intent(inout),
optional,
target :: err
1599 integer(int32) :: n, flag
1600 class(errors),
pointer :: errmgr
1601 type(errors),
target :: deferr
1602 character(len = :),
allocatable :: errmsg
1611 if (
present(err))
then
1619 if (
size(a, 2) /= n)
then
1621 else if (
size(b) /= n)
then
1625 allocate(
character(len = 256) :: errmsg)
1626 write(errmsg, 100)
"Input number ", flag, &
1627 " is not sized correctly."
1628 call errmgr%report_error(
"solve_cholesky_vec_cmplx", trim(errmsg), &
1629 la_array_size_error)
1634 call zpotrs(uplo, n, 1, a, n, b, n, flag)
1643 module subroutine mtx_inverse_dbl(a, iwork, work, olwork, err)
1645 real(real64),
intent(inout),
dimension(:,:) :: a
1646 integer(int32),
intent(out),
target,
optional,
dimension(:) :: iwork
1647 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
1648 integer(int32),
intent(out),
optional :: olwork
1649 class(errors),
intent(inout),
optional,
target :: err
1652 integer(int32) :: n, liwork, lwork, istat, flag, itemp(1)
1653 integer(int32),
pointer,
dimension(:) :: iptr
1654 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
1655 real(real64),
pointer,
dimension(:) :: wptr
1656 real(real64),
allocatable,
target,
dimension(:) :: wrk
1657 real(real64),
dimension(1) :: temp
1658 class(errors),
pointer :: errmgr
1659 type(errors),
target :: deferr
1664 if (
present(err))
then
1671 if (
size(a, 2) /= n)
then
1672 call errmgr%report_error(
"mtx_inverse", &
1673 "The matrix must be squre to invert.", la_array_size_error)
1678 call dgetri(n, a, n, itemp, temp, -1, flag)
1679 lwork = int(temp(1), int32)
1680 if (
present(olwork))
then
1686 if (
present(work))
then
1687 if (
size(work) < lwork)
then
1689 call errmgr%report_error(
"mtx_inverse_dbl", &
1690 "Incorrectly sized input array WORK, argument 3.", &
1691 la_array_size_error)
1694 wptr => work(1:lwork)
1696 allocate(wrk(lwork), stat = istat)
1697 if (istat /= 0)
then
1699 call errmgr%report_error(
"mtx_inverse_dbl", &
1700 "Insufficient memory available.", &
1701 la_out_of_memory_error)
1708 if (
present(iwork))
then
1709 if (
size(iwork) < liwork)
then
1711 call errmgr%report_error(
"mtx_inverse_dbl", &
1712 "Incorrectly sized input array IWORK, argument 2.", &
1713 la_array_size_error)
1716 iptr => iwork(1:liwork)
1718 allocate(iwrk(liwork), stat = istat)
1719 if (istat /= 0)
then
1721 call errmgr%report_error(
"mtx_inverse_dbl", &
1722 "Insufficient memory available.", &
1723 la_out_of_memory_error)
1730 call dgetrf(n, n, a, n, iptr, flag)
1733 call dgetri(n, a, n, iptr, wptr, lwork, flag)
1737 call errmgr%report_error(
"mtx_inverse_dbl", &
1738 "The matrix is singular; therefore, the inverse could " // &
1739 "not be computed.", la_singular_matrix_error)
1744 module subroutine mtx_inverse_cmplx(a, iwork, work, olwork, err)
1746 complex(real64),
intent(inout),
dimension(:,:) :: a
1747 integer(int32),
intent(out),
target,
optional,
dimension(:) :: iwork
1748 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
1749 integer(int32),
intent(out),
optional :: olwork
1750 class(errors),
intent(inout),
optional,
target :: err
1753 integer(int32) :: n, liwork, lwork, istat, flag, itemp(1)
1754 integer(int32),
pointer,
dimension(:) :: iptr
1755 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
1756 complex(real64),
pointer,
dimension(:) :: wptr
1757 complex(real64),
allocatable,
target,
dimension(:) :: wrk
1758 complex(real64),
dimension(1) :: temp
1759 class(errors),
pointer :: errmgr
1760 type(errors),
target :: deferr
1765 if (
present(err))
then
1772 if (
size(a, 2) /= n)
then
1773 call errmgr%report_error(
"mtx_inverse_cmplx", &
1774 "The matrix must be squre to invert.", la_array_size_error)
1779 call zgetri(n, a, n, itemp, temp, -1, flag)
1780 lwork = int(temp(1), int32)
1781 if (
present(olwork))
then
1787 if (
present(work))
then
1788 if (
size(work) < lwork)
then
1790 call errmgr%report_error(
"mtx_inverse_cmplx", &
1791 "Incorrectly sized input array WORK, argument 3.", &
1792 la_array_size_error)
1795 wptr => work(1:lwork)
1797 allocate(wrk(lwork), stat = istat)
1798 if (istat /= 0)
then
1800 call errmgr%report_error(
"mtx_inverse_cmplx", &
1801 "Insufficient memory available.", &
1802 la_out_of_memory_error)
1809 if (
present(iwork))
then
1810 if (
size(iwork) < liwork)
then
1812 call errmgr%report_error(
"mtx_inverse_cmplx", &
1813 "Incorrectly sized input array IWORK, argument 2.", &
1814 la_array_size_error)
1817 iptr => iwork(1:liwork)
1819 allocate(iwrk(liwork), stat = istat)
1820 if (istat /= 0)
then
1822 call errmgr%report_error(
"mtx_inverse_cmplx", &
1823 "Insufficient memory available.", &
1824 la_out_of_memory_error)
1831 call zgetrf(n, n, a, n, iptr, flag)
1834 call zgetri(n, a, n, iptr, wptr, lwork, flag)
1838 call errmgr%report_error(
"mtx_inverse_cmplx", &
1839 "The matrix is singular; therefore, the inverse could " // &
1840 "not be computed.", la_singular_matrix_error)
1845 module subroutine mtx_pinverse_dbl(a, ainv, tol, work, olwork, err)
1847 real(real64),
intent(inout),
dimension(:,:) :: a
1848 real(real64),
intent(out),
dimension(:,:) :: ainv
1849 real(real64),
intent(in),
optional :: tol
1850 real(real64),
intent(out),
target,
dimension(:),
optional :: work
1851 integer(int32),
intent(out),
optional :: olwork
1852 class(errors),
intent(inout),
optional,
target :: err
1855 real(real64),
parameter :: zero = 0.0d0
1856 real(real64),
parameter :: one = 1.0d0
1859 integer(int32) :: i, m, n, mn, lwork, istat, flag, i1, i2a, i2b, i3a, &
1861 real(real64),
pointer,
dimension(:) :: s, wptr, w
1862 real(real64),
pointer,
dimension(:,:) :: u, vt
1863 real(real64),
allocatable,
target,
dimension(:) :: wrk
1864 real(real64),
dimension(1) :: temp
1865 real(real64) :: t, tref, tolcheck, ss
1866 class(errors),
pointer :: errmgr
1867 type(errors),
target :: deferr
1868 character(len = :),
allocatable :: errmsg
1876 i2b = i2a + n * mn - 1
1881 if (
present(err))
then
1888 if (
size(ainv, 1) /= n .or.
size(ainv, 2) /= m)
then
1889 allocate(
character(len = 256) :: errmsg)
1890 write(errmsg, 100) &
1891 "The output matrix AINV is not sized appropriately. " // &
1892 "It is expected to be ", n,
"-by-", m,
"."
1893 call errmgr%report_error(
"mtx_pinverse", errmsg, &
1894 la_array_size_error)
1899 call dgesvd(
'S',
'S', m, n, a, m, temp, a, m, a, n, temp, -1, flag)
1900 lrwork = int(temp(1), int32)
1901 lwork = lrwork + m * m + n * n + mn
1902 if (
present(olwork))
then
1908 if (
present(work))
then
1909 if (
size(work) < lwork)
then
1911 call errmgr%report_error(
"mtx_pinverse", &
1912 "Incorrectly sized input array WORK, argument 4.", &
1913 la_array_size_error)
1916 wptr => work(1:lwork)
1918 allocate(wrk(lwork), stat = istat)
1919 if (istat /= 0)
then
1921 call errmgr%report_error(
"mtx_pinverse", &
1922 "Insufficient memory available.", &
1923 la_out_of_memory_error)
1928 u(1:m,1:mn) => wptr(1:i1)
1929 vt(1:mn,1:n) => wptr(i2a:i2b)
1934 call dgesvd(
'S',
'S', m, n, a, m, s, u, m, vt, n, w, lrwork, flag)
1938 allocate(
character(len = 256) :: errmsg)
1939 write(errmsg, 101) flag,
" superdiagonals could not " // &
1940 "converge to zero as part of the QR iteration process."
1941 call errmgr%report_warning(
"mtx_pinverse", errmsg, &
1942 la_convergence_error)
1948 tref = max(m, n) * epsilon(t) * s(1)
1949 if (
present(tol))
then
1955 if (t < tolcheck)
then
1973 call dscal(m, ss, u(:,i), 1)
1975 call dgemm(
"T",
"T", n, m, mn, one, vt, n, u, m, zero, ainv, n)
1978100
format(a, i0, a, i0, a)
1983 module subroutine mtx_pinverse_cmplx(a, ainv, tol, work, olwork, rwork, err)
1985 complex(real64),
intent(inout),
dimension(:,:) :: a
1986 complex(real64),
intent(out),
dimension(:,:) :: ainv
1987 real(real64),
intent(in),
optional :: tol
1988 complex(real64),
intent(out),
target,
dimension(:),
optional :: work
1989 integer(int32),
intent(out),
optional :: olwork
1990 real(real64),
intent(out),
target,
dimension(:),
optional :: rwork
1991 class(errors),
intent(inout),
optional,
target :: err
1995 function dlamch(cmach)
result(x)
1996 use,
intrinsic :: iso_fortran_env, only : real64
1997 character,
intent(in) :: cmach
2003 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
2004 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
2007 integer(int32) :: i, m, n, mn, lwork, istat, flag, i1, i2a, i2b, i3, &
2009 real(real64),
pointer,
dimension(:) :: s, rwptr, rw
2010 real(real64),
allocatable,
target,
dimension(:) :: rwrk
2011 complex(real64),
pointer,
dimension(:) :: wptr, w
2012 complex(real64),
pointer,
dimension(:,:) :: u, vt
2013 complex(real64),
allocatable,
target,
dimension(:) :: wrk
2014 complex(real64) :: temp(1), val
2015 real(real64) :: t, tref, tolcheck, rtemp(1)
2016 class(errors),
pointer :: errmgr
2017 type(errors),
target :: deferr
2018 character(len = :),
allocatable :: errmsg
2027 i2b = i2a + n * n - 1
2030 if (
present(err))
then
2037 if (
size(ainv, 1) /= n .or.
size(ainv, 2) /= m)
then
2038 allocate(
character(len = 256) :: errmsg)
2039 write(errmsg, 100) &
2040 "The output matrix AINV is not sized appropriately. " // &
2041 "It is expected to be ", n,
"-by-", m,
"."
2042 call errmgr%report_error(
"mtx_pinverse_cmplx", errmsg, &
2043 la_array_size_error)
2048 call zgesvd(
'S',
'A', m, n, a, m, rtemp, a, m, a, n, temp, -1, &
2050 lwork = int(temp(1), int32)
2051 lwork = lwork + m * mn + n * n
2052 if (
present(olwork))
then
2058 if (
present(work))
then
2059 if (
size(work) < lwork)
then
2061 call errmgr%report_error(
"mtx_pinverse_cmplx", &
2062 "Incorrectly sized input array WORK, argument 4.", &
2063 la_array_size_error)
2066 wptr => work(1:lwork)
2068 allocate(wrk(lwork), stat = istat)
2069 if (istat /= 0)
then
2071 call errmgr%report_error(
"mtx_pinverse_cmplx", &
2072 "Insufficient memory available.", &
2073 la_out_of_memory_error)
2079 if (
present(rwork))
then
2080 if (
size(rwork) < lrwork)
then
2082 call errmgr%report_error(
"mtx_pinverse_cmplx", &
2083 "Incorrectly sized input array RWORK, argument 6.", &
2084 la_array_size_error)
2087 rwptr => rwork(1:lrwork)
2089 allocate(rwrk(lrwork), stat = istat)
2090 if (istat /= 0)
then
2092 call errmgr%report_error(
"mtx_pinverse_cmplx", &
2093 "Insufficient memory available.", &
2094 la_out_of_memory_error)
2099 u(1:m,1:mn) => wptr(1:i1)
2100 vt(1:n,1:n) => wptr(i2a:i2b)
2103 rw => rwptr(mn+1:lrwork)
2106 call zgesvd(
'S',
'A', m, n, a, m, s, u, m, vt, n, w,
size(w), rw, flag)
2110 allocate(
character(len = 256) :: errmsg)
2111 write(errmsg, 101) flag,
" superdiagonals could not " // &
2112 "converge to zero as part of the QR iteration process."
2113 call errmgr%report_warning(
"mtx_pinverse_cmplx", errmsg, &
2114 la_convergence_error)
2120 tref = max(m, n) * epsilon(t) * s(1)
2121 if (
present(tol))
then
2127 if (t < tolcheck)
then
2146 vt(i,1:n) = conjg(vt(i,1:n)) / s(i)
2159 val = val + vt(k,i) * conjg(u(j,k))
2166100
format(a, i0, a, i0, a)
2173 module subroutine solve_least_squares_mtx(a, b, work, olwork, err)
2175 real(real64),
intent(inout),
dimension(:,:) :: a, b
2176 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
2177 integer(int32),
intent(out),
optional :: olwork
2178 class(errors),
intent(inout),
optional,
target :: err
2181 integer(int32) :: m, n, maxmn, nrhs, lwork, istat, flag
2182 real(real64),
pointer,
dimension(:) :: wptr
2183 real(real64),
allocatable,
target,
dimension(:) :: wrk
2184 real(real64),
dimension(1) :: temp
2185 class(errors),
pointer :: errmgr
2186 type(errors),
target :: deferr
2193 if (
present(err))
then
2200 if (
size(b, 1) /= maxmn)
then
2201 call errmgr%report_error(
"solve_least_squares_mtx", &
2202 "Input 2 is not sized correctly.", la_array_size_error)
2207 call dgels(
'N', m, n, nrhs, a, m, b, maxmn, temp, -1, flag)
2208 lwork = int(temp(1), int32)
2209 if (
present(olwork))
then
2215 if (
present(work))
then
2216 if (
size(work) < lwork)
then
2218 call errmgr%report_error(
"solve_least_squares_mtx", &
2219 "Incorrectly sized input array WORK, argument 3.", &
2220 la_array_size_error)
2223 wptr => work(1:lwork)
2225 allocate(wrk(lwork), stat = istat)
2226 if (istat /= 0)
then
2228 call errmgr%report_error(
"solve_least_squares_mtx", &
2229 "Insufficient memory available.", &
2230 la_out_of_memory_error)
2237 call dgels(
'N', m, n, nrhs, a, m, b, maxmn, wptr, lwork, flag)
2239 call errmgr%report_error(
"solve_least_squares_mtx", &
2240 "The supplied matrix is not of full rank; therefore, " // &
2241 "the solution could not be computed via this routine. " // &
2242 "Try a routine that utilizes column pivoting.", &
2243 la_invalid_operation_error)
2248 module subroutine solve_least_squares_mtx_cmplx(a, b, work, olwork, err)
2250 complex(real64),
intent(inout),
dimension(:,:) :: a, b
2251 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
2252 integer(int32),
intent(out),
optional :: olwork
2253 class(errors),
intent(inout),
optional,
target :: err
2256 integer(int32) :: m, n, maxmn, nrhs, lwork, istat, flag
2257 complex(real64),
pointer,
dimension(:) :: wptr
2258 complex(real64),
allocatable,
target,
dimension(:) :: wrk
2259 complex(real64),
dimension(1) :: temp
2260 class(errors),
pointer :: errmgr
2261 type(errors),
target :: deferr
2268 if (
present(err))
then
2275 if (
size(b, 1) /= maxmn)
then
2276 call errmgr%report_error(
"solve_least_squares_mtx_cmplx", &
2277 "Input 2 is not sized correctly.", la_array_size_error)
2282 call zgels(
'N', m, n, nrhs, a, m, b, maxmn, temp, -1, flag)
2283 lwork = int(temp(1), int32)
2284 if (
present(olwork))
then
2290 if (
present(work))
then
2291 if (
size(work) < lwork)
then
2293 call errmgr%report_error(
"solve_least_squares_mtx_cmplx", &
2294 "Incorrectly sized input array WORK, argument 3.", &
2295 la_array_size_error)
2298 wptr => work(1:lwork)
2300 allocate(wrk(lwork), stat = istat)
2301 if (istat /= 0)
then
2303 call errmgr%report_error(
"solve_least_squares_mtx_cmplx", &
2304 "Insufficient memory available.", &
2305 la_out_of_memory_error)
2312 call zgels(
'N', m, n, nrhs, a, m, b, maxmn, wptr, lwork, flag)
2314 call errmgr%report_error(
"solve_least_squares_mtx_cmplx", &
2315 "The supplied matrix is not of full rank; therefore, " // &
2316 "the solution could not be computed via this routine. " // &
2317 "Try a routine that utilizes column pivoting.", &
2318 la_invalid_operation_error)
2323 module subroutine solve_least_squares_vec(a, b, work, olwork, err)
2325 real(real64),
intent(inout),
dimension(:,:) :: a
2326 real(real64),
intent(inout),
dimension(:) :: b
2327 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
2328 integer(int32),
intent(out),
optional :: olwork
2329 class(errors),
intent(inout),
optional,
target :: err
2332 integer(int32) :: m, n, maxmn, lwork, istat, flag
2333 real(real64),
pointer,
dimension(:) :: wptr
2334 real(real64),
allocatable,
target,
dimension(:) :: wrk
2335 real(real64),
dimension(1) :: temp
2336 class(errors),
pointer :: errmgr
2337 type(errors),
target :: deferr
2343 if (
present(err))
then
2350 if (
size(b) /= maxmn)
then
2351 call errmgr%report_error(
"solve_least_squares_vec", &
2352 "Input 2 is not sized correctly.", la_array_size_error)
2357 call dgels(
'N', m, n, 1, a, m, b, maxmn, temp, -1, flag)
2358 lwork = int(temp(1), int32)
2359 if (
present(olwork))
then
2365 if (
present(work))
then
2366 if (
size(work) < lwork)
then
2368 call errmgr%report_error(
"solve_least_squares_vec", &
2369 "Incorrectly sized input array WORK, argument 3.", &
2370 la_array_size_error)
2373 wptr => work(1:lwork)
2375 allocate(wrk(lwork), stat = istat)
2376 if (istat /= 0)
then
2378 call errmgr%report_error(
"solve_least_squares_vec", &
2379 "Insufficient memory available.", &
2380 la_out_of_memory_error)
2387 call dgels(
'N', m, n, 1, a, m, b, maxmn, wptr, lwork, flag)
2389 call errmgr%report_error(
"solve_least_squares_mtx", &
2390 "The supplied matrix is not of full rank; therefore, " // &
2391 "the solution could not be computed via this routine. " // &
2392 "Try a routine that utilizes column pivoting.", &
2393 la_invalid_operation_error)
2398 module subroutine solve_least_squares_vec_cmplx(a, b, work, olwork, err)
2400 complex(real64),
intent(inout),
dimension(:,:) :: a
2401 complex(real64),
intent(inout),
dimension(:) :: b
2402 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
2403 integer(int32),
intent(out),
optional :: olwork
2404 class(errors),
intent(inout),
optional,
target :: err
2407 integer(int32) :: m, n, maxmn, lwork, istat, flag
2408 complex(real64),
pointer,
dimension(:) :: wptr
2409 complex(real64),
allocatable,
target,
dimension(:) :: wrk
2410 complex(real64),
dimension(1) :: temp
2411 class(errors),
pointer :: errmgr
2412 type(errors),
target :: deferr
2418 if (
present(err))
then
2425 if (
size(b) /= maxmn)
then
2426 call errmgr%report_error(
"solve_least_squares_vec_cmplx", &
2427 "Input 2 is not sized correctly.", la_array_size_error)
2432 call zgels(
'N', m, n, 1, a, m, b, maxmn, temp, -1, flag)
2433 lwork = int(temp(1), int32)
2434 if (
present(olwork))
then
2440 if (
present(work))
then
2441 if (
size(work) < lwork)
then
2443 call errmgr%report_error(
"solve_least_squares_vec_cmplx", &
2444 "Incorrectly sized input array WORK, argument 3.", &
2445 la_array_size_error)
2448 wptr => work(1:lwork)
2450 allocate(wrk(lwork), stat = istat)
2451 if (istat /= 0)
then
2453 call errmgr%report_error(
"solve_least_squares_vec_cmplx", &
2454 "Insufficient memory available.", &
2455 la_out_of_memory_error)
2462 call zgels(
'N', m, n, 1, a, m, b, maxmn, wptr, lwork, flag)
2464 call errmgr%report_error(
"solve_least_squares_mtx_cmplx", &
2465 "The supplied matrix is not of full rank; therefore, " // &
2466 "the solution could not be computed via this routine. " // &
2467 "Try a routine that utilizes column pivoting.", &
2468 la_invalid_operation_error)
2473 module subroutine solve_least_squares_mtx_pvt(a, b, ipvt, arnk, work, olwork, err)
2475 real(real64),
intent(inout),
dimension(:,:) :: a, b
2476 integer(int32),
intent(inout),
target,
optional,
dimension(:) :: ipvt
2477 integer(int32),
intent(out),
optional :: arnk
2478 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
2479 integer(int32),
intent(out),
optional :: olwork
2480 class(errors),
intent(inout),
optional,
target :: err
2483 integer(int32) :: m, n, maxmn, nrhs, lwork, istat, flag, rnk
2484 real(real64),
pointer,
dimension(:) :: wptr
2485 real(real64),
allocatable,
target,
dimension(:) :: wrk
2486 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
2487 integer(int32),
pointer,
dimension(:) :: iptr
2488 real(real64),
dimension(1) :: temp
2489 integer(int32),
dimension(1) :: itemp
2491 class(errors),
pointer :: errmgr
2492 type(errors),
target :: deferr
2493 character(len = :),
allocatable :: errmsg
2501 if (
present(arnk)) arnk = 0
2502 if (
present(err))
then
2510 if (
size(b, 1) /= maxmn)
then
2514 allocate(
character(len = 256) :: errmsg)
2515 write(errmsg, 100)
"Input number ", flag, &
2516 " is not sized correctly."
2517 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2518 trim(errmsg), la_array_size_error)
2523 call dgelsy(m, n, nrhs, a, m, b, maxmn, itemp, rc, rnk, temp, -1, flag)
2524 lwork = int(temp(1), int32)
2525 if (
present(olwork))
then
2531 if (
present(ipvt))
then
2532 if (
size(ipvt) < n)
then
2534 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2535 "Incorrectly sized pivot array, argument 3.", &
2536 la_array_size_error)
2541 allocate(iwrk(n), stat = istat)
2542 if (istat /= 0)
then
2544 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2545 "Insufficient memory available.", &
2546 la_out_of_memory_error)
2553 if (
present(work))
then
2554 if (
size(work) < lwork)
then
2556 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2557 "Incorrectly sized input array WORK, argument 5.", &
2558 la_array_size_error)
2561 wptr => work(1:lwork)
2563 allocate(wrk(lwork), stat = istat)
2564 if (istat /= 0)
then
2566 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2567 "Insufficient memory available.", &
2568 la_out_of_memory_error)
2575 call dgelsy(m, n, nrhs, a, m, b, maxmn, iptr, rc, rnk, wptr, lwork, &
2577 if (
present(arnk)) arnk = rnk
2584 module subroutine solve_least_squares_mtx_pvt_cmplx(a, b, ipvt, arnk, &
2585 work, olwork, rwork, err)
2587 complex(real64),
intent(inout),
dimension(:,:) :: a, b
2588 integer(int32),
intent(inout),
target,
optional,
dimension(:) :: ipvt
2589 integer(int32),
intent(out),
optional :: arnk
2590 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
2591 integer(int32),
intent(out),
optional :: olwork
2592 real(real64),
intent(out),
target,
optional,
dimension(:) :: rwork
2593 class(errors),
intent(inout),
optional,
target :: err
2596 integer(int32) :: m, n, maxmn, nrhs, lwork, istat, flag, rnk, lrwork
2597 complex(real64),
pointer,
dimension(:) :: wptr
2598 complex(real64),
allocatable,
target,
dimension(:) :: wrk
2599 real(real64),
pointer,
dimension(:) :: rwptr
2600 real(real64),
allocatable,
target,
dimension(:) :: rwrk
2601 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
2602 integer(int32),
pointer,
dimension(:) :: iptr
2603 complex(real64),
dimension(1) :: temp
2604 real(real64),
dimension(1) :: rtemp
2605 integer(int32),
dimension(1) :: itemp
2607 class(errors),
pointer :: errmgr
2608 type(errors),
target :: deferr
2609 character(len = :),
allocatable :: errmsg
2618 if (
present(arnk)) arnk = 0
2619 if (
present(err))
then
2627 if (
size(b, 1) /= maxmn)
then
2631 allocate(
character(len = 256) :: errmsg)
2632 write(errmsg, 100)
"Input number ", flag, &
2633 " is not sized correctly."
2634 call errmgr%report_error(
"solve_least_squares_mtx_pvt_cmplx", &
2635 trim(errmsg), la_array_size_error)
2640 call zgelsy(m, n, nrhs, a, m, b, maxmn, itemp, rc, rnk, temp, -1, &
2642 lwork = int(temp(1), int32)
2643 if (
present(olwork))
then
2649 if (
present(ipvt))
then
2650 if (
size(ipvt) < n)
then
2652 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2653 "Incorrectly sized pivot array, argument 3.", &
2654 la_array_size_error)
2659 allocate(iwrk(n), stat = istat)
2660 if (istat /= 0)
then
2662 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2663 "Insufficient memory available.", &
2664 la_out_of_memory_error)
2671 if (
present(work))
then
2672 if (
size(work) < lwork)
then
2674 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2675 "Incorrectly sized input array WORK, argument 5.", &
2676 la_array_size_error)
2679 wptr => work(1:lwork)
2681 allocate(wrk(lwork), stat = istat)
2682 if (istat /= 0)
then
2684 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2685 "Insufficient memory available.", &
2686 la_out_of_memory_error)
2692 if (
present(rwork))
then
2693 if (
size(rwork) < lrwork)
then
2695 call errmgr%report_error(
"solve_least_squares_mtx_pvt_cmplx", &
2696 "Incorrectly sized input array RWORK, argument 7.", &
2697 la_array_size_error)
2700 rwptr => rwork(1:lrwork)
2702 allocate(rwrk(lrwork), stat = istat)
2703 if (istat /= 0)
then
2705 call errmgr%report_error(
"solve_least_squares_mtx_pvt_cmplx", &
2706 "Insufficient memory available.", &
2707 la_out_of_memory_error)
2714 call zgelsy(m, n, nrhs, a, m, b, maxmn, iptr, rc, rnk, wptr, lwork, &
2716 if (
present(arnk)) arnk = rnk
2723 module subroutine solve_least_squares_vec_pvt(a, b, ipvt, arnk, work, olwork, err)
2725 real(real64),
intent(inout),
dimension(:,:) :: a
2726 real(real64),
intent(inout),
dimension(:) :: b
2727 integer(int32),
intent(inout),
target,
optional,
dimension(:) :: ipvt
2728 integer(int32),
intent(out),
optional :: arnk
2729 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
2730 integer(int32),
intent(out),
optional :: olwork
2731 class(errors),
intent(inout),
optional,
target :: err
2734 integer(int32) :: m, n, maxmn, lwork, istat, flag, rnk
2735 real(real64),
pointer,
dimension(:) :: wptr
2736 real(real64),
allocatable,
target,
dimension(:) :: wrk
2737 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
2738 integer(int32),
pointer,
dimension(:) :: iptr
2739 real(real64),
dimension(1) :: temp
2740 integer(int32),
dimension(1) :: itemp
2742 class(errors),
pointer :: errmgr
2743 type(errors),
target :: deferr
2744 character(len = :),
allocatable :: errmsg
2751 if (
present(arnk)) arnk = 0
2752 if (
present(err))
then
2760 if (
size(b, 1) /= maxmn)
then
2764 allocate(
character(len = 256) :: errmsg)
2765 write(errmsg, 100)
"Input number ", flag, &
2766 " is not sized correctly."
2767 call errmgr%report_error(
"solve_least_squares_vec_pvt", &
2768 trim(errmsg), la_array_size_error)
2773 call dgelsy(m, n, 1, a, m, b, maxmn, itemp, rc, rnk, temp, -1, flag)
2774 lwork = int(temp(1), int32)
2775 if (
present(olwork))
then
2781 if (
present(ipvt))
then
2782 if (
size(ipvt) < n)
then
2784 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2785 "Incorrectly sized pivot array, argument 3.", &
2786 la_array_size_error)
2791 allocate(iwrk(n), stat = istat)
2792 if (istat /= 0)
then
2794 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2795 "Insufficient memory available.", &
2796 la_out_of_memory_error)
2803 if (
present(work))
then
2804 if (
size(work) < lwork)
then
2806 call errmgr%report_error(
"solve_least_squares_vec_pvt", &
2807 "Incorrectly sized input array WORK, argument 5.", &
2808 la_array_size_error)
2811 wptr => work(1:lwork)
2813 allocate(wrk(lwork), stat = istat)
2814 if (istat /= 0)
then
2816 call errmgr%report_error(
"solve_least_squares_vec_pvt", &
2817 "Insufficient memory available.", &
2818 la_out_of_memory_error)
2825 call dgelsy(m, n, 1, a, m, b, maxmn, iptr, rc, rnk, wptr, lwork, flag)
2826 if (
present(arnk)) arnk = rnk
2833 module subroutine solve_least_squares_vec_pvt_cmplx(a, b, ipvt, arnk, &
2834 work, olwork, rwork, err)
2836 complex(real64),
intent(inout),
dimension(:,:) :: a
2837 complex(real64),
intent(inout),
dimension(:) :: b
2838 integer(int32),
intent(inout),
target,
optional,
dimension(:) :: ipvt
2839 integer(int32),
intent(out),
optional :: arnk
2840 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
2841 integer(int32),
intent(out),
optional :: olwork
2842 real(real64),
intent(out),
target,
optional,
dimension(:) :: rwork
2843 class(errors),
intent(inout),
optional,
target :: err
2846 integer(int32) :: m, n, maxmn, lwork, lrwork, istat, flag, rnk
2847 complex(real64),
pointer,
dimension(:) :: wptr
2848 complex(real64),
allocatable,
target,
dimension(:) :: wrk
2849 real(real64),
pointer,
dimension(:) :: rwptr
2850 real(real64),
allocatable,
target,
dimension(:) :: rwrk
2851 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
2852 integer(int32),
pointer,
dimension(:) :: iptr
2853 complex(real64),
dimension(1) :: temp
2854 real(real64),
dimension(1) :: rtemp
2855 integer(int32),
dimension(1) :: itemp
2857 class(errors),
pointer :: errmgr
2858 type(errors),
target :: deferr
2859 character(len = :),
allocatable :: errmsg
2867 if (
present(arnk)) arnk = 0
2868 if (
present(err))
then
2876 if (
size(b, 1) /= maxmn)
then
2880 allocate(
character(len = 256) :: errmsg)
2881 write(errmsg, 100)
"Input number ", flag, &
2882 " is not sized correctly."
2883 call errmgr%report_error(
"solve_least_squares_vec_pvt_cmplx", &
2884 trim(errmsg), la_array_size_error)
2889 call zgelsy(m, n, 1, a, m, b, maxmn, itemp, rc, rnk, temp, -1, rtemp, &
2891 lwork = int(temp(1), int32)
2892 if (
present(olwork))
then
2898 if (
present(ipvt))
then
2899 if (
size(ipvt) < n)
then
2901 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2902 "Incorrectly sized pivot array, argument 3.", &
2903 la_array_size_error)
2908 allocate(iwrk(n), stat = istat)
2909 if (istat /= 0)
then
2911 call errmgr%report_error(
"solve_least_squares_mtx_pvt", &
2912 "Insufficient memory available.", &
2913 la_out_of_memory_error)
2920 if (
present(work))
then
2921 if (
size(work) < lwork)
then
2923 call errmgr%report_error(
"solve_least_squares_vec_pvt_cmplx", &
2924 "Incorrectly sized input array WORK, argument 5.", &
2925 la_array_size_error)
2928 wptr => work(1:lwork)
2930 allocate(wrk(lwork), stat = istat)
2931 if (istat /= 0)
then
2933 call errmgr%report_error(
"solve_least_squares_vec_pvt_cmplx", &
2934 "Insufficient memory available.", &
2935 la_out_of_memory_error)
2941 if (
present(rwork))
then
2942 if (
size(rwork) < lrwork)
then
2944 call errmgr%report_error(
"solve_least_squares_vec_pvt_cmplx", &
2945 "Incorrectly sized input array RWORK, argument 7.", &
2946 la_array_size_error)
2949 rwptr => rwork(1:lrwork)
2951 allocate(rwrk(lrwork), stat = istat)
2952 if (istat /= 0)
then
2954 call errmgr%report_error(
"solve_least_squares_vec_pvt_cmplx", &
2955 "Insufficient memory available.", &
2956 la_out_of_memory_error)
2963 call zgelsy(m, n, 1, a, m, b, maxmn, iptr, rc, rnk, wptr, lwork, &
2965 if (
present(arnk)) arnk = rnk
2972 module subroutine solve_least_squares_mtx_svd(a, b, s, arnk, work, olwork, err)
2974 real(real64),
intent(inout),
dimension(:,:) :: a, b
2975 integer(int32),
intent(out),
optional :: arnk
2976 real(real64),
intent(out),
target,
optional,
dimension(:) :: work, s
2977 integer(int32),
intent(out),
optional :: olwork
2978 class(errors),
intent(inout),
optional,
target :: err
2981 integer(int32) :: m, n, nrhs, mn, maxmn, istat, flag, lwork, rnk
2982 real(real64),
pointer,
dimension(:) :: wptr, sptr
2983 real(real64),
allocatable,
target,
dimension(:) :: wrk, sing
2984 real(real64),
dimension(1) :: temp
2985 real(real64) :: rcond
2986 class(errors),
pointer :: errmgr
2987 type(errors),
target :: deferr
2988 character(len = :),
allocatable :: errmsg
2996 rcond = epsilon(rcond)
2997 if (
present(arnk)) arnk = 0
2998 if (
present(err))
then
3006 if (
size(b, 1) /= maxmn)
then
3011 allocate(
character(len = 256) :: errmsg)
3012 write(errmsg, 100)
"Input number ", flag, &
3013 " is not sized correctly."
3014 call errmgr%report_error(
"solve_least_squares_mtx_svd", &
3015 trim(errmsg), la_array_size_error)
3020 call dgelss(m, n, nrhs, a, m, b, maxmn, temp, rcond, rnk, temp, -1, &
3022 lwork = int(temp(1), int32)
3023 if (
present(olwork))
then
3029 if (
present(s))
then
3030 if (
size(s) < mn)
then
3032 call errmgr%report_error(
"solve_least_squares_mtx_svd", &
3033 "Incorrectly sized input array S, argument 3.", &
3034 la_array_size_error)
3039 allocate(sing(mn), stat = istat)
3040 if (istat /= 0)
then
3042 call errmgr%report_error(
"solve_least_squares_mtx_svd", &
3043 "Insufficient memory available.", &
3044 la_out_of_memory_error)
3050 if (
present(work))
then
3051 if (
size(work) < lwork)
then
3053 call errmgr%report_error(
"solve_least_squares_mtx_svd", &
3054 "Incorrectly sized input array WORK, argument 5.", &
3055 la_array_size_error)
3058 wptr => work(1:lwork)
3060 allocate(wrk(lwork), stat = istat)
3061 if (istat /= 0)
then
3063 call errmgr%report_error(
"solve_least_squares_mtx_svd", &
3064 "Insufficient memory available.", &
3065 la_out_of_memory_error)
3072 call dgelss(m, n, nrhs, a, m, b, maxmn, sptr, rcond, rnk, wptr, lwork, &
3074 if (
present(arnk)) arnk = rnk
3076 allocate(
character(len = 256) :: errmsg)
3077 write(errmsg, 101) flag,
" superdiagonals could not " // &
3078 "converge to zero as part of the QR iteration process."
3079 call errmgr%report_warning(
"solve_least_squares_mtx_svd", errmsg, &
3080 la_convergence_error)
3089 module subroutine solve_least_squares_mtx_svd_cmplx(a, b, s, arnk, work, &
3092 complex(real64),
intent(inout),
dimension(:,:) :: a, b
3093 integer(int32),
intent(out),
optional :: arnk
3094 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
3095 real(real64),
intent(out),
target,
optional,
dimension(:) :: s, rwork
3096 integer(int32),
intent(out),
optional :: olwork
3097 class(errors),
intent(inout),
optional,
target :: err
3100 integer(int32) :: m, n, nrhs, mn, maxmn, istat, flag, lwork, rnk, lrwork
3101 complex(real64),
pointer,
dimension(:) :: wptr
3102 complex(real64),
allocatable,
target,
dimension(:) :: wrk
3103 real(real64),
pointer,
dimension(:) :: rwptr, sptr
3104 real(real64),
allocatable,
target,
dimension(:) :: rwrk, sing
3105 complex(real64),
dimension(1) :: temp
3106 real(real64),
dimension(1) :: rtemp
3107 real(real64) :: rcond
3108 class(errors),
pointer :: errmgr
3109 type(errors),
target :: deferr
3110 character(len = :),
allocatable :: errmsg
3119 rcond = epsilon(rcond)
3120 if (
present(arnk)) arnk = 0
3121 if (
present(err))
then
3129 if (
size(b, 1) /= maxmn)
then
3134 allocate(
character(len = 256) :: errmsg)
3135 write(errmsg, 100)
"Input number ", flag, &
3136 " is not sized correctly."
3137 call errmgr%report_error(
"solve_least_squares_mtx_svd_cmplx", &
3138 trim(errmsg), la_array_size_error)
3143 call zgelss(m, n, nrhs, a, m, b, maxmn, rtemp, rcond, rnk, temp, -1, &
3145 lwork = int(temp(1), int32)
3146 if (
present(olwork))
then
3152 if (
present(s))
then
3153 if (
size(s) < mn)
then
3155 call errmgr%report_error(
"solve_least_squares_mtx_svd_cmplx", &
3156 "Incorrectly sized input array S, argument 3.", &
3157 la_array_size_error)
3162 allocate(sing(mn), stat = istat)
3163 if (istat /= 0)
then
3165 call errmgr%report_error(
"solve_least_squares_mtx_svd_cmplx", &
3166 "Insufficient memory available.", &
3167 la_out_of_memory_error)
3173 if (
present(work))
then
3174 if (
size(work) < lwork)
then
3176 call errmgr%report_error(
"solve_least_squares_mtx_svd_cmplx", &
3177 "Incorrectly sized input array WORK, argument 5.", &
3178 la_array_size_error)
3181 wptr => work(1:lwork)
3183 allocate(wrk(lwork), stat = istat)
3184 if (istat /= 0)
then
3186 call errmgr%report_error(
"solve_least_squares_mtx_svd_cmplx", &
3187 "Insufficient memory available.", &
3188 la_out_of_memory_error)
3194 if (
present(rwork))
then
3195 if (
size(rwork) < lrwork)
then
3197 call errmgr%report_error(
"solve_least_squares_mtx_svd_cmplx", &
3198 "Incorrectly sized input array RWORK, argument 7.", &
3199 la_array_size_error)
3202 rwptr => rwork(1:lrwork)
3204 allocate(rwrk(lrwork), stat = istat)
3205 if (istat /= 0)
then
3207 call errmgr%report_error(
"solve_least_squares_mtx_svd_cmplx", &
3208 "Insufficient memory available.", &
3209 la_out_of_memory_error)
3216 call zgelss(m, n, nrhs, a, m, b, maxmn, sptr, rcond, rnk, wptr, lwork, &
3218 if (
present(arnk)) arnk = rnk
3220 allocate(
character(len = 256) :: errmsg)
3221 write(errmsg, 101) flag,
" superdiagonals could not " // &
3222 "converge to zero as part of the QR iteration process."
3223 call errmgr%report_warning(
"solve_least_squares_mtx_svd_cmplx", &
3224 errmsg, la_convergence_error)
3233 module subroutine solve_least_squares_vec_svd(a, b, s, arnk, work, olwork, err)
3235 real(real64),
intent(inout),
dimension(:,:) :: a
3236 real(real64),
intent(inout),
dimension(:) :: b
3237 integer(int32),
intent(out),
optional :: arnk
3238 real(real64),
intent(out),
target,
optional,
dimension(:) :: work, s
3239 integer(int32),
intent(out),
optional :: olwork
3240 class(errors),
intent(inout),
optional,
target :: err
3243 integer(int32) :: m, n, mn, maxmn, istat, flag, lwork, rnk
3244 real(real64),
pointer,
dimension(:) :: wptr, sptr
3245 real(real64),
allocatable,
target,
dimension(:) :: wrk, sing
3246 real(real64),
dimension(1) :: temp
3247 real(real64) :: rcond
3248 class(errors),
pointer :: errmgr
3249 type(errors),
target :: deferr
3250 character(len = :),
allocatable :: errmsg
3257 rcond = epsilon(rcond)
3258 if (
present(arnk)) arnk = 0
3259 if (
present(err))
then
3267 if (
size(b) /= maxmn)
then
3272 allocate(
character(len = 256) :: errmsg)
3273 write(errmsg, 100)
"Input number ", flag, &
3274 " is not sized correctly."
3275 call errmgr%report_error(
"solve_least_squares_vec_svd", &
3276 trim(errmsg), la_array_size_error)
3281 call dgelss(m, n, 1, a, m, b, maxmn, temp, rcond, rnk, temp, -1, flag)
3282 lwork = int(temp(1), int32)
3283 if (
present(olwork))
then
3289 if (
present(s))
then
3290 if (
size(s) < mn)
then
3292 call errmgr%report_error(
"solve_least_squares_vec_svd", &
3293 "Incorrectly sized input array S, argument 3.", &
3294 la_array_size_error)
3299 allocate(sing(mn), stat = istat)
3300 if (istat /= 0)
then
3302 call errmgr%report_error(
"solve_least_squares_vec_svd", &
3303 "Insufficient memory available.", &
3304 la_out_of_memory_error)
3310 if (
present(work))
then
3311 if (
size(work) < lwork)
then
3313 call errmgr%report_error(
"solve_least_squares_vec_svd", &
3314 "Incorrectly sized input array WORK, argument 5.", &
3315 la_array_size_error)
3318 wptr => work(1:lwork)
3320 allocate(wrk(lwork), stat = istat)
3321 if (istat /= 0)
then
3323 call errmgr%report_error(
"solve_least_squares_vec_svd", &
3324 "Insufficient memory available.", &
3325 la_out_of_memory_error)
3332 call dgelss(m, n, 1, a, m, b, maxmn, sptr, rcond, rnk, wptr, lwork, &
3334 if (
present(arnk)) arnk = rnk
3336 allocate(
character(len = 256) :: errmsg)
3337 write(errmsg, 101) flag,
" superdiagonals could not " // &
3338 "converge to zero as part of the QR iteration process."
3339 call errmgr%report_warning(
"solve_least_squares_vec_svd", errmsg, &
3340 la_convergence_error)
3349 module subroutine solve_least_squares_vec_svd_cmplx(a, b, s, arnk, work, &
3352 complex(real64),
intent(inout),
dimension(:,:) :: a
3353 complex(real64),
intent(inout),
dimension(:) :: b
3354 integer(int32),
intent(out),
optional :: arnk
3355 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
3356 real(real64),
intent(out),
target,
optional,
dimension(:) :: rwork, s
3357 integer(int32),
intent(out),
optional :: olwork
3358 class(errors),
intent(inout),
optional,
target :: err
3361 integer(int32) :: m, n, mn, maxmn, istat, flag, lwork, rnk, lrwork
3362 real(real64),
pointer,
dimension(:) :: rwptr, sptr
3363 real(real64),
allocatable,
target,
dimension(:) :: rwrk, sing
3364 complex(real64),
pointer,
dimension(:) :: wptr
3365 complex(real64),
allocatable,
target,
dimension(:) :: wrk
3366 complex(real64),
dimension(1) :: temp
3367 real(real64),
dimension(1) :: rtemp
3368 real(real64) :: rcond
3369 class(errors),
pointer :: errmgr
3370 type(errors),
target :: deferr
3371 character(len = :),
allocatable :: errmsg
3379 rcond = epsilon(rcond)
3380 if (
present(arnk)) arnk = 0
3381 if (
present(err))
then
3389 if (
size(b) /= maxmn)
then
3394 allocate(
character(len = 256) :: errmsg)
3395 write(errmsg, 100)
"Input number ", flag, &
3396 " is not sized correctly."
3397 call errmgr%report_error(
"solve_least_squares_vec_svd_cmplx", &
3398 trim(errmsg), la_array_size_error)
3403 call zgelss(m, n, 1, a, m, b, maxmn, rtemp, rcond, rnk, temp, -1, &
3405 lwork = int(temp(1), int32)
3406 if (
present(olwork))
then
3412 if (
present(s))
then
3413 if (
size(s) < mn)
then
3415 call errmgr%report_error(
"solve_least_squares_vec_svd_cmplx", &
3416 "Incorrectly sized input array S, argument 3.", &
3417 la_array_size_error)
3422 allocate(sing(mn), stat = istat)
3423 if (istat /= 0)
then
3425 call errmgr%report_error(
"solve_least_squares_vec_svd_cmplx", &
3426 "Insufficient memory available.", &
3427 la_out_of_memory_error)
3433 if (
present(work))
then
3434 if (
size(work) < lwork)
then
3436 call errmgr%report_error(
"solve_least_squares_vec_svd_cmplx", &
3437 "Incorrectly sized input array WORK, argument 5.", &
3438 la_array_size_error)
3441 wptr => work(1:lwork)
3443 allocate(wrk(lwork), stat = istat)
3444 if (istat /= 0)
then
3446 call errmgr%report_error(
"solve_least_squares_vec_svd_cmplx", &
3447 "Insufficient memory available.", &
3448 la_out_of_memory_error)
3454 if (
present(rwork))
then
3455 if (
size(rwork) < lrwork)
then
3457 call errmgr%report_error(
"solve_least_squares_vec_svd_cmplx", &
3458 "Incorrectly sized input array RWORK, argument 7.", &
3459 la_array_size_error)
3462 rwptr => rwork(1:lrwork)
3464 allocate(rwrk(lrwork), stat = istat)
3465 if (istat /= 0)
then
3467 call errmgr%report_error(
"solve_least_squares_vec_svd_cmplx", &
3468 "Insufficient memory available.", &
3469 la_out_of_memory_error)
3476 call zgelss(m, n, 1, a, m, b, maxmn, sptr, rcond, rnk, wptr, lwork, &
3478 if (
present(arnk)) arnk = rnk
3480 allocate(
character(len = 256) :: errmsg)
3481 write(errmsg, 101) flag,
" superdiagonals could not " // &
3482 "converge to zero as part of the QR iteration process."
3483 call errmgr%report_warning(
"solve_least_squares_vec_svd_cmplx", &
3484 errmsg, la_convergence_error)
3495 module subroutine solve_lq_mtx(a, tau, b, work, olwork, err)
3497 real(real64),
intent(in),
dimension(:,:) :: a
3498 real(real64),
intent(in),
dimension(:) :: tau
3499 real(real64),
intent(inout),
dimension(:,:) :: b
3500 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
3501 integer(int32),
intent(out),
optional :: olwork
3502 class(errors),
intent(inout),
optional,
target :: err
3505 real(real64),
parameter :: one = 1.0d0
3508 integer(int32) :: m, n, nrhs, k, lwork, flag, istat
3509 real(real64),
pointer,
dimension(:) :: wptr
3510 real(real64),
allocatable,
target,
dimension(:) :: wrk
3511 class(errors),
pointer :: errmgr
3512 type(errors),
target :: deferr
3513 character(len = :),
allocatable :: errmsg
3520 if (
present(err))
then
3530 else if (
size(tau) /= k)
then
3532 else if (
size(b, 1) /= n)
then
3538 allocate(
character(len = 256) :: errmsg)
3539 write(errmsg, 100)
"Input number ", flag, &
3540 " is not sized correctly."
3541 call errmgr%report_error(
"solve_lq_mtx", trim(errmsg), &
3542 la_array_size_error)
3547 call mult_lq(.true., .true., a, tau, b, olwork = lwork)
3549 if (
present(olwork))
then
3555 if (
present(work))
then
3556 if (
size(work) < lwork)
then
3558 call errmgr%report_error(
"solve_lq_mtx", &
3559 "Incorrectly sized input array WORK, argument 4.", &
3560 la_array_size_error)
3563 wptr => work(1:lwork)
3565 allocate(wrk(lwork), stat = istat)
3566 if (istat /= 0)
then
3568 call errmgr%report_error(
"solve_lq_mtx", &
3569 "Insufficient memory available.", &
3570 la_out_of_memory_error)
3578 call solve_triangular_system(.true., .false., .false., .true., one, &
3579 a(1:m,1:m), b(1:m,:), errmgr)
3580 if (errmgr%has_error_occurred())
return
3583 call mult_lq(.true., .true., a, tau, b, work = wptr, err = errmgr)
3584 if (errmgr%has_error_occurred())
return
3591 module subroutine solve_lq_mtx_cmplx(a, tau, b, work, olwork, err)
3593 complex(real64),
intent(in),
dimension(:,:) :: a
3594 complex(real64),
intent(in),
dimension(:) :: tau
3595 complex(real64),
intent(inout),
dimension(:,:) :: b
3596 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
3597 integer(int32),
intent(out),
optional :: olwork
3598 class(errors),
intent(inout),
optional,
target :: err
3601 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
3604 integer(int32) :: m, n, nrhs, k, lwork, flag, istat
3605 complex(real64),
pointer,
dimension(:) :: wptr
3606 complex(real64),
allocatable,
target,
dimension(:) :: wrk
3607 class(errors),
pointer :: errmgr
3608 type(errors),
target :: deferr
3609 character(len = :),
allocatable :: errmsg
3616 if (
present(err))
then
3626 else if (
size(tau) /= k)
then
3628 else if (
size(b, 1) /= n)
then
3634 allocate(
character(len = 256) :: errmsg)
3635 write(errmsg, 100)
"Input number ", flag, &
3636 " is not sized correctly."
3637 call errmgr%report_error(
"solve_lq_mtx_cmplx", trim(errmsg), &
3638 la_array_size_error)
3643 call mult_lq(.true., .true., a, tau, b, olwork = lwork)
3645 if (
present(olwork))
then
3651 if (
present(work))
then
3652 if (
size(work) < lwork)
then
3654 call errmgr%report_error(
"solve_lq_mtx_cmplx", &
3655 "Incorrectly sized input array WORK, argument 4.", &
3656 la_array_size_error)
3659 wptr => work(1:lwork)
3661 allocate(wrk(lwork), stat = istat)
3662 if (istat /= 0)
then
3664 call errmgr%report_error(
"solve_lq_mtx_cmplx", &
3665 "Insufficient memory available.", &
3666 la_out_of_memory_error)
3674 call solve_triangular_system(.true., .false., .false., .true., one, &
3675 a(1:m,1:m), b(1:m,:), errmgr)
3676 if (errmgr%has_error_occurred())
return
3679 call mult_lq(.true., .true., a, tau, b, work = wptr, err = errmgr)
3680 if (errmgr%has_error_occurred())
return
3687 module subroutine solve_lq_vec(a, tau, b, work, olwork, err)
3689 real(real64),
intent(in),
dimension(:,:) :: a
3690 real(real64),
intent(in),
dimension(:) :: tau
3691 real(real64),
intent(inout),
dimension(:) :: b
3692 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
3693 integer(int32),
intent(out),
optional :: olwork
3694 class(errors),
intent(inout),
optional,
target :: err
3697 integer(int32) :: m, n, k, lwork, flag, istat
3698 real(real64),
pointer,
dimension(:) :: wptr
3699 real(real64),
allocatable,
target,
dimension(:) :: wrk
3700 class(errors),
pointer :: errmgr
3701 type(errors),
target :: deferr
3702 character(len = :),
allocatable :: errmsg
3708 if (
present(err))
then
3718 else if (
size(tau) /= k)
then
3720 else if (
size(b) /= n)
then
3726 allocate(
character(len = 256) :: errmsg)
3727 write(errmsg, 100)
"Input number ", flag, &
3728 " is not sized correctly."
3729 call errmgr%report_error(
"solve_lq_vec", trim(errmsg), &
3730 la_array_size_error)
3735 call mult_lq(.true., a, tau, b, olwork = lwork)
3737 if (
present(olwork))
then
3743 if (
present(work))
then
3744 if (
size(work) < lwork)
then
3746 call errmgr%report_error(
"solve_lq_vec", &
3747 "Incorrectly sized input array WORK, argument 4.", &
3748 la_array_size_error)
3751 wptr => work(1:lwork)
3753 allocate(wrk(lwork), stat = istat)
3754 if (istat /= 0)
then
3756 call errmgr%report_error(
"solve_lq_vec", &
3757 "Insufficient memory available.", &
3758 la_out_of_memory_error)
3766 call solve_triangular_system(.false., .false., .true., a(1:m,1:m), &
3768 if (errmgr%has_error_occurred())
return
3771 call mult_lq(.true., a, tau, b, work = wptr, err = errmgr)
3772 if (errmgr%has_error_occurred())
return
3779 module subroutine solve_lq_vec_cmplx(a, tau, b, work, olwork, err)
3781 complex(real64),
intent(in),
dimension(:,:) :: a
3782 complex(real64),
intent(in),
dimension(:) :: tau
3783 complex(real64),
intent(inout),
dimension(:) :: b
3784 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
3785 integer(int32),
intent(out),
optional :: olwork
3786 class(errors),
intent(inout),
optional,
target :: err
3789 integer(int32) :: m, n, k, lwork, flag, istat
3790 complex(real64),
pointer,
dimension(:) :: wptr
3791 complex(real64),
allocatable,
target,
dimension(:) :: wrk
3792 class(errors),
pointer :: errmgr
3793 type(errors),
target :: deferr
3794 character(len = :),
allocatable :: errmsg
3800 if (
present(err))
then
3810 else if (
size(tau) /= k)
then
3812 else if (
size(b) /= n)
then
3818 allocate(
character(len = 256) :: errmsg)
3819 write(errmsg, 100)
"Input number ", flag, &
3820 " is not sized correctly."
3821 call errmgr%report_error(
"solve_lq_vec_cmplx", trim(errmsg), &
3822 la_array_size_error)
3827 call mult_lq(.true., a, tau, b, olwork = lwork)
3829 if (
present(olwork))
then
3835 if (
present(work))
then
3836 if (
size(work) < lwork)
then
3838 call errmgr%report_error(
"solve_lq_vec_cmplx", &
3839 "Incorrectly sized input array WORK, argument 4.", &
3840 la_array_size_error)
3843 wptr => work(1:lwork)
3845 allocate(wrk(lwork), stat = istat)
3846 if (istat /= 0)
then
3848 call errmgr%report_error(
"solve_lq_vec_cmplx", &
3849 "Insufficient memory available.", &
3850 la_out_of_memory_error)
3858 call solve_triangular_system(.false., .false., .true., a(1:m,1:m), &
3860 if (errmgr%has_error_occurred())
return
3863 call mult_lq(.true., a, tau, b, work = wptr, err = errmgr)
3864 if (errmgr%has_error_occurred())
return
A module providing explicit interfaces to BLAS routines.
Provides a set of common linear algebra routines.