summaryrefslogtreecommitdiff
path: root/boost/compute/algorithm/adjacent_difference.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/compute/algorithm/adjacent_difference.hpp')
-rw-r--r--boost/compute/algorithm/adjacent_difference.hpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/boost/compute/algorithm/adjacent_difference.hpp b/boost/compute/algorithm/adjacent_difference.hpp
new file mode 100644
index 0000000000..a8f84e020e
--- /dev/null
+++ b/boost/compute/algorithm/adjacent_difference.hpp
@@ -0,0 +1,98 @@
+//---------------------------------------------------------------------------//
+// Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
+//
+// Distributed under the Boost Software License, Version 1.0
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+// See http://boostorg.github.com/compute for more information.
+//---------------------------------------------------------------------------//
+
+#ifndef BOOST_COMPUTE_ALGORITHM_ADJACENT_DIFFERENCE_HPP
+#define BOOST_COMPUTE_ALGORITHM_ADJACENT_DIFFERENCE_HPP
+
+#include <iterator>
+
+#include <boost/compute/system.hpp>
+#include <boost/compute/command_queue.hpp>
+#include <boost/compute/detail/meta_kernel.hpp>
+#include <boost/compute/detail/iterator_range_size.hpp>
+#include <boost/compute/functional/operator.hpp>
+#include <boost/compute/container/vector.hpp>
+
+namespace boost {
+namespace compute {
+
+/// Stores the difference of each pair of consecutive values in the range
+/// [\p first, \p last) to the range beginning at \p result. If \p op is not
+/// provided, \c minus<T> is used.
+///
+/// \param first first element in the input range
+/// \param last last element in the input range
+/// \param result first element in the output range
+/// \param op binary difference function
+/// \param queue command queue to perform the operation
+///
+/// \return \c OutputIterator to the end of the result range
+///
+/// \see adjacent_find()
+template<class InputIterator, class OutputIterator, class BinaryFunction>
+inline OutputIterator
+adjacent_difference(InputIterator first,
+ InputIterator last,
+ OutputIterator result,
+ BinaryFunction op,
+ command_queue &queue = system::default_queue())
+{
+ if(first == last){
+ return result;
+ }
+
+ size_t count = detail::iterator_range_size(first, last);
+
+ detail::meta_kernel k("adjacent_difference");
+
+ k << "const uint i = get_global_id(0);\n"
+ << "if(i == 0){\n"
+ << " " << result[k.var<uint_>("0")] << " = " << first[k.var<uint_>("0")] << ";\n"
+ << "}\n"
+ << "else {\n"
+ << " " << result[k.var<uint_>("i")] << " = "
+ << op(first[k.var<uint_>("i")], first[k.var<uint_>("i-1")]) << ";\n"
+ << "}\n";
+
+ k.exec_1d(queue, 0, count, 1);
+
+ return result + count;
+}
+
+/// \overload
+template<class InputIterator, class OutputIterator>
+inline OutputIterator
+adjacent_difference(InputIterator first,
+ InputIterator last,
+ OutputIterator result,
+ command_queue &queue = system::default_queue())
+{
+ typedef typename std::iterator_traits<InputIterator>::value_type value_type;
+
+ if (first == result) {
+ vector<value_type> temp(detail::iterator_range_size(first, last),
+ queue.get_context());
+ copy(first, last, temp.begin(), queue);
+
+ return ::boost::compute::adjacent_difference(
+ temp.begin(), temp.end(), result, ::boost::compute::minus<value_type>(), queue
+ );
+ }
+ else {
+ return ::boost::compute::adjacent_difference(
+ first, last, result, ::boost::compute::minus<value_type>(), queue
+ );
+ }
+}
+
+} // end compute namespace
+} // end boost namespace
+
+#endif // BOOST_COMPUTE_ALGORITHM_ADJACENT_DIFFERENCE_HPP