KrisLibrary  1.0.0
arrayutils.h
Go to the documentation of this file.
1 #ifndef ARRAY_UTILS_H
2 #define ARRAY_UTILS_H
3 
4 #include <algorithm>
5 #include <functional>
6 
7 #if ((defined (__GNUC__) && (__GNUC__ > 2)) && !defined(__APPLE__))
8 #include <ext/algorithm>
9 #if __cplusplus <= 199711L
10 //CPLUSPLUS 11 or greater
11 namespace std {
12  using __gnu_cxx::copy_n;
13 }
14 #endif
15 
16 #endif
17 #include <assert.h>
18 
19 
28 namespace ArrayUtils {
29 
32 
33 template <typename T>
34 inline void copy(const T& a, T* out, int n)
35 {
36  std::fill(out,out+n,a);
37 }
38 
39 template <typename T>
40 inline void copy(const T* a, T* out, int n)
41 {
42 #if defined(__APPLE__)
43  for(int i=0;i<n;i++)
44  out[i] = a[i];
45 #else
46  std::copy_n(a,n,out);
47 #endif //defined(__APPLE__)
48 }
49 
50 template <typename T,typename ftype>
51 inline void foreach(T* a, ftype f,int n)
52 {
53  std::for_each(a,a+n,f);
54 }
55 
56 template <typename T>
57 inline void reverse (T *a, int n)
58 {
59  std::reverse(a,a+n);
60 }
61 
62 
63 template <typename t1,typename t2,typename ftype>
64 inline void transform(const t1* a, t2* out, ftype f,int n)
65 {
66  std::transform(a,a+n,out,f);
67 }
68 
69 template <typename t1,typename t2,typename t3,typename ftype>
70 inline void binary_transform(const t1* a, const t2* b, t3* out, ftype f,int n)
71 {
72  std::transform(a,a+n,b,out,f);
73 }
74 
75 template <typename T>
76 inline void add(const T* a, const T* b, T* out, int n)
77 {
78  binary_transform(a,b,out,std::plus<T>(),n);
79 }
80 
81 template <typename T>
82 inline void sub(const T* a, const T* b, T* out, int n)
83 {
84  binary_transform(a,b,out,std::minus<T>(),n);
85 }
86 
87 template <typename T>
88 inline void mul(const T* a, const T* b, T* out, int n)
89 {
90  binary_transform(a,b,out,std::multiplies<T>(),n);
91 }
92 
93 template <typename T>
94 inline void div(const T* a, const T* b, T* out, int n)
95 {
96  binary_transform(a,b,out,std::divides<T>(),n);
97 }
98 
100 template <typename T>
101 inline T nth_element (const std::vector<T>& S, size_t n)
102 {
103  assert(n < S.size());
104  size_t i=rand()%S.size();
105  const T& m=S[i];
106  std::vector<T>S1,S2;
107  S1.reserve(n);
108  S2.reserve(n);
109  for(i=0;i<S.size();i++) {
110  if(S[i] < m) S1.push_back(S[i]);
111  else if(m < S[i]) S2.push_back(S[i]);
112  }
113  if(S1.size() > n) return nth_element(S1,n);
114  else if(S.size()-S2.size()>=n) return m;
115  else return nth_element(S2,n-(S.size()-S2.size()));
116 }
117 
119 template <typename T,typename fless>
120 inline T nth_element (const std::vector<T>& S, size_t n, fless less)
121 {
122  assert(n < S.size());
123  size_t i=rand()%S.size();
124  const T& m=S[i];
125  std::vector<T>S1,S2;
126  S1.reserve(n);
127  S2.reserve(n);
128  for(i=0;i<S.size();i++) {
129  if(less(S[i],m)) S1.push_back(S[i]);
130  else if(less(m,S[i])) S2.push_back(S[i]);
131  }
132  if(S1.size() > n) return nth_element(S1,n,less);
133  else if(S.size()-S2.size()>=n) return m;
134  else return nth_element(S2,n-(S.size()-S2.size()),less);
135 }
136 
137 template <typename T>
138 inline bool is_sorted(T* a, int n)
139 {
140  for(int i=1;i<n;i++)
141  if(a[i]<a[i-1]) return false;
142  return true;
143  //return std::is_sorted(a,a+n);
144 }
145 
146 template <typename T,typename fless>
147 inline bool is_sorted(T* a, int n, fless f)
148 {
149  for(int i=1;i<n;i++)
150  if(f(a[i],a[i-1])) return false;
151  return true;
152  //return std::is_sorted(a,a+n,f);
153 }
154 
155 template <typename T>
156 inline void quicksort(T* a, int p, int r)
157 {
158  if(p < r) {
159  T x = a[p];
160  T temp;
161  int i = p;
162  int j = p + 1;
163  while (j <= r) {
164  if (a[j] < x) {
165  i++;
166  temp=a[j];a[j]=a[i];a[i]=temp;
167  }
168  j++;
169  }
170  temp=a[p];a[p]=a[i];a[i]=temp;
171 
172  quicksort(a,p,i-1);
173  quicksort(a,i+1,r);
174  }
175 }
176 
177 template <typename T,typename fless>
178 inline void quicksort(T* a, int p, int r,fless f)
179 {
180  if(p < r) {
181  T x = a[p];
182  T temp;
183  int i = p;
184  int j = p + 1;
185  while (j <= r) {
186  if (f(a[j],x)) {
187  i++;
188  temp=a[j];a[j]=a[i];a[i]=temp;
189  }
190  j++;
191  }
192  temp=a[p];a[p]=a[i];a[i]=temp;
193 
194  quicksort(a,p,i-1,f);
195  quicksort(a,i+1,r,f);
196  }
197 }
198 
199 template <typename T>
200 inline void sort(T* a, int n)
201 {
202  quicksort(a,0,n-1);
203 }
204 
205 template <typename T,typename fless>
206 inline void sort(T* a, int n, fless f)
207 {
208  quicksort(a,0,n-1,f);
209 }
210 
212 template <class T>
213 inline void concat(std::vector<T>& a,const std::vector<T>& b)
214 {
215  size_t aorig=a.size();
216  a.resize(a.size()+b.size());
217  copy(b.begin(),b.end(),a.begin()+aorig);
218 }
219 
222 } //namespace ArrayUtils
223 
224 #endif
T nth_element(const std::vector< T > &S, size_t n, fless less)
returns the nth largest element in the array a
Definition: arrayutils.h:120
Definition: rayprimitives.h:132
void copy(const T &a, T *out, int n)
Definition: arrayutils.h:34
Convenience routines for C arrays and STL vectors.
Definition: arrayutils.h:28
void concat(std::vector< T > &a, const std::vector< T > &b)
Concatenates b onto the end of a.
Definition: arrayutils.h:213