Skip to content

Commit f141e4f

Browse files
committed
Implement minmax_element
1 parent 3cde0ba commit f141e4f

File tree

5 files changed

+375
-9
lines changed

5 files changed

+375
-9
lines changed

doc/modules/algorithm.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,20 @@ Example::
101101
minmax_element
102102
--------------
103103

104-
TODO
104+
Finds the smallest and largest element in an array.
105+
Note that the *first* occurrence of the minimum value is selected, and the
106+
*last* occurrence of the maximum value is selected. Thus, for a sorted array
107+
``arr`` which may have duplicate elements, the expression
108+
``arr(min_idx:max_idx)`` will always return the entire array.
109+
110+
Example::
111+
112+
use flc_algorithm, only : minmax_element, INDEX_INT
113+
implicit none
114+
integer, dimension(6) :: iarr = [ -5, 1000, -1000, 999, -1000, 1000]
115+
integer(INDEX_INT) :: min_idx, max_idx
116+
117+
call minmax_element(iarr, min_idx, max_idx) ! min_idx == 3, max_idx == 6
105118

106119
Set operations
107120
==============

src/flc_algorithm.i

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,31 @@ static index_int binary_search_impl(const T *data, size_t size, T value, Compare
108108
// Index of the found item *IN FORTAN INDEXING*
109109
return (iter - data) + 1;
110110
}
111+
112+
template<class T, class Compare>
113+
static void minmax_element_impl(const T *data, size_t size, index_int *min_index, index_int *max_index, Compare cmp) {
114+
if (size == 0) {
115+
*min_index = 0;
116+
*max_index = 0;
117+
return;
118+
}
119+
const T *end = data + size;
120+
auto mm_pair = std::minmax_element(data, end, cmp);
121+
// Index of the min/max items *IN FORTAN INDEXING*
122+
*min_index = mm_pair.first - data + 1;
123+
*max_index = mm_pair.second - data + 1;
124+
}
111125
%}
112126

113127
%flc_cmp_algorithm(index_int, binary_search, %arg(const T *DATA, size_t DATASIZE,
114128
T value),
115129
%arg(DATA, DATASIZE, value))
116130

131+
%flc_cmp_algorithm(void, minmax_element, %arg(const T *DATA, size_t DATASIZE,
132+
index_int *min_index, index_int *max_index),
133+
%arg(DATA, DATASIZE, min_index, max_index))
134+
135+
117136
/******************************
118137
* Reordering
119138
******************************/

src/generated/flc_algorithm.f90

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ module flc_algorithm
3535
swigf_binary_search__SWIG_4, swigf_binary_search__SWIG_5, swigf_binary_search__SWIG_6
3636
end interface
3737
public :: binary_search
38+
interface minmax_element
39+
module procedure swigf_minmax_element__SWIG_1, swigf_minmax_element__SWIG_2, swigf_minmax_element__SWIG_3, &
40+
swigf_minmax_element__SWIG_4, swigf_minmax_element__SWIG_5, swigf_minmax_element__SWIG_6
41+
end interface
42+
public :: minmax_element
3843
interface shuffle
3944
module procedure swigf_shuffle__SWIG_1, swigf_shuffle__SWIG_2, swigf_shuffle__SWIG_3
4045
end interface
@@ -273,6 +278,63 @@ function swigc_binary_search__SWIG_6(farg1, farg3, farg4) &
273278
integer(C_INT) :: fresult
274279
end function
275280

281+
subroutine swigc_minmax_element__SWIG_1(farg1, farg3, farg4) &
282+
bind(C, name="_wrap_minmax_element__SWIG_1")
283+
use, intrinsic :: ISO_C_BINDING
284+
import :: swigarraywrapper
285+
type(SwigArrayWrapper) :: farg1
286+
type(C_PTR), value :: farg3
287+
type(C_PTR), value :: farg4
288+
end subroutine
289+
290+
subroutine swigc_minmax_element__SWIG_2(farg1, farg3, farg4) &
291+
bind(C, name="_wrap_minmax_element__SWIG_2")
292+
use, intrinsic :: ISO_C_BINDING
293+
import :: swigarraywrapper
294+
type(SwigArrayWrapper) :: farg1
295+
type(C_PTR), value :: farg3
296+
type(C_PTR), value :: farg4
297+
end subroutine
298+
299+
subroutine swigc_minmax_element__SWIG_3(farg1, farg3, farg4) &
300+
bind(C, name="_wrap_minmax_element__SWIG_3")
301+
use, intrinsic :: ISO_C_BINDING
302+
import :: swigarraywrapper
303+
type(SwigArrayWrapper) :: farg1
304+
type(C_PTR), value :: farg3
305+
type(C_PTR), value :: farg4
306+
end subroutine
307+
308+
subroutine swigc_minmax_element__SWIG_4(farg1, farg3, farg4, farg5) &
309+
bind(C, name="_wrap_minmax_element__SWIG_4")
310+
use, intrinsic :: ISO_C_BINDING
311+
import :: swigarraywrapper
312+
type(SwigArrayWrapper) :: farg1
313+
type(C_PTR), value :: farg3
314+
type(C_PTR), value :: farg4
315+
type(C_FUNPTR), value :: farg5
316+
end subroutine
317+
318+
subroutine swigc_minmax_element__SWIG_5(farg1, farg3, farg4, farg5) &
319+
bind(C, name="_wrap_minmax_element__SWIG_5")
320+
use, intrinsic :: ISO_C_BINDING
321+
import :: swigarraywrapper
322+
type(SwigArrayWrapper) :: farg1
323+
type(C_PTR), value :: farg3
324+
type(C_PTR), value :: farg4
325+
type(C_FUNPTR), value :: farg5
326+
end subroutine
327+
328+
subroutine swigc_minmax_element__SWIG_6(farg1, farg3, farg4, farg5) &
329+
bind(C, name="_wrap_minmax_element__SWIG_6")
330+
use, intrinsic :: ISO_C_BINDING
331+
import :: swigarraywrapper
332+
type(SwigArrayWrapper) :: farg1
333+
type(C_PTR), value :: farg3
334+
type(C_PTR), value :: farg4
335+
type(C_FUNPTR), value :: farg5
336+
end subroutine
337+
276338
subroutine swigc_shuffle__SWIG_1(farg1, farg2) &
277339
bind(C, name="_wrap_shuffle__SWIG_1")
278340
use, intrinsic :: ISO_C_BINDING
@@ -894,6 +956,153 @@ function swigf_binary_search__SWIG_6(data, value, cmp) &
894956
swig_result = fresult
895957
end function
896958

959+
subroutine swigf_minmax_element__SWIG_1(data, min_index, max_index)
960+
use, intrinsic :: ISO_C_BINDING
961+
integer(C_INT32_T), dimension(:), intent(in), target :: data
962+
integer(C_INT32_T), pointer :: farg1_view
963+
integer(INDEX_INT), target, intent(inout) :: min_index
964+
integer(INDEX_INT), target, intent(inout) :: max_index
965+
type(SwigArrayWrapper) :: farg1
966+
type(C_PTR) :: farg3
967+
type(C_PTR) :: farg4
968+
969+
if (size(data) > 0) then
970+
farg1_view => data(1)
971+
farg1%data = c_loc(farg1_view)
972+
farg1%size = size(data)
973+
else
974+
farg1%data = c_null_ptr
975+
farg1%size = 0
976+
end if
977+
farg3 = c_loc(min_index)
978+
farg4 = c_loc(max_index)
979+
call swigc_minmax_element__SWIG_1(farg1, farg3, farg4)
980+
end subroutine
981+
982+
subroutine swigf_minmax_element__SWIG_2(data, min_index, max_index)
983+
use, intrinsic :: ISO_C_BINDING
984+
integer(C_INT64_T), dimension(:), intent(in), target :: data
985+
integer(C_INT64_T), pointer :: farg1_view
986+
integer(INDEX_INT), target, intent(inout) :: min_index
987+
integer(INDEX_INT), target, intent(inout) :: max_index
988+
type(SwigArrayWrapper) :: farg1
989+
type(C_PTR) :: farg3
990+
type(C_PTR) :: farg4
991+
992+
if (size(data) > 0) then
993+
farg1_view => data(1)
994+
farg1%data = c_loc(farg1_view)
995+
farg1%size = size(data)
996+
else
997+
farg1%data = c_null_ptr
998+
farg1%size = 0
999+
end if
1000+
farg3 = c_loc(min_index)
1001+
farg4 = c_loc(max_index)
1002+
call swigc_minmax_element__SWIG_2(farg1, farg3, farg4)
1003+
end subroutine
1004+
1005+
subroutine swigf_minmax_element__SWIG_3(data, min_index, max_index)
1006+
use, intrinsic :: ISO_C_BINDING
1007+
real(C_DOUBLE), dimension(:), intent(in), target :: data
1008+
real(C_DOUBLE), pointer :: farg1_view
1009+
integer(INDEX_INT), target, intent(inout) :: min_index
1010+
integer(INDEX_INT), target, intent(inout) :: max_index
1011+
type(SwigArrayWrapper) :: farg1
1012+
type(C_PTR) :: farg3
1013+
type(C_PTR) :: farg4
1014+
1015+
if (size(data) > 0) then
1016+
farg1_view => data(1)
1017+
farg1%data = c_loc(farg1_view)
1018+
farg1%size = size(data)
1019+
else
1020+
farg1%data = c_null_ptr
1021+
farg1%size = 0
1022+
end if
1023+
farg3 = c_loc(min_index)
1024+
farg4 = c_loc(max_index)
1025+
call swigc_minmax_element__SWIG_3(farg1, farg3, farg4)
1026+
end subroutine
1027+
1028+
subroutine swigf_minmax_element__SWIG_4(data, min_index, max_index, cmp)
1029+
use, intrinsic :: ISO_C_BINDING
1030+
integer(C_INT32_T), dimension(:), intent(in), target :: data
1031+
integer(C_INT32_T), pointer :: farg1_view
1032+
integer(INDEX_INT), target, intent(inout) :: min_index
1033+
integer(INDEX_INT), target, intent(inout) :: max_index
1034+
type(C_FUNPTR), intent(in), value :: cmp
1035+
type(SwigArrayWrapper) :: farg1
1036+
type(C_PTR) :: farg3
1037+
type(C_PTR) :: farg4
1038+
type(C_FUNPTR) :: farg5
1039+
1040+
if (size(data) > 0) then
1041+
farg1_view => data(1)
1042+
farg1%data = c_loc(farg1_view)
1043+
farg1%size = size(data)
1044+
else
1045+
farg1%data = c_null_ptr
1046+
farg1%size = 0
1047+
end if
1048+
farg3 = c_loc(min_index)
1049+
farg4 = c_loc(max_index)
1050+
farg5 = cmp
1051+
call swigc_minmax_element__SWIG_4(farg1, farg3, farg4, farg5)
1052+
end subroutine
1053+
1054+
subroutine swigf_minmax_element__SWIG_5(data, min_index, max_index, cmp)
1055+
use, intrinsic :: ISO_C_BINDING
1056+
integer(C_INT64_T), dimension(:), intent(in), target :: data
1057+
integer(C_INT64_T), pointer :: farg1_view
1058+
integer(INDEX_INT), target, intent(inout) :: min_index
1059+
integer(INDEX_INT), target, intent(inout) :: max_index
1060+
type(C_FUNPTR), intent(in), value :: cmp
1061+
type(SwigArrayWrapper) :: farg1
1062+
type(C_PTR) :: farg3
1063+
type(C_PTR) :: farg4
1064+
type(C_FUNPTR) :: farg5
1065+
1066+
if (size(data) > 0) then
1067+
farg1_view => data(1)
1068+
farg1%data = c_loc(farg1_view)
1069+
farg1%size = size(data)
1070+
else
1071+
farg1%data = c_null_ptr
1072+
farg1%size = 0
1073+
end if
1074+
farg3 = c_loc(min_index)
1075+
farg4 = c_loc(max_index)
1076+
farg5 = cmp
1077+
call swigc_minmax_element__SWIG_5(farg1, farg3, farg4, farg5)
1078+
end subroutine
1079+
1080+
subroutine swigf_minmax_element__SWIG_6(data, min_index, max_index, cmp)
1081+
use, intrinsic :: ISO_C_BINDING
1082+
real(C_DOUBLE), dimension(:), intent(in), target :: data
1083+
real(C_DOUBLE), pointer :: farg1_view
1084+
integer(INDEX_INT), target, intent(inout) :: min_index
1085+
integer(INDEX_INT), target, intent(inout) :: max_index
1086+
type(C_FUNPTR), intent(in), value :: cmp
1087+
type(SwigArrayWrapper) :: farg1
1088+
type(C_PTR) :: farg3
1089+
type(C_PTR) :: farg4
1090+
type(C_FUNPTR) :: farg5
1091+
1092+
if (size(data) > 0) then
1093+
farg1_view => data(1)
1094+
farg1%data = c_loc(farg1_view)
1095+
farg1%size = size(data)
1096+
else
1097+
farg1%data = c_null_ptr
1098+
farg1%size = 0
1099+
end if
1100+
farg3 = c_loc(min_index)
1101+
farg4 = c_loc(max_index)
1102+
farg5 = cmp
1103+
call swigc_minmax_element__SWIG_6(farg1, farg3, farg4, farg5)
1104+
end subroutine
1105+
8971106
subroutine swigf_shuffle__SWIG_1(g, data)
8981107
use, intrinsic :: ISO_C_BINDING
8991108
class(Engine), intent(in) :: g

0 commit comments

Comments
 (0)