fix testspr::print_type

This commit is contained in:
bolero-MURAKAMI 2017-07-26 15:22:14 +09:00
parent 59c5e7874c
commit 481b277216
10 changed files with 616 additions and 591 deletions

View file

@ -1,81 +1,81 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP #ifndef SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP
#define SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP #define SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/array.hpp> #include <sprout/array.hpp>
#include <sprout/bit/bit_length.hpp> #include <sprout/bit/bit_length.hpp>
#include <sprout/index_tuple/make_index_tuple.hpp> #include <sprout/index_tuple/make_index_tuple.hpp>
#include <sprout/complex.hpp> #include <sprout/complex.hpp>
#include <sprout/math/cos.hpp> #include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp> #include <sprout/math/sin.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
namespace sprout { namespace sprout {
namespace detail namespace detail
{ {
template<typename value_type, sprout::index_t... Indexes> template<typename value_type, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, sizeof...(Indexes)*2> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, sizeof...(Indexes)*2>
make_fft_coefficients_impl( make_fft_coefficients_impl(
sprout::array<sprout::complex<value_type>, sizeof...(Indexes)> const& arr, sprout::array<sprout::complex<value_type>, sizeof...(Indexes)> const& arr,
sprout::complex<value_type> mul, sprout::index_tuple<Indexes...> sprout::complex<value_type> mul, sprout::index_tuple<Indexes...>
) )
{ {
return sprout::array<sprout::complex<value_type>, sizeof...(Indexes)*2>{ { return sprout::array<sprout::complex<value_type>, sizeof...(Indexes)*2>{ {
arr[Indexes]..., (arr[Indexes] * mul)... arr[Indexes]..., (arr[Indexes] * mul)...
} }; } };
} }
template<typename value_type, std::size_t N, std::size_t Size> template<typename value_type, std::size_t N, std::size_t Size>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
N == 0, N == 0,
typename sprout::array<sprout::complex<value_type>, 1> typename sprout::array<sprout::complex<value_type>, 1>
>::type >::type
make_fft_coefficients_loop( bool ) { make_fft_coefficients_loop( bool ) {
return typename sprout::array<sprout::complex<value_type>, 1>{ { return typename sprout::array<sprout::complex<value_type>, 1>{ {
{ static_cast<value_type>( 1 ) } { static_cast<value_type>( 1 ) }
} }; } };
} }
template<typename value_type, std::size_t N, std::size_t Size> template<typename value_type, std::size_t N, std::size_t Size>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
N != 0, N != 0,
typename sprout::array<sprout::complex<value_type>, 1 << N> typename sprout::array<sprout::complex<value_type>, 1 << N>
>::type >::type
make_fft_coefficients_loop(bool inverse) make_fft_coefficients_loop(bool inverse)
{ {
return make_fft_coefficients_impl( return make_fft_coefficients_impl(
make_fft_coefficients_loop<value_type, N - 1, Size>(inverse), make_fft_coefficients_loop<value_type, N - 1, Size>(inverse),
{ {
sprout::cos((inverse?-1:1)*sprout::math::two_pi<value_type>() / (1 << Size >> (N - 1))), sprout::cos((inverse?-1:1)*sprout::math::two_pi<value_type>() / (1 << Size >> (N - 1))),
sprout::sin((inverse?-1:1)*sprout::math::two_pi<value_type>() / (1 << Size >> (N - 1))) sprout::sin((inverse?-1:1)*sprout::math::two_pi<value_type>() / (1 << Size >> (N - 1)))
}, },
sprout::make_index_tuple<1 << (N - 1)>() sprout::make_index_tuple<1 << (N - 1)>()
); );
} }
template<typename value_type, std::size_t Size> template<typename value_type, std::size_t Size>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, 1 << Size> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, 1 << Size>
make_fft_coefficients(bool inverse) { make_fft_coefficients(bool inverse) {
return make_fft_coefficients_loop<value_type, Size, Size>(inverse); return make_fft_coefficients_loop<value_type, Size, Size>(inverse);
} }
} // namespace detail } // namespace detail
template<typename value_type, std::size_t Size> template<typename value_type, std::size_t Size>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
make_fft_coefficients() { make_fft_coefficients() {
return sprout::detail::make_fft_coefficients<value_type, sprout::bit_length(Size)-1>(false); return sprout::detail::make_fft_coefficients<value_type, sprout::bit_length(Size)-1>(false);
} }
template<typename value_type, std::size_t Size> template<typename value_type, std::size_t Size>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
make_ifft_coefficients() { make_ifft_coefficients() {
return sprout::detail::make_fft_coefficients<value_type, sprout::bit_length(Size)-1>(true); return sprout::detail::make_fft_coefficients<value_type, sprout::bit_length(Size)-1>(true);
} }
} // namespce sprout } // namespce sprout
#endif // SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP #endif // SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP

View file

@ -1,137 +1,137 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_NUMERIC_FFT_CXX14_FFT_HPP #ifndef SPROUT_NUMERIC_FFT_CXX14_FFT_HPP
#define SPROUT_NUMERIC_FFT_CXX14_FFT_HPP #define SPROUT_NUMERIC_FFT_CXX14_FFT_HPP
#include <iterator> #include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/complex.hpp> #include <sprout/complex.hpp>
#include <sprout/math/cos.hpp> #include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp> #include <sprout/math/sin.hpp>
#include <sprout/math/constants.hpp> #include <sprout/math/constants.hpp>
#include <sprout/utility/swap.hpp> #include <sprout/utility/swap.hpp>
namespace sprout { namespace sprout {
// //
// fft // fft
// //
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void inline SPROUT_CXX14_CONSTEXPR void
fft(RandomAccessIterator first, RandomAccessIterator last) { fft(RandomAccessIterator first, RandomAccessIterator last) {
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type; typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type;
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type; typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
typedef typename value_type::value_type elem_type; typedef typename value_type::value_type elem_type;
using sprout::real; using sprout::real;
using sprout::imag; using sprout::imag;
difference_type const size = last - first; difference_type const size = last - first;
// scrambler // scrambler
for (difference_type i = 0, j = 1; j < size - 1; ++j) { for (difference_type i = 0, j = 1; j < size - 1; ++j) {
for (difference_type k = size >> 1; k > (i ^= k); k >>= 1) for (difference_type k = size >> 1; k > (i ^= k); k >>= 1)
; ;
if (j < i) { if (j < i) {
sprout::swap(first[i], first[j]); sprout::swap(first[i], first[j]);
} }
} }
// L shaped butterflies // L shaped butterflies
elem_type const theta = -(sprout::math::half_pi<elem_type>() / size); elem_type const theta = -(sprout::math::half_pi<elem_type>() / size);
for (difference_type m = 4; m <= size; m <<= 1) { for (difference_type m = 4; m <= size; m <<= 1) {
difference_type mq = m >> 2; difference_type mq = m >> 2;
// W == 1 // W == 1
for (difference_type k = mq; k >= 1; k >>= 2) { for (difference_type k = mq; k >= 1; k >>= 2) {
for (difference_type j = mq - k; j < mq - (k >> 1); ++j) { for (difference_type j = mq - k; j < mq - (k >> 1); ++j) {
difference_type j1 = j + mq; difference_type j1 = j + mq;
difference_type j2 = j1 + mq; difference_type j2 = j1 + mq;
difference_type j3 = j2 + mq; difference_type j3 = j2 + mq;
value_type x1 = first[j] - first[j1]; value_type x1 = first[j] - first[j1];
first[j] += first[j1]; first[j] += first[j1];
value_type x3 = first[j3] - first[j2]; value_type x3 = first[j3] - first[j2];
first[j2] += first[j3]; first[j2] += first[j3];
first[j1] = value_type( first[j1] = value_type(
real(x1) - imag(x3), real(x1) - imag(x3),
imag(x1) + real(x3) imag(x1) + real(x3)
); );
first[j3] = value_type( first[j3] = value_type(
real(x1) + imag(x3), real(x1) + imag(x3),
imag(x1) - real(x3) imag(x1) - real(x3)
); );
} }
} }
if (m == size) { if (m == size) {
continue; continue;
} }
difference_type irev = size >> 1; difference_type irev = size >> 1;
elem_type w1r = sprout::cos(theta * irev); elem_type w1r = sprout::cos(theta * irev);
for (difference_type k = mq; k >= 1; k >>= 2) { for (difference_type k = mq; k >= 1; k >>= 2) {
for (difference_type j = m + mq - k; j < m + mq - (k >> 1); ++j) { for (difference_type j = m + mq - k; j < m + mq - (k >> 1); ++j) {
difference_type j1 = j + mq; difference_type j1 = j + mq;
difference_type j2 = j1 + mq; difference_type j2 = j1 + mq;
difference_type j3 = j2 + mq; difference_type j3 = j2 + mq;
value_type x1 = first[j] - first[j1]; value_type x1 = first[j] - first[j1];
first[j] += first[j1]; first[j] += first[j1];
value_type x3 = first[j3] - first[j2]; value_type x3 = first[j3] - first[j2];
first[j2] += first[j3]; first[j2] += first[j3];
elem_type x0r = real(x1) - imag(x3); elem_type x0r = real(x1) - imag(x3);
elem_type x0i = imag(x1) + real(x3); elem_type x0i = imag(x1) + real(x3);
first[j1] = value_type( first[j1] = value_type(
w1r * (x0r + x0i), w1r * (x0r + x0i),
w1r * (x0i - x0r) w1r * (x0i - x0r)
); );
x0r = real(x1) + imag(x3); x0r = real(x1) + imag(x3);
x0i = imag(x1) - real(x3); x0i = imag(x1) - real(x3);
first[j3] = value_type( first[j3] = value_type(
w1r * (-x0r + x0i), w1r * (-x0r + x0i),
w1r * (-x0i - x0r) w1r * (-x0i - x0r)
); );
} }
} }
for (difference_type i = 2 * m; i < size; i += m) { for (difference_type i = 2 * m; i < size; i += m) {
for (difference_type k = size >> 1; k > (irev ^= k); k >>= 1) for (difference_type k = size >> 1; k > (irev ^= k); k >>= 1)
; ;
elem_type w1r = sprout::cos(theta * irev); elem_type w1r = sprout::cos(theta * irev);
elem_type w1i = sprout::sin(theta * irev); elem_type w1i = sprout::sin(theta * irev);
elem_type w3r = sprout::cos(theta * 3 * irev); elem_type w3r = sprout::cos(theta * 3 * irev);
elem_type w3i = sprout::sin(theta * 3 * irev); elem_type w3i = sprout::sin(theta * 3 * irev);
for (difference_type k = mq; k >= 1; k >>= 2) { for (difference_type k = mq; k >= 1; k >>= 2) {
for (difference_type j = i + mq - k; j < i + mq - (k >> 1); ++j) { for (difference_type j = i + mq - k; j < i + mq - (k >> 1); ++j) {
difference_type j1 = j + mq; difference_type j1 = j + mq;
difference_type j2 = j1 + mq; difference_type j2 = j1 + mq;
difference_type j3 = j2 + mq; difference_type j3 = j2 + mq;
value_type x1 = first[j] - first[j1]; value_type x1 = first[j] - first[j1];
first[j] += first[j1]; first[j] += first[j1];
value_type x3 = first[j3] - first[j2]; value_type x3 = first[j3] - first[j2];
first[j2] += first[j3]; first[j2] += first[j3];
elem_type x0r = real(x1) - imag(x3); elem_type x0r = real(x1) - imag(x3);
elem_type x0i = imag(x1) + real(x3); elem_type x0i = imag(x1) + real(x3);
first[j1] = value_type( first[j1] = value_type(
w1r * x0r - w1i * x0i, w1r * x0r - w1i * x0i,
w1r * x0i + w1i * x0r w1r * x0i + w1i * x0r
); );
x0r = real(x1) + imag(x3); x0r = real(x1) + imag(x3);
x0i = imag(x1) - real(x3); x0i = imag(x1) - real(x3);
first[j3] = value_type( first[j3] = value_type(
w3r * x0r - w3i * x0i, w3r * x0r - w3i * x0i,
w3r * x0i + w3i * x0r w3r * x0i + w3i * x0r
); );
} }
} }
} }
} }
// radix 2 butterflies // radix 2 butterflies
difference_type mq = size >> 1; difference_type mq = size >> 1;
for (difference_type k = mq; k >= 1; k >>= 2) { for (difference_type k = mq; k >= 1; k >>= 2) {
for (difference_type j = mq - k; j < mq - (k >> 1); ++j) { for (difference_type j = mq - k; j < mq - (k >> 1); ++j) {
difference_type j1 = mq + j; difference_type j1 = mq + j;
value_type x0 = first[j] - first[j1]; value_type x0 = first[j] - first[j1];
first[j] += first[j1]; first[j] += first[j1];
first[j1] = x0; first[j1] = x0;
} }
} }
} }
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FFT_CXX14_FFT_HPP #endif // #ifndef SPROUT_NUMERIC_FFT_CXX14_FFT_HPP

View file

@ -1,58 +1,58 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_NUMERIC_FFT_CXX14_IFFT_HPP #ifndef SPROUT_NUMERIC_FFT_CXX14_IFFT_HPP
#define SPROUT_NUMERIC_FFT_CXX14_IFFT_HPP #define SPROUT_NUMERIC_FFT_CXX14_IFFT_HPP
#include <iterator> #include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/complex.hpp> #include <sprout/complex.hpp>
#include <sprout/algorithm/cxx14/transform.hpp> #include <sprout/algorithm/cxx14/transform.hpp>
#include <sprout/numeric/fft/cxx14/fft.hpp> #include <sprout/numeric/fft/cxx14/fft.hpp>
namespace sprout { namespace sprout {
namespace detail { namespace detail {
struct conj_value { struct conj_value {
public: public:
template<typename Complex> template<typename Complex>
SPROUT_CONSTEXPR Complex operator()(Complex const& x) const { SPROUT_CONSTEXPR Complex operator()(Complex const& x) const {
return conj(x); return conj(x);
} }
}; };
template<typename Size> template<typename Size>
struct conj_div_value { struct conj_div_value {
private: private:
Size n_; Size n_;
public: public:
explicit SPROUT_CONSTEXPR conj_div_value(Size n) explicit SPROUT_CONSTEXPR conj_div_value(Size n)
: n_(n) : n_(n)
{} {}
template<typename Complex> template<typename Complex>
SPROUT_CONSTEXPR Complex operator()(Complex const& x) const { SPROUT_CONSTEXPR Complex operator()(Complex const& x) const {
return conj(x) / typename Complex::value_type(n_); return conj(x) / typename Complex::value_type(n_);
} }
}; };
template<typename Size> template<typename Size>
SPROUT_CONSTEXPR sprout::detail::conj_div_value<Size> SPROUT_CONSTEXPR sprout::detail::conj_div_value<Size>
conj_div(Size n) { conj_div(Size n) {
return sprout::detail::conj_div_value<Size>(n); return sprout::detail::conj_div_value<Size>(n);
} }
} // namespace detail } // namespace detail
// //
// ifft // ifft
// //
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void inline SPROUT_CXX14_CONSTEXPR void
ifft(RandomAccessIterator first, RandomAccessIterator last) { ifft(RandomAccessIterator first, RandomAccessIterator last) {
sprout::transform(first, last, first, sprout::detail::conj_value()); sprout::transform(first, last, first, sprout::detail::conj_value());
sprout::fft(first, last); sprout::fft(first, last);
sprout::transform(first, last, first, sprout::detail::conj_div(last - first)); sprout::transform(first, last, first, sprout::detail::conj_div(last - first));
} }
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FFT_CXX14_IFFT_HPP #endif // #ifndef SPROUT_NUMERIC_FFT_CXX14_IFFT_HPP

View file

@ -1,55 +1,55 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_NUMERIC_FFT_FIT_FFT_HPP #ifndef SPROUT_NUMERIC_FFT_FIT_FFT_HPP
#define SPROUT_NUMERIC_FFT_FIT_FFT_HPP #define SPROUT_NUMERIC_FFT_FIT_FFT_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/distance.hpp> #include <sprout/iterator/distance.hpp>
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/numeric/fft/fixed/fft.hpp> #include <sprout/numeric/fft/fixed/fft.hpp>
#include <sprout/algorithm/fit/results.hpp> #include <sprout/algorithm/fit/results.hpp>
#include <sprout/sub_array/sub_array.hpp> #include <sprout/sub_array/sub_array.hpp>
#include <sprout/sub_array/sub.hpp> #include <sprout/sub_array/sub.hpp>
#include <sprout/pit/pit.hpp> #include <sprout/pit/pit.hpp>
namespace sprout { namespace sprout {
namespace fit { namespace fit {
namespace detail { namespace detail {
template<typename ForwardIterator, typename Result> template<typename ForwardIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type
fft_impl( fft_impl(
ForwardIterator const& first, ForwardIterator const& last, Result const& result, ForwardIterator const& first, ForwardIterator const& last, Result const& result,
typename sprout::container_traits<Result>::difference_type offset typename sprout::container_traits<Result>::difference_type offset
) )
{ {
return sprout::sub_copy( return sprout::sub_copy(
sprout::get_internal(sprout::fixed::fft(first, last, result)), sprout::get_internal(sprout::fixed::fft(first, last, result)),
offset, offset,
offset + sprout::fit_size(result, sprout::distance(first, last)) offset + sprout::fit_size(result, sprout::distance(first, last))
); );
} }
} // namespace detail } // namespace detail
// //
// fft // fft
// //
template<typename ForwardIterator, typename Result> template<typename ForwardIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type
fft(ForwardIterator first, ForwardIterator last, Result const& result) { fft(ForwardIterator first, ForwardIterator last, Result const& result) {
return sprout::fit::detail::fft_impl(first, last, result, sprout::internal_begin_offset(result)); return sprout::fit::detail::fft_impl(first, last, result, sprout::internal_begin_offset(result));
} }
template<typename Result, typename ForwardIterator> template<typename Result, typename ForwardIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
fft(ForwardIterator first, ForwardIterator last) { fft(ForwardIterator first, ForwardIterator last) {
return sprout::fit::fft(first, last, sprout::pit<Result>()); return sprout::fit::fft(first, last, sprout::pit<Result>());
} }
} // namespace fit } // namespace fit
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FFT_FIT_FFT_HPP #endif // #ifndef SPROUT_NUMERIC_FFT_FIT_FFT_HPP

View file

@ -1,55 +1,55 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_NUMERIC_FFT_FIT_IFFT_HPP #ifndef SPROUT_NUMERIC_FFT_FIT_IFFT_HPP
#define SPROUT_NUMERIC_FFT_FIT_IFFT_HPP #define SPROUT_NUMERIC_FFT_FIT_IFFT_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/distance.hpp> #include <sprout/iterator/distance.hpp>
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/numeric/fft/fixed/ifft.hpp> #include <sprout/numeric/fft/fixed/ifft.hpp>
#include <sprout/algorithm/fit/results.hpp> #include <sprout/algorithm/fit/results.hpp>
#include <sprout/sub_array/sub_array.hpp> #include <sprout/sub_array/sub_array.hpp>
#include <sprout/sub_array/sub.hpp> #include <sprout/sub_array/sub.hpp>
#include <sprout/pit/pit.hpp> #include <sprout/pit/pit.hpp>
namespace sprout { namespace sprout {
namespace fit { namespace fit {
namespace detail { namespace detail {
template<typename ForwardIterator, typename Result> template<typename ForwardIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type
ifft_impl( ifft_impl(
ForwardIterator const& first, ForwardIterator const& last, Result const& result, ForwardIterator const& first, ForwardIterator const& last, Result const& result,
typename sprout::container_traits<Result>::difference_type offset typename sprout::container_traits<Result>::difference_type offset
) )
{ {
return sprout::sub_copy( return sprout::sub_copy(
sprout::get_internal(sprout::fixed::ifft(first, last, result)), sprout::get_internal(sprout::fixed::ifft(first, last, result)),
offset, offset,
offset + sprout::fit_size(result, sprout::distance(first, last)) offset + sprout::fit_size(result, sprout::distance(first, last))
); );
} }
} // namespace detail } // namespace detail
// //
// ifft // ifft
// //
template<typename ForwardIterator, typename Result> template<typename ForwardIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fit::results::algorithm<Result>::type
ifft(ForwardIterator first, ForwardIterator last, Result const& result) { ifft(ForwardIterator first, ForwardIterator last, Result const& result) {
return sprout::fit::detail::ifft_impl(first, last, result, sprout::internal_begin_offset(result)); return sprout::fit::detail::ifft_impl(first, last, result, sprout::internal_begin_offset(result));
} }
template<typename Result, typename ForwardIterator> template<typename Result, typename ForwardIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
ifft(ForwardIterator first, ForwardIterator last) { ifft(ForwardIterator first, ForwardIterator last) {
return sprout::fit::ifft(first, last, sprout::pit<Result>()); return sprout::fit::ifft(first, last, sprout::pit<Result>());
} }
} // namespace fit } // namespace fit
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FFT_FIT_IFFT_HPP #endif // #ifndef SPROUT_NUMERIC_FFT_FIT_IFFT_HPP

View file

@ -1,118 +1,118 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_NUMERIC_FFT_FIXED_FFT_HPP #ifndef SPROUT_NUMERIC_FFT_FIXED_FFT_HPP
#define SPROUT_NUMERIC_FFT_FIXED_FFT_HPP #define SPROUT_NUMERIC_FFT_FIXED_FFT_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/array.hpp> #include <sprout/array.hpp>
#include <sprout/index_tuple/make_index_tuple.hpp> #include <sprout/index_tuple/make_index_tuple.hpp>
#include <sprout/algorithm/fixed/results.hpp> #include <sprout/algorithm/fixed/results.hpp>
#include <sprout/complex.hpp> #include <sprout/complex.hpp>
#include <sprout/math/less.hpp> #include <sprout/math/less.hpp>
#include <sprout/pit/pit.hpp> #include <sprout/pit/pit.hpp>
#include <sprout/numeric/fft/coefficients.hpp> #include <sprout/numeric/fft/coefficients.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
namespace detail { namespace detail {
template<typename value_type, std::size_t Size> template<typename value_type, std::size_t Size>
inline SPROUT_CONSTEXPR sprout::complex<value_type> inline SPROUT_CONSTEXPR sprout::complex<value_type>
fft_element( fft_element(
sprout::array<sprout::complex<value_type>, Size> const& arr, sprout::array<sprout::complex<value_type>, Size> const& arr,
std::size_t step, std::size_t i, std::size_t j, bool sub, std::size_t step, std::size_t i, std::size_t j, bool sub,
sprout::array<sprout::complex<value_type>, Size> const& coeffs sprout::array<sprout::complex<value_type>, Size> const& coeffs
) )
{ {
return sub return sub
? arr[i * step + j] - coeffs[j * (Size / 2 / step)] * arr[i * step + j + Size / 2] ? arr[i * step + j] - coeffs[j * (Size / 2 / step)] * arr[i * step + j + Size / 2]
: arr[i * step + j] + coeffs[j * (Size / 2 / step)] * arr[i * step + j + Size / 2] : arr[i * step + j] + coeffs[j * (Size / 2 / step)] * arr[i * step + j + Size / 2]
; ;
} }
template<typename value_type, std::size_t Size, sprout::index_t... Indexes> template<typename value_type, std::size_t Size, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
butterfly( butterfly(
sprout::array<sprout::complex<value_type>, Size> const& arr, sprout::array<sprout::complex<value_type>, Size> const& arr,
std::size_t step, std::size_t step,
sprout::array<sprout::complex<value_type>, Size> const& coeffs, sprout::array<sprout::complex<value_type>, Size> const& coeffs,
sprout::index_tuple<Indexes...> sprout::index_tuple<Indexes...>
) )
{ {
return sprout::array<sprout::complex<value_type>, Size> { { return sprout::array<sprout::complex<value_type>, Size> { {
fft_element(arr, step, Indexes / (step * 2), Indexes%step, (Indexes&step) != 0, coeffs)... fft_element(arr, step, Indexes / (step * 2), Indexes%step, (Indexes&step) != 0, coeffs)...
} }; } };
} }
template<typename value_type, std::size_t Size> template<typename value_type, std::size_t Size>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
fft_loop( fft_loop(
sprout::array<sprout::complex<value_type>, Size> const& arr, sprout::array<sprout::complex<value_type>, Size> const& arr,
std::size_t step, std::size_t step,
sprout::array<sprout::complex<value_type>, Size> const& coeffs sprout::array<sprout::complex<value_type>, Size> const& coeffs
) )
{ {
return step == Size ? arr return step == Size ? arr
: fft_loop(butterfly(arr, step, coeffs, sprout::make_index_tuple<Size>()), step * 2, coeffs); : fft_loop(butterfly(arr, step, coeffs, sprout::make_index_tuple<Size>()), step * 2, coeffs);
} }
template<typename value_type, std::size_t Size> template<typename value_type, std::size_t Size>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
fft(sprout::array<sprout::complex<value_type>, Size> const& arr) { fft(sprout::array<sprout::complex<value_type>, Size> const& arr) {
return fft_loop(arr, 1, sprout::make_fft_coefficients<value_type, Size>()); return fft_loop(arr, 1, sprout::make_fft_coefficients<value_type, Size>());
} }
template<typename Container, sprout::index_t... Indexes> template<typename Container, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR sprout::array<typename sprout::container_traits<Container>::value_type, sizeof...(Indexes)> inline SPROUT_CONSTEXPR sprout::array<typename sprout::container_traits<Container>::value_type, sizeof...(Indexes)>
make_input_impl(Container const& cont, sprout::index_tuple<Indexes...>) { make_input_impl(Container const& cont, sprout::index_tuple<Indexes...>) {
return sprout::array<typename sprout::container_traits<Container>::value_type, sizeof...(Indexes)> { { return sprout::array<typename sprout::container_traits<Container>::value_type, sizeof...(Indexes)> { {
(sprout::math::less(Indexes, cont.size()) (sprout::math::less(Indexes, cont.size())
? *sprout::next(sprout::begin(cont), Indexes) ? *sprout::next(sprout::begin(cont), Indexes)
: static_cast<typename sprout::container_traits<Container>::value_type>(0) : static_cast<typename sprout::container_traits<Container>::value_type>(0)
)... )...
} }; } };
} }
template<std::size_t Size, typename Container> template<std::size_t Size, typename Container>
inline SPROUT_CONSTEXPR sprout::array<typename sprout::container_traits<Container>::value_type, Size> inline SPROUT_CONSTEXPR sprout::array<typename sprout::container_traits<Container>::value_type, Size>
make_input(Container const& cont) { make_input(Container const& cont) {
return make_input_impl(cont, sprout::make_index_tuple<Size>()); return make_input_impl(cont, sprout::make_index_tuple<Size>());
} }
template<typename value_type, std::size_t Size, typename Result, sprout::index_t... Indexes> template<typename value_type, std::size_t Size, typename Result, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
make_fft_result_impl(sprout::array<sprout::complex<value_type>, Size> const& cont, Result const& result, sprout::index_tuple<Indexes...>) { make_fft_result_impl(sprout::array<sprout::complex<value_type>, Size> const& cont, Result const& result, sprout::index_tuple<Indexes...>) {
return remake<Result>(result, sprout::size(result), cont[Indexes]...); return remake<Result>(result, sprout::size(result), cont[Indexes]...);
} }
template<typename value_type, std::size_t Size, typename Result> template<typename value_type, std::size_t Size, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
make_fft_result(sprout::array<sprout::complex<value_type>, Size> const& cont, Result const& result) { make_fft_result(sprout::array<sprout::complex<value_type>, Size> const& cont, Result const& result) {
return make_fft_result_impl(cont, result, sprout::make_index_tuple<sprout::container_traits<Result>::static_size>()); return make_fft_result_impl(cont, result, sprout::make_index_tuple<sprout::container_traits<Result>::static_size>());
} }
} // namespace detail } // namespace detail
// //
// fft // fft
// Algorithm: Stockham decimation-in-time // Algorithm: Stockham decimation-in-time
// //
template<typename Container, typename Result> template<typename Container, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
fft(Container const& cont, Result const& result) { fft(Container const& cont, Result const& result) {
return sprout::fixed::detail::make_fft_result( return sprout::fixed::detail::make_fft_result(
sprout::fixed::detail::fft(sprout::fixed::detail::make_input<sprout::container_traits<Result>::static_size>(cont)), result sprout::fixed::detail::fft(sprout::fixed::detail::make_input<sprout::container_traits<Result>::static_size>(cont)), result
); );
} }
template<typename Result, typename Container> template<typename Result, typename Container>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
fft(Container const& cont) { fft(Container const& cont) {
return sprout::fixed::fft(cont, sprout::pit<Result>()); return sprout::fixed::fft(cont, sprout::pit<Result>());
} }
} // namespace fixed } // namespace fixed
using sprout::fixed::fft; using sprout::fixed::fft;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FFT_FIXED_FFT_HPP #endif // #ifndef SPROUT_NUMERIC_FFT_FIXED_FFT_HPP

View file

@ -1,65 +1,65 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_NUMERIC_FFT_FIXED_IFFT_HPP #ifndef SPROUT_NUMERIC_FFT_FIXED_IFFT_HPP
#define SPROUT_NUMERIC_FFT_FIXED_IFFT_HPP #define SPROUT_NUMERIC_FFT_FIXED_IFFT_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/array.hpp> #include <sprout/array.hpp>
#include <sprout/algorithm/fixed/results.hpp> #include <sprout/algorithm/fixed/results.hpp>
#include <sprout/complex.hpp> #include <sprout/complex.hpp>
#include <sprout/pit/pit.hpp> #include <sprout/pit/pit.hpp>
#include <sprout/numeric/fft/coefficients.hpp> #include <sprout/numeric/fft/coefficients.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
namespace detail { namespace detail {
template<typename value_type, std::size_t Size, typename Result, sprout::index_t... Indexes> template<typename value_type, std::size_t Size, typename Result, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
make_ifft_result_impl(sprout::array<sprout::complex<value_type>, Size> const& container, Result const& result, sprout::index_tuple<Indexes...>) { make_ifft_result_impl(sprout::array<sprout::complex<value_type>, Size> const& container, Result const& result, sprout::index_tuple<Indexes...>) {
return remake<Result>(result, sprout::size(result), (container[Indexes] / static_cast<value_type>(Size))...); return remake<Result>(result, sprout::size(result), (container[Indexes] / static_cast<value_type>(Size))...);
} }
template<typename value_type, std::size_t Size, typename Result> template<typename value_type, std::size_t Size, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
make_ifft_result(sprout::array<sprout::complex<value_type>, Size> const& container, Result const& result) { make_ifft_result(sprout::array<sprout::complex<value_type>, Size> const& container, Result const& result) {
return make_ifft_result_impl(container, result, sprout::make_index_tuple<sprout::container_traits<Result>::static_size>()); return make_ifft_result_impl(container, result, sprout::make_index_tuple<sprout::container_traits<Result>::static_size>());
} }
template<typename value_type, std::size_t Size> template<typename value_type, std::size_t Size>
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size> inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
ifft(sprout::array<sprout::complex<value_type>, Size> const& arr) { ifft(sprout::array<sprout::complex<value_type>, Size> const& arr) {
return sprout::fixed::detail::fft_loop(arr, 1, sprout::make_ifft_coefficients<value_type, Size>()); return sprout::fixed::detail::fft_loop(arr, 1, sprout::make_ifft_coefficients<value_type, Size>());
} }
} // namespace detail } // namespace detail
// //
// ifft // ifft
// Algorithm: Stockham decimation-in-time // Algorithm: Stockham decimation-in-time
// //
template< template<
typename ForwardIterator, typename Result, typename ForwardIterator, typename Result,
typename sprout::container_traits<Result>::size_type Size typename sprout::container_traits<Result>::size_type Size
= sprout::container_traits<Result>::static_size = sprout::container_traits<Result>::static_size
> >
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
ifft(ForwardIterator first, ForwardIterator last, Result const& result) { ifft(ForwardIterator first, ForwardIterator last, Result const& result) {
return sprout::fixed::detail::make_ifft_result( return sprout::fixed::detail::make_ifft_result(
sprout::fixed::detail::ifft(sprout::fixed::detail::make_input<Size>(first, last)), result sprout::fixed::detail::ifft(sprout::fixed::detail::make_input<Size>(first, last)), result
); );
} }
template<typename Result, typename ForwardIterator> template<typename Result, typename ForwardIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm<Result>::type
ifft(ForwardIterator first, ForwardIterator last) { ifft(ForwardIterator first, ForwardIterator last) {
return sprout::fixed::ifft(first, last, sprout::pit<Result>()); return sprout::fixed::ifft(first, last, sprout::pit<Result>());
} }
} // namespace fixed } // namespace fixed
using sprout::fixed::ifft; using sprout::fixed::ifft;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_NUMERIC_FFT_FIXED_IFFT_HPP #endif // #ifndef SPROUT_NUMERIC_FFT_FIXED_IFFT_HPP

View file

@ -1,21 +1,21 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2011-2016 Bolero MURAKAMI Copyright (c) 2011-2016 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/ =============================================================================*/
#ifndef SPROUT_UTILITY_IGNORE_UNUSED_HPP #ifndef SPROUT_UTILITY_IGNORE_UNUSED_HPP
#define SPROUT_UTILITY_IGNORE_UNUSED_HPP #define SPROUT_UTILITY_IGNORE_UNUSED_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
namespace sprout { namespace sprout {
// //
// ignore_unused // ignore_unused
// //
inline SPROUT_CXX14_CONSTEXPR void inline SPROUT_CXX14_CONSTEXPR void
ignore_unused(...) SPROUT_NOEXCEPT {} ignore_unused(...) SPROUT_NOEXCEPT {}
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_UTILITY_IGNORE_UNUSED_HPP #endif // #ifndef SPROUT_UTILITY_IGNORE_UNUSED_HPP

View file

@ -119,7 +119,7 @@ namespace testspr {
template<typename T> template<typename T>
inline SPROUT_NON_CONSTEXPR void inline SPROUT_NON_CONSTEXPR void
print_type() { print_type() {
testspr::print_typename<testspr::id<T> >(); testspr::print_ln(testspr::qualified_typename_of<T>());
} }
// //

View file

@ -88,6 +88,31 @@ namespace testspr {
typename_of(T&& t) { typename_of(T&& t) {
return testspr::detail::demangle(typeid(std::forward<T>(t)).name()); return testspr::detail::demangle(typeid(std::forward<T>(t)).name());
} }
//
// strip_outer_template
//
inline SPROUT_NON_CONSTEXPR std::string
strip_outer_template(std::string const& s) {
std::string::size_type f = s.find('<');
if (f == std::string::npos) {
return s;
}
std::string::size_type l = s.rfind('>');
if (l == std::string::npos || f > l) {
return s;
}
return s.substr(f + 1, l - f - 1);
}
//
// qualified_typename_of
//
template<typename T>
inline SPROUT_NON_CONSTEXPR std::string
qualified_typename_of() {
return testspr::strip_outer_template(testspr::typename_of<testspr::id<T> >());
}
} // namespace testspr } // namespace testspr
#endif // #ifndef TESTSPR_TYPEINFO_HPP #endif // #ifndef TESTSPR_TYPEINFO_HPP