7submodule(
linalg) linalg_sorting
14 module subroutine sort_dbl_array(x, ascend)
16 real(real64),
intent(inout),
dimension(:) :: x
17 logical,
intent(in),
optional :: ascend
21 integer(int32) :: n, info
24 if (
present(ascend))
then
36 call dlasrt(id, n, x, info)
40 module subroutine sort_dbl_array_ind(x, ind, ascend, err)
42 real(real64),
intent(inout),
dimension(:) :: x
43 integer(int32),
intent(inout),
dimension(:) :: ind
44 logical,
intent(in),
optional :: ascend
45 class(errors),
intent(inout),
optional,
target :: err
48 class(errors),
pointer :: errmgr
49 type(errors),
target :: deferr
50 character(len = :),
allocatable :: errmsg
56 if (
present(err))
then
61 if (
present(ascend))
then
68 if (
size(ind) /= n)
then
69 allocate(
character(len = 256) :: errmsg)
71 "Expected the tracking array to be of size ", n, &
72 ", but found an array of size ",
size(ind),
"."
73 call errmgr%report_error(
"sort_dbl_array_ind", trim(errmsg), &
80 call qsort_dbl_ind(dir, x, ind)
83100
format(a, i0, a, i0, a)
87 module subroutine sort_cmplx_array(x, ascend)
89 complex(real64),
intent(inout),
dimension(:) :: x
90 logical,
intent(in),
optional :: ascend
96 if (
present(ascend))
then
103 call qsort_cmplx(dir, x)
107 module subroutine sort_cmplx_array_ind(x, ind, ascend, err)
109 complex(real64),
intent(inout),
dimension(:) :: x
110 integer(int32),
intent(inout),
dimension(:) :: ind
111 logical,
intent(in),
optional :: ascend
112 class(errors),
intent(inout),
optional,
target :: err
115 class(errors),
pointer :: errmgr
116 type(errors),
target :: deferr
117 character(len = :),
allocatable :: errmsg
123 if (
present(err))
then
128 if (
present(ascend))
then
135 if (
size(ind) /= n)
then
136 allocate(
character(len = 256) :: errmsg)
138 "Expected the tracking array to be of size ", n, &
139 ", but found an array of size ",
size(ind),
"."
140 call errmgr%report_error(
"sort_cmplx_array_ind", trim(errmsg), &
147 call qsort_cmplx_ind(dir, x, ind)
150100
format(a, i0, a, i0, a)
154 module subroutine sort_eigen_cmplx(vals, vecs, ascend, err)
156 complex(real64),
intent(inout),
dimension(:) :: vals
157 complex(real64),
intent(inout),
dimension(:,:) :: vecs
158 logical,
intent(in),
optional :: ascend
159 class(errors),
intent(inout),
optional,
target :: err
162 class(errors),
pointer :: errmgr
163 type(errors),
target :: deferr
164 character(len = :),
allocatable :: errmsg
165 integer(int32) :: i, n, flag
167 integer(int32),
allocatable,
dimension(:) :: ind
170 if (
present(err))
then
175 if (
present(ascend))
then
183 if (
size(vecs, 1) /= n .or.
size(vecs, 2) /= n)
then
185 allocate(
character(len = 256) :: errmsg)
187 "Expected the eigenvector matrix to be of size ", n, &
188 "-by-", n,
", but found a matrix of size ",
size(vecs, 1), &
189 "-by-",
size(vecs, 2),
"."
190 call errmgr%report_error(
"sort_eigen_cmplx", trim(errmsg), &
195 allocate(ind(n), stat = flag)
197 call errmgr%report_error(
"sort_eigen_cmplx", &
198 "Insufficient memory available.", la_out_of_memory_error)
206 call qsort_cmplx_ind(dir, vals, ind)
213100
format(a, i0, a, i0, a, i0, a, i0, a)
217 module subroutine sort_eigen_dbl(vals, vecs, ascend, err)
219 real(real64),
intent(inout),
dimension(:) :: vals
220 real(real64),
intent(inout),
dimension(:,:) :: vecs
221 logical,
intent(in),
optional :: ascend
222 class(errors),
intent(inout),
optional,
target :: err
225 class(errors),
pointer :: errmgr
226 type(errors),
target :: deferr
227 character(len = :),
allocatable :: errmsg
228 integer(int32) :: i, n, flag
230 integer(int32),
allocatable,
dimension(:) :: ind
233 if (
present(err))
then
238 if (
present(ascend))
then
246 if (
size(vecs, 1) /= n .or.
size(vecs, 2) /= n)
then
248 allocate(
character(len = 256) :: errmsg)
250 "Expected the eigenvector matrix to be of size ", n, &
251 "-by-", n,
", but found a matrix of size ",
size(vecs, 1), &
252 "-by-",
size(vecs, 2),
"."
253 call errmgr%report_error(
"sort_eigen_dbl", trim(errmsg), &
258 allocate(ind(n), stat = flag)
260 call errmgr%report_error(
"sort_eigen_dbl", &
261 "Insufficient memory available.", la_out_of_memory_error)
269 call qsort_dbl_ind(dir, vals, ind)
276100
format(a, i0, a, i0, a, i0, a, i0, a)
280 module subroutine sort_int32_array(x, ascend)
282 integer(int32),
intent(inout),
dimension(:) :: x
283 logical,
intent(in),
optional :: ascend
289 if (
present(ascend))
then
296 call qsort_int32(dir, x)
300 module subroutine sort_int32_array_ind(x, ind, ascend, err)
302 integer(int32),
intent(inout),
dimension(:) :: x
303 integer(int32),
intent(inout),
dimension(:) :: ind
304 logical,
intent(in),
optional :: ascend
305 class(errors),
intent(inout),
optional,
target :: err
308 class(errors),
pointer :: errmgr
309 type(errors),
target :: deferr
310 character(len = :),
allocatable :: errmsg
316 if (
present(err))
then
321 if (
present(ascend))
then
328 if (
size(ind) /= n)
then
329 allocate(
character(len = 256) :: errmsg)
331 "Expected the tracking array to be of size ", n, &
332 ", but found an array of size ",
size(ind),
"."
333 call errmgr%report_error(
"sort_int32_array_ind", trim(errmsg), &
340 call qsort_int32_ind(dir, x, ind)
343100
format(a, i0, a, i0, a)
362 recursive subroutine qsort_dbl_ind(ascend, x, ind)
364 logical,
intent(in) :: ascend
365 real(real64),
intent(inout),
dimension(:) :: x
366 integer(int32),
intent(inout),
dimension(:) :: ind
372 if (
size(x) > 1)
then
373 call dbl_partition_ind(ascend, x, ind, iq)
374 call qsort_dbl_ind(ascend, x(:iq-1), ind(:iq-1))
375 call qsort_dbl_ind(ascend, x(iq:), ind(iq:))
395 subroutine dbl_partition_ind(ascend, x, ind, marker)
397 logical,
intent(in) :: ascend
398 real(real64),
intent(inout),
dimension(:) :: x
399 integer(int32),
intent(inout),
dimension(:) :: ind
400 integer(int32),
intent(out) :: marker
403 integer(int32) :: i, j, itemp
404 real(real64) :: temp, pivot
415 if (x(j) <= pivot)
exit
420 if (x(i) >= pivot)
exit
432 else if (i == j)
then
445 if (x(j) >= pivot)
exit
450 if (x(i) <= pivot)
exit
462 else if (i == j)
then
488 recursive subroutine qsort_cmplx(ascend, x)
490 logical,
intent(in) :: ascend
491 complex(real64),
intent(inout),
dimension(:) :: x
497 if (
size(x) > 1)
then
498 call cmplx_partition(ascend, x, iq)
499 call qsort_cmplx(ascend, x(:iq-1))
500 call qsort_cmplx(ascend, x(iq:))
521 subroutine cmplx_partition(ascend, x, marker)
523 logical,
intent(in) :: ascend
524 complex(real64),
intent(inout),
dimension(:) :: x
525 integer(int32),
intent(out) :: marker
528 integer(int32) :: i, j
529 complex(real64) :: temp
530 real(real64) :: pivot
533 pivot = real(x(1), real64)
541 if (real(x(j), real64) <= pivot)
exit
546 if (real(x(i), real64) >= pivot)
exit
554 else if (i == j)
then
567 if (real(x(j), real64) >= pivot)
exit
572 if (real(x(i), real64) <= pivot)
exit
580 else if (i == j)
then
609 recursive subroutine qsort_cmplx_ind(ascend, x, ind)
611 logical,
intent(in) :: ascend
612 complex(real64),
intent(inout),
dimension(:) :: x
613 integer(int32),
intent(inout),
dimension(:) :: ind
619 if (
size(x) > 1)
then
620 call cmplx_partition_ind(ascend, x, ind, iq)
621 call qsort_cmplx_ind(ascend, x(:iq-1), ind(:iq-1))
622 call qsort_cmplx_ind(ascend, x(iq:), ind(iq:))
646 subroutine cmplx_partition_ind(ascend, x, ind, marker)
648 logical,
intent(in) :: ascend
649 complex(real64),
intent(inout),
dimension(:) :: x
650 integer(int32),
intent(inout),
dimension(:) :: ind
651 integer(int32),
intent(out) :: marker
654 integer(int32) :: i, j, itemp
655 complex(real64) :: temp
656 real(real64) :: pivot
659 pivot = real(x(1), real64)
667 if (real(x(j), real64) <= pivot)
exit
672 if (real(x(i), real64) >= pivot)
exit
684 else if (i == j)
then
697 if (real(x(j), real64) >= pivot)
exit
702 if (real(x(i), real64) <= pivot)
exit
714 else if (i == j)
then
736 recursive subroutine qsort_int32(ascend, x)
738 logical,
intent(in) :: ascend
739 integer(int32),
intent(inout),
dimension(:) :: x
745 if (
size(x) > 1)
then
746 call int32_partition(ascend, x, iq)
747 call qsort_int32(ascend, x(:iq-1))
748 call qsort_int32(ascend, x(iq:))
765 subroutine int32_partition(ascend, x, marker)
767 logical,
intent(in) :: ascend
768 integer(int32),
intent(inout),
dimension(:) :: x
769 integer(int32),
intent(out) :: marker
772 integer(int32) :: i, j, temp, pivot
783 if (x(j) <= pivot)
exit
788 if (x(i) >= pivot)
exit
796 else if (i == j)
then
809 if (x(j) >= pivot)
exit
814 if (x(i) <= pivot)
exit
822 else if (i == j)
then
847 recursive subroutine qsort_int32_ind(ascend, x, ind)
849 logical,
intent(in) :: ascend
850 integer(int32),
intent(inout),
dimension(:) :: x
851 integer(int32),
intent(inout),
dimension(:) :: ind
857 if (
size(x) > 1)
then
858 call int32_partition_ind(ascend, x, ind, iq)
859 call qsort_int32_ind(ascend, x(:iq-1), ind(:iq-1))
860 call qsort_int32_ind(ascend, x(iq:), ind(iq:))
880 subroutine int32_partition_ind(ascend, x, ind, marker)
882 logical,
intent(in) :: ascend
883 integer(int32),
intent(inout),
dimension(:) :: x
884 integer(int32),
intent(inout),
dimension(:) :: ind
885 integer(int32),
intent(out) :: marker
888 integer(int32) :: i, j, itemp, temp, pivot
899 if (x(j) <= pivot)
exit
904 if (x(i) >= pivot)
exit
916 else if (i == j)
then
929 if (x(j) >= pivot)
exit
934 if (x(i) <= pivot)
exit
946 else if (i == j)
then
Provides a set of common linear algebra routines.