/* * Copyright 2008-2012 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*! \file transform.h * \brief Transforms input ranges using a function object */ #pragma once #include #include namespace thrust { /*! \addtogroup algorithms */ /*! \addtogroup transformations * \ingroup algorithms * \{ */ /*! This version of \p transform applies a unary function to each element * of an input sequence and stores the result in the corresponding * position in an output sequence. Specifically, for each iterator * i in the range [\p first, \p last) the operation * op(*i) is performed and the result is assigned to *o, * where o is the corresponding output iterator in the range * [\p result, \p result + (\p last - \p first) ). The input and * output sequences may coincide, resulting in an in-place transformation. * * The algorithm's execution is parallelized as determined by \p exec. * * \param exec The execution policy to use for parallelization. * \param first The beginning of the input sequence. * \param last The end of the input sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \return The end of the output sequence. * * \tparam DerivedPolicy The name of the derived execution policy. * \tparam InputIterator is a model of Input Iterator * and \c InputIterator's \c value_type is convertible to \c UnaryFunction's \c argument_type. * \tparam OutputIterator is a model of Output Iterator. * \tparam UnaryFunction is a model of Unary Function * and \c UnaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * * \pre \p first may equal \p result, but the range [first, last) shall not overlap the range [result, result + (last - first)) otherwise. * * The following code snippet demonstrates how to use \p transform to negate a range in-place * using the \p thrust::host execution policy for parallelization: * * \code * #include * #include * #include * ... * * int data[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8}; * * thrust::negate op; * * thrust::transform(thrust::host, data, data + 10, data, op); // in-place transformation * * // data is now {5, 0, -2, 3, -2, -4, 0, 1, -2, -8}; * \endcode * * \see http://www.sgi.com/tech/stl/transform.html */ template OutputIterator transform(const thrust::detail::execution_policy_base &exec, InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op); /*! This version of \p transform applies a unary function to each element * of an input sequence and stores the result in the corresponding * position in an output sequence. Specifically, for each iterator * i in the range [\p first, \p last) the operation * op(*i) is performed and the result is assigned to *o, * where o is the corresponding output iterator in the range * [\p result, \p result + (\p last - \p first) ). The input and * output sequences may coincide, resulting in an in-place transformation. * * \param first The beginning of the input sequence. * \param last The end of the input sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \return The end of the output sequence. * * \tparam InputIterator is a model of Input Iterator * and \c InputIterator's \c value_type is convertible to \c UnaryFunction's \c argument_type. * \tparam OutputIterator is a model of Output Iterator. * \tparam UnaryFunction is a model of Unary Function * and \c UnaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * * \pre \p first may equal \p result, but the range [first, last) shall not overlap the range [result, result + (last - first)) otherwise. * * The following code snippet demonstrates how to use \p transform * * \code * #include * #include * * int data[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8}; * * thrust::negate op; * * thrust::transform(data, data + 10, data, op); // in-place transformation * * // data is now {5, 0, -2, 3, -2, -4, 0, 1, -2, -8}; * \endcode * * \see http://www.sgi.com/tech/stl/transform.html */ template OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op); /*! This version of \p transform applies a binary function to each pair * of elements from two input sequences and stores the result in the * corresponding position in an output sequence. Specifically, for * each iterator i in the range [\p first1, \p last1) and * j = first + (i - first1) in the range [\p first2, \p last2) * the operation op(*i,*j) is performed and the result is * assigned to *o, where o is the corresponding * output iterator in the range [\p result, \p result + (\p last - \p first) ). * The input and output sequences may coincide, resulting in an * in-place transformation. * * The algorithm's execution is parallelized as determined by \p exec. * * \param exec The execution policy to use for parallelization. * \param first1 The beginning of the first input sequence. * \param last1 The end of the first input sequence. * \param first2 The beginning of the second input sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \return The end of the output sequence. * * \tparam DerivedPolicy The name of the derived execution policy. * \tparam InputIterator1 is a model of Input Iterator * and \c InputIterator1's \c value_type is convertible to \c BinaryFunction's \c first_argument_type. * \tparam InputIterator2 is a model of Input Iterator * and \c InputIterator2's \c value_type is convertible to \c BinaryFunction's \c second_argument_type. * \tparam OutputIterator is a model of Output Iterator. * \tparam BinaryFunction is a model of Binary Function * and \c BinaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * * \pre \p first1 may equal \p result, but the range [first1, last1) shall not overlap the range [result, result + (last1 - first1)) otherwise. * \pre \p first2 may equal \p result, but the range [first2, first2 + (last1 - first1)) shall not overlap the range [result, result + (last1 - first1)) otherwise. * * The following code snippet demonstrates how to use \p transform to compute the sum of two * ranges using the \p thrust::host execution policy for parallelization: * * \code * #include * #include * #include * ... * * int input1[6] = {-5, 0, 2, 3, 2, 4}; * int input2[6] = { 3, 6, -2, 1, 2, 3}; * int output[6]; * * thrust::plus op; * * thrust::transform(thrust::host, input1, input1 + 6, input2, output, op); * * // output is now {-2, 6, 0, 4, 4, 7}; * \endcode * * \see http://www.sgi.com/tech/stl/transform.html */ template OutputIterator transform(const thrust::detail::execution_policy_base &exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction op); /*! This version of \p transform applies a binary function to each pair * of elements from two input sequences and stores the result in the * corresponding position in an output sequence. Specifically, for * each iterator i in the range [\p first1, \p last1) and * j = first + (i - first1) in the range [\p first2, \p last2) * the operation op(*i,*j) is performed and the result is * assigned to *o, where o is the corresponding * output iterator in the range [\p result, \p result + (\p last - \p first) ). * The input and output sequences may coincide, resulting in an * in-place transformation. * * \param first1 The beginning of the first input sequence. * \param last1 The end of the first input sequence. * \param first2 The beginning of the second input sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \return The end of the output sequence. * * \tparam InputIterator1 is a model of Input Iterator * and \c InputIterator1's \c value_type is convertible to \c BinaryFunction's \c first_argument_type. * \tparam InputIterator2 is a model of Input Iterator * and \c InputIterator2's \c value_type is convertible to \c BinaryFunction's \c second_argument_type. * \tparam OutputIterator is a model of Output Iterator. * \tparam BinaryFunction is a model of Binary Function * and \c BinaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * * \pre \p first1 may equal \p result, but the range [first1, last1) shall not overlap the range [result, result + (last1 - first1)) otherwise. * \pre \p first2 may equal \p result, but the range [first2, first2 + (last1 - first1)) shall not overlap the range [result, result + (last1 - first1)) otherwise. * * The following code snippet demonstrates how to use \p transform * * \code * #include * #include * * int input1[6] = {-5, 0, 2, 3, 2, 4}; * int input2[6] = { 3, 6, -2, 1, 2, 3}; * int output[6]; * * thrust::plus op; * * thrust::transform(input1, input1 + 6, input2, output, op); * * // output is now {-2, 6, 0, 4, 4, 7}; * \endcode * * \see http://www.sgi.com/tech/stl/transform.html */ template OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction op); /*! This version of \p transform_if conditionally applies a unary function * to each element of an input sequence and stores the result in the corresponding * position in an output sequence if the corresponding position in the input sequence * satifies a predicate. Otherwise, the corresponding position in the * output sequence is not modified. * * Specifically, for each iterator i in the range [first, last) the * predicate pred(*i) is evaluated. If this predicate * evaluates to \c true, the result of op(*i) is assigned to *o, * where o is the corresponding output iterator in the range * [result, result + (last - first) ). Otherwise, op(*i) is * not evaluated and no assignment occurs. The input and output sequences may coincide, * resulting in an in-place transformation. * * The algorithm's execution is parallelized as determined by \p exec. * * \param exec The execution policy to use for parallelization. * \param first The beginning of the input sequence. * \param last The end of the input sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \param pred The predicate operation. * \return The end of the output sequence. * * \tparam DerivedPolicy The name of the derived execution policy. * \tparam InputIterator is a model of Input Iterator, * and \c InputIterator's \c value_type is convertible to \c Predicate's \c argument_type, * and \c InputIterator's \c value_type is convertible to \c UnaryFunction's \c argument_type. * \tparam ForwardIterator is a model of Forward Iterator. * \tparam UnaryFunction is a model of Unary Function * and \c UnaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * \tparam Predicate is a model of Predicate. * * \pre \p first may equal \p result, but the range [first, last) shall not overlap the range [result, result + (last - first)) otherwise. * * The following code snippet demonstrates how to use \p transform_if to negate the odd-valued * elements of a range using the \p thrust::host execution policy for parallelization: * * \code * #include * #include * #include * ... * * int data[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8}; * * struct is_odd * { * __host__ __device__ * bool operator()(int x) * { * return x % 2; * } * }; * * thrust::negate op; * thrust::identity identity; * * // negate odd elements * thrust::transform_if(thrust::host, data, data + 10, data, op, is_odd()); // in-place transformation * * // data is now {5, 0, 2, 3, 2, 4, 0, 1, 2, 8}; * \endcode * * \see thrust::transform */ template ForwardIterator transform_if(const thrust::detail::execution_policy_base &exec, InputIterator first, InputIterator last, ForwardIterator result, UnaryFunction op, Predicate pred); /*! This version of \p transform_if conditionally applies a unary function * to each element of an input sequence and stores the result in the corresponding * position in an output sequence if the corresponding position in the input sequence * satifies a predicate. Otherwise, the corresponding position in the * output sequence is not modified. * * Specifically, for each iterator i in the range [first, last) the * predicate pred(*i) is evaluated. If this predicate * evaluates to \c true, the result of op(*i) is assigned to *o, * where o is the corresponding output iterator in the range * [result, result + (last - first) ). Otherwise, op(*i) is * not evaluated and no assignment occurs. The input and output sequences may coincide, * resulting in an in-place transformation. * * \param first The beginning of the input sequence. * \param last The end of the input sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \param pred The predicate operation. * \return The end of the output sequence. * * \tparam InputIterator is a model of Input Iterator, * and \c InputIterator's \c value_type is convertible to \c Predicate's \c argument_type, * and \c InputIterator's \c value_type is convertible to \c UnaryFunction's \c argument_type. * \tparam ForwardIterator is a model of Forward Iterator. * \tparam UnaryFunction is a model of Unary Function * and \c UnaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * \tparam Predicate is a model of Predicate. * * \pre \p first may equal \p result, but the range [first, last) shall not overlap the range [result, result + (last - first)) otherwise. * * The following code snippet demonstrates how to use \p transform_if: * * \code * #include * #include * * int data[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8}; * * struct is_odd * { * __host__ __device__ * bool operator()(int x) * { * return x % 2; * } * }; * * thrust::negate op; * thrust::identity identity; * * // negate odd elements * thrust::transform_if(data, data + 10, data, op, is_odd()); // in-place transformation * * // data is now {5, 0, 2, 3, 2, 4, 0, 1, 2, 8}; * \endcode * * \see thrust::transform */ template ForwardIterator transform_if(InputIterator first, InputIterator last, ForwardIterator result, UnaryFunction op, Predicate pred); /*! This version of \p transform_if conditionally applies a unary function * to each element of an input sequence and stores the result in the corresponding * position in an output sequence if the corresponding position in a stencil sequence * satisfies a predicate. Otherwise, the corresponding position in the * output sequence is not modified. * * Specifically, for each iterator i in the range [first, last) the * predicate pred(*s) is evaluated, where s is the corresponding input * iterator in the range [stencil, stencil + (last - first) ). If this predicate * evaluates to \c true, the result of op(*i) is assigned to *o, * where o is the corresponding output iterator in the range * [result, result + (last - first) ). Otherwise, op(*i) is * not evaluated and no assignment occurs. The input and output sequences may coincide, * resulting in an in-place transformation. * * The algorithm's execution is parallelized as determined by \p exec. * * \param exec The execution policy to use for parallelization. * \param first The beginning of the input sequence. * \param last The end of the input sequence. * \param stencil The beginning of the stencil sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \param pred The predicate operation. * \return The end of the output sequence. * * \tparam DerivedPolicy The name of the derived execution policy. * \tparam InputIterator1 is a model of Input Iterator * and \c InputIterator1's \c value_type is convertible to \c UnaryFunction's \c argument_type. * \tparam InputIterator2 is a model of Input Iterator * and \c InputIterator2's \c value_type is convertible to \c Predicate's \c argument_type. * \tparam ForwardIterator is a model of Forward Iterator. * \tparam UnaryFunction is a model of Unary Function * and \c UnaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * \tparam Predicate is a model of Predicate. * * \pre \p first may equal \p result, but the range [first, last) shall not overlap the range [result, result + (last - first)) otherwise. * \pre \p stencil may equal \p result, but the range [stencil, stencil + (last - first)) shall not overlap the range [result, result + (last - first)) otherwise. * * The following code snippet demonstrates how to use \p transform_if using the \p thrust::host * execution policy for parallelization: * * \code * #include * #include * #include * ... * * int data[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8}; * int stencil[10] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}; * * thrust::negate op; * thrust::identity identity; * * thrust::transform_if(thrust::host, data, data + 10, stencil, data, op, identity); // in-place transformation * * // data is now {5, 0, -2, -3, -2, 4, 0, -1, -2, 8}; * \endcode * * \see thrust::transform */ template ForwardIterator transform_if(const thrust::detail::execution_policy_base &exec, InputIterator1 first, InputIterator1 last, InputIterator2 stencil, ForwardIterator result, UnaryFunction op, Predicate pred); /*! This version of \p transform_if conditionally applies a unary function * to each element of an input sequence and stores the result in the corresponding * position in an output sequence if the corresponding position in a stencil sequence * satisfies a predicate. Otherwise, the corresponding position in the * output sequence is not modified. * * Specifically, for each iterator i in the range [first, last) the * predicate pred(*s) is evaluated, where s is the corresponding input * iterator in the range [stencil, stencil + (last - first) ). If this predicate * evaluates to \c true, the result of op(*i) is assigned to *o, * where o is the corresponding output iterator in the range * [result, result + (last - first) ). Otherwise, op(*i) is * not evaluated and no assignment occurs. The input and output sequences may coincide, * resulting in an in-place transformation. * * \param first The beginning of the input sequence. * \param last The end of the input sequence. * \param stencil The beginning of the stencil sequence. * \param result The beginning of the output sequence. * \param op The tranformation operation. * \param pred The predicate operation. * \return The end of the output sequence. * * \tparam InputIterator1 is a model of Input Iterator * and \c InputIterator1's \c value_type is convertible to \c UnaryFunction's \c argument_type. * \tparam InputIterator2 is a model of Input Iterator * and \c InputIterator2's \c value_type is convertible to \c Predicate's \c argument_type. * \tparam ForwardIterator is a model of Forward Iterator. * \tparam UnaryFunction is a model of Unary Function * and \c UnaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * \tparam Predicate is a model of Predicate. * * \pre \p first may equal \p result, but the range [first, last) shall not overlap the range [result, result + (last - first)) otherwise. * \pre \p stencil may equal \p result, but the range [stencil, stencil + (last - first)) shall not overlap the range [result, result + (last - first)) otherwise. * * The following code snippet demonstrates how to use \p transform_if: * * \code * #include * #include * * int data[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8}; * int stencil[10] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}; * * thrust::negate op; * thrust::identity identity; * * thrust::transform_if(data, data + 10, stencil, data, op, identity); // in-place transformation * * // data is now {5, 0, -2, -3, -2, 4, 0, -1, -2, 8}; * \endcode * * \see thrust::transform */ template ForwardIterator transform_if(InputIterator1 first, InputIterator1 last, InputIterator2 stencil, ForwardIterator result, UnaryFunction op, Predicate pred); /*! This version of \p transform_if conditionally applies a binary function * to each pair of elements from two input sequences and stores the result in the corresponding * position in an output sequence if the corresponding position in a stencil sequence * satifies a predicate. Otherwise, the corresponding position in the * output sequence is not modified. * * Specifically, for each iterator i in the range [first1, last1) and * j = first2 + (i - first1) in the range [first2, first2 + (last1 - first1) ), * the predicate pred(*s) is evaluated, where s is the corresponding input * iterator in the range [stencil, stencil + (last1 - first1) ). If this predicate * evaluates to \c true, the result of binary_op(*i,*j) is assigned to *o, * where o is the corresponding output iterator in the range * [result, result + (last1 - first1) ). Otherwise, binary_op(*i,*j) is * not evaluated and no assignment occurs. The input and output sequences may coincide, * resulting in an in-place transformation. * * The algorithm's execution is parallelized as determined by \p exec. * * \param exec The execution policy to use for parallelization. * \param first1 The beginning of the first input sequence. * \param last1 The end of the first input sequence. * \param first2 The beginning of the second input sequence. * \param stencil The beginning of the stencil sequence. * \param result The beginning of the output sequence. * \param binary_op The transformation operation. * \param pred The predicate operation. * \return The end of the output sequence. * * \tparam DerivedPolicy The name of the derived execution policy. * \tparam InputIterator1 is a model of Input Iterator * and \c InputIterator1's \c value_type is convertible to \c BinaryFunction's \c first_argument_type. * \tparam InputIterator2 is a model of Input Iterator * and \c InputIterator2's \c value_type is convertible to \c BinaryFunction's \c second_argument_type. * \tparam ForwardIterator is a model of Forward Iterator. * \tparam BinaryFunction is a model of Binary Function * and \c BinaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * \tparam Predicate is a model of Predicate. * * \pre \p first1 may equal \p result, but the range [first1, last1) shall not overlap the range [result, result + (last1 - first1)) otherwise. * \pre \p first2 may equal \p result, but the range [first2, first2 + (last1 - first1)) shall not overlap the range [result, result + (last1 - first1)) otherwise. * \pre \p stencil may equal \p result, but the range [stencil, stencil + (last1 - first1)) shall not overlap the range [result, result + (last1 - first1)) otherwise. * * The following code snippet demonstrates how to use \p transform_if using the \p thrust::host * execution policy for parallelization: * * \code * #include * #include * #include * ... * * int input1[6] = {-5, 0, 2, 3, 2, 4}; * int input2[6] = { 3, 6, -2, 1, 2, 3}; * int stencil[8] = { 1, 0, 1, 0, 1, 0}; * int output[6]; * * thrust::plus op; * thrust::identity identity; * * thrust::transform_if(thrust::host, input1, input1 + 6, input2, stencil, output, op, identity); * * // output is now {-2, 0, 0, 3, 4, 4}; * \endcode * * \see thrust::transform */ template ForwardIterator transform_if(const thrust::detail::execution_policy_base &exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator3 stencil, ForwardIterator result, BinaryFunction binary_op, Predicate pred); /*! This version of \p transform_if conditionally applies a binary function * to each pair of elements from two input sequences and stores the result in the corresponding * position in an output sequence if the corresponding position in a stencil sequence * satifies a predicate. Otherwise, the corresponding position in the * output sequence is not modified. * * Specifically, for each iterator i in the range [first1, last1) and * j = first2 + (i - first1) in the range [first2, first2 + (last1 - first1) ), * the predicate pred(*s) is evaluated, where s is the corresponding input * iterator in the range [stencil, stencil + (last1 - first1) ). If this predicate * evaluates to \c true, the result of binary_op(*i,*j) is assigned to *o, * where o is the corresponding output iterator in the range * [result, result + (last1 - first1) ). Otherwise, binary_op(*i,*j) is * not evaluated and no assignment occurs. The input and output sequences may coincide, * resulting in an in-place transformation. * * \param first1 The beginning of the first input sequence. * \param last1 The end of the first input sequence. * \param first2 The beginning of the second input sequence. * \param stencil The beginning of the stencil sequence. * \param result The beginning of the output sequence. * \param binary_op The transformation operation. * \param pred The predicate operation. * \return The end of the output sequence. * * \tparam InputIterator1 is a model of Input Iterator * and \c InputIterator1's \c value_type is convertible to \c BinaryFunction's \c first_argument_type. * \tparam InputIterator2 is a model of Input Iterator * and \c InputIterator2's \c value_type is convertible to \c BinaryFunction's \c second_argument_type. * \tparam ForwardIterator is a model of Forward Iterator. * \tparam BinaryFunction is a model of Binary Function * and \c BinaryFunction's \c result_type is convertible to \c OutputIterator's \c value_type. * \tparam Predicate is a model of Predicate. * * \pre \p first1 may equal \p result, but the range [first1, last1) shall not overlap the range [result, result + (last1 - first1)) otherwise. * \pre \p first2 may equal \p result, but the range [first2, first2 + (last1 - first1)) shall not overlap the range [result, result + (last1 - first1)) otherwise. * \pre \p stencil may equal \p result, but the range [stencil, stencil + (last1 - first1)) shall not overlap the range [result, result + (last1 - first1)) otherwise. * * The following code snippet demonstrates how to use \p transform_if: * * \code * #include * #include * * int input1[6] = {-5, 0, 2, 3, 2, 4}; * int input2[6] = { 3, 6, -2, 1, 2, 3}; * int stencil[8] = { 1, 0, 1, 0, 1, 0}; * int output[6]; * * thrust::plus op; * thrust::identity identity; * * thrust::transform_if(input1, input1 + 6, input2, stencil, output, op, identity); * * // output is now {-2, 0, 0, 3, 4, 4}; * \endcode * * \see thrust::transform */ template ForwardIterator transform_if(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator3 stencil, ForwardIterator result, BinaryFunction binary_op, Predicate pred); /*! \} // end transformations */ } // end namespace thrust #include