#ifndef SPROUT_NUMERIC_DFT_DETAIL_DFT_ELEMENT_GEN_HPP #define SPROUT_NUMERIC_DFT_DETAIL_DFT_ELEMENT_GEN_HPP #include #include #include #include #include #include namespace sprout { namespace detail { template inline SPROUT_CONSTEXPR typename std::iterator_traits::value_type dft_element_gen_impl_ra( RandomAccessIterator first, RandomAccessIterator last, typename std::iterator_traits::value_type::value_type arg, typename std::iterator_traits::difference_type pivot, typename std::iterator_traits::difference_type k = 0 ) { typedef typename std::iterator_traits::value_type value_type; using sprout::cos; using sprout::sin; return pivot == 0 ? *first * value_type(cos(arg * k), sin(arg * k)) : sprout::detail::dft_element_gen_impl_ra( first, sprout::next(first, pivot), arg, pivot / 2, k ) + sprout::detail::dft_element_gen_impl_ra( sprout::next(first, pivot), last, arg, (sprout::distance(first, last) - pivot) / 2, k + pivot ) ; } template inline SPROUT_CONSTEXPR typename std::iterator_traits::value_type dft_element_gen_impl( RandomAccessIterator first, RandomAccessIterator last, typename std::iterator_traits::value_type::value_type arg, std::random_access_iterator_tag* ) { typedef typename std::iterator_traits::value_type value_type; return first == last ? value_type() : sprout::detail::dft_element_gen_impl_ra(first, last, arg, sprout::distance(first, last) / 2) ; } template inline SPROUT_CONSTEXPR typename std::iterator_traits::value_type dft_element_gen_impl_1( InputIterator first, InputIterator last, typename std::iterator_traits::value_type::value_type arg, typename std::iterator_traits::difference_type k = 0, typename std::iterator_traits::value_type value = typename std::iterator_traits::value_type(), typename std::iterator_traits::value_type::value_type theta = typename std::iterator_traits::value_type::value_type() ) { typedef typename std::iterator_traits::value_type value_type; using sprout::cos; using sprout::sin; return first == last ? value : value + sprout::detail::dft_element_gen_impl_1( sprout::next(first), last, arg, k + 1, *first * value_type(cos(theta), sin(theta)), arg * (k + 1) ) ; } template inline SPROUT_CONSTEXPR typename std::iterator_traits::value_type dft_element_gen_impl( InputIterator first, InputIterator last, typename std::iterator_traits::value_type::value_type arg, void* ) { return sprout::detail::dft_element_gen_impl_1(first, last, arg); } template inline SPROUT_CONSTEXPR typename std::iterator_traits::value_type dft_element_gen( InputIterator first, InputIterator last, typename std::iterator_traits::value_type::value_type arg, typename std::iterator_traits::difference_type k = 0, typename std::iterator_traits::value_type value = typename std::iterator_traits::value_type(), typename std::iterator_traits::value_type::value_type theta = typename std::iterator_traits::value_type::value_type() ) { typedef typename std::iterator_traits::iterator_category* category; return sprout::detail::dft_element_gen_impl(first, last, arg, category()); } } // namespace detail } // namespace sprout #endif // #ifndef SPROUT_NUMERIC_DFT_DETAIL_DFT_ELEMENT_GEN_HPP