Fermat
algorithms.h
Go to the documentation of this file.
1 /*
2  * CUGAR : Cuda Graphics Accelerator
3  *
4  * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the NVIDIA CORPORATION nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
33 #pragma once
34 
35 #include <cugar/basic/types.h>
36 
37 namespace cugar {
38 
49 
52 
56 
62 template <typename Iterator, typename Predicate>
63 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Iterator find_pivot(
64  Iterator begin,
65  const uint32 n,
66  const Predicate predicate)
67 {
68  // if the range has a size of zero, let's just return the intial element
69  if (n == 0)
70  return begin;
71 
72  // check whether this segment contains only 0s or only 1s
73  if (predicate( begin[0] ) == predicate( begin[n-1] ))
74  return predicate( begin[0] ) ? begin + n : begin;
75 
76  // perform a binary search over the given range
77  uint32 count = n;
78 
79  while (count > 0)
80  {
81  const uint32 count2 = count / 2;
82 
83  Iterator mid = begin + count2;
84 
85  if (predicate( *mid ) == false)
86  begin = ++mid, count -= count2 + 1;
87  else
88  count = count2;
89  }
90  return begin;
91 }
92 
98 template <typename Iterator, typename Value, typename index_type>
99 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Iterator lower_bound(
100  const Value x,
101  Iterator begin,
102  const index_type n)
103 {
104  // if the range has a size of zero, let's just return the intial element
105  if (n == 0)
106  return begin;
107 
108  // check whether this segment is all left or right of x
109  if (x < begin[0])
110  return begin;
111 
112  if (begin[n-1] < x)
113  return begin + n;
114 
115  // perform a binary search over the given range
116  index_type count = n;
117 
118  while (count > 0)
119  {
120  const index_type count2 = count / 2;
121 
122  Iterator mid = begin + count2;
123 
124  if (*mid < x)
125  begin = ++mid, count -= count2 + 1;
126  else
127  count = count2;
128  }
129  return begin;
130 }
131 
137 template <typename Iterator, typename Value, typename index_type>
138 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Iterator upper_bound(
139  const Value x,
140  Iterator begin,
141  const index_type n)
142 {
143  // if the range has a size of zero, let's just return the intial element
144  //if (n == 0)
145  // return begin;
146 
147  // check whether this segment is all left or right of x
148  //if (x < begin[0])
149  // return begin;
150 
151  //if (begin[n-1] <= x)
152  // return begin + n;
153 
154  index_type count = n;
155 
156  while (count > 0)
157  {
158  const index_type step = count / 2;
159 
160  Iterator it = begin + step;
161 
162  if (!(x < *it))
163  {
164  begin = ++it;
165  count -= step + 1;
166  }
167  else
168  count = step;
169  }
170  return begin;
171 }
172 
178 template <typename Iterator, typename Value, typename index_type>
179 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE index_type lower_bound_index(
180  const Value x,
181  Iterator begin,
182  const index_type n)
183 {
184  return uint32( lower_bound( x, begin, n ) - begin );
185 }
186 
192 template <typename Iterator, typename Value, typename index_type>
193 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE index_type upper_bound_index(
194  const Value x,
195  Iterator begin,
196  const index_type n)
197 {
198  return index_type( upper_bound( x, begin, n ) - begin );
199 }
200 
209 template <
210  typename input_iterator1,
211  typename input_iterator2,
212  typename output_iterator>
213 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
214 void merge(
215  input_iterator1 first1,
216  input_iterator1 end1,
217  input_iterator2 first2,
218  input_iterator2 end2,
219  output_iterator output)
220 {
221  while (first1 != end1 &&
222  first2 != end2)
223  {
224  if (*first2 < *first1)
225  {
226  *output = *first2;
227 
228  ++first2;
229  }
230  else
231  {
232  *output = *first1;
233 
234  ++first1;
235  }
236 
237  ++output;
238  }
239 
240  while (first1 != end1)
241  {
242  *output = *first1;
243 
244  ++first1;
245  ++output;
246  }
247 
248  while (first2 != end2)
249  {
250  *output = *first2;
251 
252  ++first2;
253  ++output;
254  }
255 }
256 
265 template <
266  typename key_iterator1,
267  typename key_iterator2,
268  typename value_iterator1,
269  typename value_iterator2,
270  typename key_iterator,
271  typename value_iterator>
272 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
274  key_iterator1 first1,
275  key_iterator1 end1,
276  key_iterator2 first2,
277  key_iterator2 end2,
278  value_iterator1 values1,
279  value_iterator2 values2,
280  key_iterator output_keys,
281  value_iterator output_values)
282 {
283  while (first1 != end1 &&
284  first2 != end2)
285  {
286  if (*first2 < *first1)
287  {
288  *output_keys = *first2;
289  *output_values = *values2;
290 
291  ++first2;
292  ++values2;
293  }
294  else
295  {
296  *output_keys = *first1;
297  *output_values = *values1;
298 
299  ++first1;
300  ++values1;
301  }
302 
303  ++output_keys;
304  ++output_values;
305  }
306 
307  while (first1 != end1)
308  {
309  *output_keys = *first1;
310  *output_values = *values1;
311 
312  ++first1;
313  ++values1;
314  ++output_keys;
315  ++output_values;
316  }
317 
318  while (first2 != end2)
319  {
320  *output_keys = *first2;
321  *output_values = *values2;
322 
323  ++first2;
324  ++values2;
325  ++output_keys;
326  ++output_values;
327  }
328 }
329 
332 
333 } // namespace cugar
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE index_type upper_bound_index(const Value x, Iterator begin, const index_type n)
Definition: algorithms.h:193
thrust::device_vector< T >::iterator begin(thrust::device_vector< T > &vec)
Definition: thrust_view.h:89
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void merge_by_key(key_iterator1 first1, key_iterator1 end1, key_iterator2 first2, key_iterator2 end2, value_iterator1 values1, value_iterator2 values2, key_iterator output_keys, value_iterator output_values)
Definition: algorithms.h:273
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Iterator upper_bound(const Value x, Iterator begin, const index_type n)
Definition: algorithms.h:138
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE index_type lower_bound_index(const Value x, Iterator begin, const index_type n)
Definition: algorithms.h:179
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Iterator lower_bound(const Value x, Iterator begin, const index_type n)
Definition: algorithms.h:99
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void merge(input_iterator1 first1, input_iterator1 end1, input_iterator2 first2, input_iterator2 end2, output_iterator output)
Definition: algorithms.h:214
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Iterator find_pivot(Iterator begin, const uint32 n, const Predicate predicate)
Definition: algorithms.h:63