mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-11-29 01:03:45 +00:00
e6af368c77
Stockham DIT fft algorithm written in C++11constexpr
81 lines
3 KiB
C++
81 lines
3 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2011-2016 Bolero MURAKAMI
|
|
https://github.com/bolero-MURAKAMI/Sprout
|
|
|
|
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)
|
|
=============================================================================*/
|
|
#ifndef SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP
|
|
#define SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP
|
|
|
|
#include <sprout/config.hpp>
|
|
#include <sprout/array.hpp>
|
|
#include <sprout/bit/bit_length.hpp>
|
|
#include <sprout/index_tuple/make_index_tuple.hpp>
|
|
#include <sprout/complex.hpp>
|
|
#include <sprout/math/cos.hpp>
|
|
#include <sprout/math/sin.hpp>
|
|
#include <sprout/math/constants.hpp>
|
|
|
|
namespace sprout {
|
|
namespace detail
|
|
{
|
|
template<typename value_type, sprout::index_t... Indexes>
|
|
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, sizeof...(Indexes)*2>
|
|
make_fft_coefficients_impl(
|
|
sprout::array<sprout::complex<value_type>, sizeof...(Indexes)> const& arr,
|
|
sprout::complex<value_type> mul, sprout::index_tuple<Indexes...>
|
|
)
|
|
{
|
|
return sprout::array<sprout::complex<value_type>, sizeof...(Indexes)*2>{ {
|
|
arr[Indexes]..., (arr[Indexes] * mul)...
|
|
} };
|
|
}
|
|
|
|
template<typename value_type, std::size_t N, std::size_t Size>
|
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
|
N == 0,
|
|
typename sprout::array<sprout::complex<value_type>, 1>
|
|
>::type
|
|
make_fft_coefficients_loop( bool ) {
|
|
return typename sprout::array<sprout::complex<value_type>, 1>{ {
|
|
{ static_cast<value_type>( 1 ) }
|
|
} };
|
|
}
|
|
|
|
template<typename value_type, std::size_t N, std::size_t Size>
|
|
inline SPROUT_CONSTEXPR typename std::enable_if<
|
|
N != 0,
|
|
typename sprout::array<sprout::complex<value_type>, 1 << N>
|
|
>::type
|
|
make_fft_coefficients_loop(bool inverse)
|
|
{
|
|
return make_fft_coefficients_impl(
|
|
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::sin((inverse?-1:1)*sprout::math::two_pi<value_type>() / (1 << Size >> (N - 1)))
|
|
},
|
|
sprout::make_index_tuple<1 << (N - 1)>()
|
|
);
|
|
}
|
|
|
|
template<typename value_type, std::size_t Size>
|
|
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, 1 << Size>
|
|
make_fft_coefficients(bool inverse) {
|
|
return make_fft_coefficients_loop<value_type, Size, Size>(inverse);
|
|
}
|
|
} // namespace detail
|
|
template<typename value_type, std::size_t Size>
|
|
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
|
|
make_fft_coefficients() {
|
|
return sprout::detail::make_fft_coefficients<value_type, sprout::bit_length(Size)-1>(false);
|
|
}
|
|
template<typename value_type, std::size_t Size>
|
|
inline SPROUT_CONSTEXPR sprout::array<sprout::complex<value_type>, Size>
|
|
make_ifft_coefficients() {
|
|
return sprout::detail::make_fft_coefficients<value_type, sprout::bit_length(Size)-1>(true);
|
|
}
|
|
} // namespce sprout
|
|
|
|
#endif // SPROUT_NUMERIC_FFT_COEFFICIENT_ARRAY_HPP
|