38 #ifndef GMM_ALGOBASE_H__
39 #define GMM_ALGOBASE_H__
53 inline int operator()(
const T& x,
const T& y)
const
54 {
return (x < y) ? -1 : ((y < x) ? 1 : 0); }
57 template<>
struct less<int> {
58 int operator()(
int x,
int y)
const {
return x-y; } };
59 template<>
struct less<char> {
60 int operator()(
char x,
char y)
const {
return int(x-y); } };
61 template<>
struct less<short> {
62 int operator()(
short x,
short y)
const {
return int(x-y); } };
63 template<>
struct less<unsigned char> {
64 int operator()(
unsigned char x,
unsigned char y)
const
65 {
return int(x)-int(y); }
71 inline int operator()(
const T& x,
const T& y)
const
72 {
return (y < x) ? -1 : ((x < y) ? 1 : 0); }
75 template<>
struct greater<int> {
76 int operator()(
int x,
int y)
const {
return y-x; } };
77 template<>
struct greater<char> {
78 int operator()(
char x,
char y)
const {
return int(y-x); } };
79 template<>
struct greater<short> {
80 int operator()(
short x,
short y)
const {
return int(y-x); } };
81 template<>
struct greater<unsigned char> {
82 int operator()(
unsigned char x,
unsigned char y)
const
83 {
return int(y)-int(x); }
86 template <
typename T>
inline T my_abs(T a) {
return (a < T(0)) ? T(-a) : a; }
91 inline int operator()(
const T &x,
const T &y)
const
92 {
if (my_abs(x - y) <= eps)
return 0;
if (x < y)
return -1;
return 1; }
93 approx_less(
double e = 1E-13) { eps = e; }
97 struct approx_greater {
99 inline int operator()(
const T &x,
const T &y)
const
100 {
if (my_abs(x - y) <= eps)
return 0;
if (x > y)
return -1;
return 1; }
101 approx_greater(
double e = 1E-13) { eps = e; }
104 template<
class ITER1,
class ITER2,
class COMP>
105 int lexicographical_compare(ITER1 b1,
const ITER1 &e1,
106 ITER2 b2,
const ITER2 &e2,
const COMP &c) {
108 for ( ; b1 != e1 && b2 != e2; ++b1, ++b2)
109 if ((i = c(*b1, *b2)) != 0)
return i;
110 if (b1 != e1)
return 1;
111 if (b2 != e2)
return -1;
115 template<
class CONT,
class COMP = gmm::less<
typename CONT::value_type> >
116 struct lexicographical_less {
118 int operator()(
const CONT &x,
const CONT &y)
const {
119 return gmm::lexicographical_compare(x.begin(), x.end(),
120 y.begin(), y.end(), c);
122 lexicographical_less(
const COMP &d = COMP()) { c = d; }
125 template<
class CONT,
class COMP = gmm::less<
typename CONT::value_type> >
126 struct lexicographical_greater {
128 int operator()(
const CONT &x,
const CONT &y)
const {
129 return -gmm::lexicographical_compare(x.begin(), x.end(),
130 y.begin(), y.end(), c);
132 lexicographical_greater(
const COMP &d = COMP()) { c = d; }
141 template<
class T>
struct sequence_iterator {
143 typedef T value_type;
144 typedef value_type* pointer;
145 typedef value_type& reference;
146 typedef const value_type& const_reference;
147 typedef std::forward_iterator_tag iterator_category;
151 sequence_iterator(T U0 = T(0)) { Un = U0; }
153 sequence_iterator &operator ++()
154 { ++Un;
return *
this; }
155 sequence_iterator operator ++(
int)
156 { sequence_iterator tmp = *
this; (*this)++;
return tmp; }
158 const_reference operator *()
const {
return Un; }
159 reference operator *() {
return Un; }
161 bool operator ==(
const sequence_iterator &i)
const {
return (i.Un==Un);}
162 bool operator !=(
const sequence_iterator &i)
const {
return (i.Un!=Un);}
169 template <
class ITER1,
class SIZE,
class ITER2>
170 ITER2 copy_n(ITER1 first, SIZE count, ITER2 result) {
171 for ( ; count > 0; --count, ++first, ++result) *result = *first;
176 typename std::iterator_traits<ITER>::value_type
177 mean_value(ITER first,
const ITER &last) {
178 GMM_ASSERT2(first != last,
"mean value of empty container");
180 typename std::iterator_traits<ITER>::value_type res = *first++;
181 while (first != last) { res += *first; ++first; ++n; }
187 typename CONT::value_type
188 mean_value(
const CONT &c) {
return mean_value(c.begin(), c.end()); }
191 void minmax_box(
typename std::iterator_traits<ITER>::value_type &pmin,
192 typename std::iterator_traits<ITER>::value_type &pmax,
193 ITER first,
const ITER &last) {
194 typedef typename std::iterator_traits<ITER>::value_type PT;
195 if (first != last) { pmin = pmax = *first; ++first; }
196 while (first != last) {
197 typename PT::const_iterator b = (*first).begin(), e = (*first).end();
198 typename PT::iterator b1 = pmin.begin(), b2 = pmax.begin();
200 { *b1 = std::min(*b1, *b); *b2 = std::max(*b2, *b); ++b; ++b1; ++b2; }
204 template<
typename VEC>
struct sorted_indexes_aux {
207 sorted_indexes_aux(
const VEC& v_) : v(v_) {}
208 template <
typename IDX>
209 bool operator()(
const IDX &ia,
const IDX &ib)
const
210 {
return v[ia] < v[ib]; }
213 template<
typename VEC,
typename IVEC>
214 void sorted_indexes(
const VEC &v, IVEC &iv) {
215 iv.clear(); iv.resize(v.size());
216 for (
size_t i=0; i < v.size(); ++i) iv[i] = i;
217 std::sort(iv.begin(), iv.end(), sorted_indexes_aux<VEC>(v));