1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#ifndef PYTHONIC_NUMPY_SETDIFF1D_HPP
#define PYTHONIC_NUMPY_SETDIFF1D_HPP
#include "pythonic/include/numpy/setdiff1d.hpp"
#include "pythonic/numpy/asarray.hpp"
#include "pythonic/types/ndarray.hpp"
#include "pythonic/utils/allocate.hpp"
#include "pythonic/utils/functor.hpp"
#include "pythonic/utils/pdqsort.hpp"
#include <algorithm>
#include <set>
PYTHONIC_NS_BEGIN
namespace numpy
{
namespace impl
{
template <typename InputIterator1, typename InputIterator2,
typename OutputIterator>
OutputIterator
set_difference_unique(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result)
{
while (first1 != last1 && first2 != last2) {
auto const t1 = *first1;
auto const t2 = *first2;
if (t1 < t2) {
*result = t1;
while (*++first1 == t1)
;
++result;
} else if (t2 < t1)
while (*++first2 == t2)
;
else {
while (*++first1 == t1)
;
while (*++first2 == t2)
;
}
}
while (first1 != last1) {
auto const t1 = *first1;
*result = t1;
while (*++first1 == t1)
;
++result;
}
return result;
}
} // namespace impl
template <class T, class U>
types::ndarray<typename __combined<typename types::dtype_of<T>::type,
typename types::dtype_of<U>::type>::type,
types::pshape<long>>
setdiff1d(T const &ar1, U const &ar2, bool assume_unique)
{
using dtype = typename __combined<typename types::dtype_of<T>::type,
typename types::dtype_of<U>::type>::type;
auto far1 = numpy::functor::array{}(ar1);
auto far2 = numpy::functor::array{}(ar2);
pdqsort(far1.fbegin(), far1.fend());
pdqsort(far2.fbegin(), far2.fend());
dtype *out = utils::allocate<dtype>(far1.flat_size() * far2.flat_size());
dtype *out_last;
if (assume_unique) {
out_last = std::set_difference(far1.fbegin(), far1.fend(), far2.fbegin(),
far2.fend(), out);
} else {
out_last = impl::set_difference_unique(far1.fbegin(), far1.fend(),
far2.fbegin(), far2.fend(), out);
}
auto size = out_last - out;
out = utils::reallocate(out, size);
return {out, types::pshape<long>(size), types::ownership::owned};
}
} // namespace numpy
PYTHONIC_NS_END
#endif
|