1#ifndef STAN_MATH_FWD_FUN_FFT_HPP
2#define STAN_MATH_FWD_FUN_FFT_HPP
24template <
typename V, require_eigen_vector_vt<is_complex, V>* =
nullptr,
25 require_fvar_t<base_type_t<value_type_t<V>>>* =
nullptr>
26inline Eigen::Matrix<scalar_type_t<V>, -1, 1>
fft(V&& x) {
29 using complex_t = std::complex<partials_type_t<fvar_t>>;
30 decltype(
auto) x_ref =
to_ref(std::forward<V>(x));
31 if (x_ref.size() <= 1) {
32 return Eigen::Matrix<scalar_type_t<V>, -1, 1>(x_ref);
35 Eigen::Matrix<complex_t, -1, 1> x_val =
value_of(x_ref);
36 Eigen::Matrix<complex_t, -1, 1> x_d = x_ref.unaryExpr(
37 [](
const auto& z) {
return complex_t(z.real().d(), z.imag().d()); });
39 auto y_val =
fft(std::move(x_val));
40 auto y_d =
fft(std::move(x_d));
42 using out_t = Eigen::Matrix<scalar_type_t<V>, -1, 1>;
44 = y_val.binaryExpr(y_d, [](
const complex_t& val,
const complex_t& der) {
45 return std::complex<fvar_t>{fvar_t(val.real(), der.real()),
46 fvar_t(val.imag(), der.imag())};
59template <
typename V, require_eigen_vector_vt<is_complex, V>* =
nullptr,
60 require_fvar_t<base_type_t<value_type_t<V>>>* =
nullptr>
61inline Eigen::Matrix<scalar_type_t<V>, -1, 1>
inv_fft(V&& y) {
64 using complex_t = std::complex<partials_type_t<fvar_t>>;
65 decltype(
auto) y_ref =
to_ref(std::forward<V>(y));
66 if (y_ref.size() <= 1) {
67 return Eigen::Matrix<scalar_type_t<V>, -1, 1>(y_ref);
70 Eigen::Matrix<complex_t, -1, 1> y_val =
value_of(y_ref);
71 Eigen::Matrix<complex_t, -1, 1> y_d = y_ref.unaryExpr(
72 [](
const auto& z) {
return complex_t(z.real().d(), z.imag().d()); });
74 auto x_val =
inv_fft(std::move(y_val));
75 auto x_d =
inv_fft(std::move(y_d));
77 using out_t = Eigen::Matrix<scalar_type_t<V>, -1, 1>;
79 = x_val.binaryExpr(x_d, [](
const complex_t& val,
const complex_t& der) {
80 return std::complex<fvar_t>{fvar_t(val.real(), der.real()),
81 fvar_t(val.imag(), der.imag())};
94template <
typename M, require_eigen_dense_dynamic_vt<is_complex, M>* =
nullptr,
95 require_fvar_t<base_type_t<value_type_t<M>>>* =
nullptr>
96inline Eigen::Matrix<scalar_type_t<M>, -1, -1>
fft2(M&& x) {
99 using complex_t = std::complex<partials_type_t<fvar_t>>;
100 decltype(
auto) x_ref =
to_ref(std::forward<M>(x));
101 Eigen::Matrix<complex_t, -1, -1> x_val =
value_of(x_ref);
102 Eigen::Matrix<complex_t, -1, -1> x_d = x_ref.unaryExpr(
103 [](
const auto& z) {
return complex_t(z.real().d(), z.imag().d()); });
105 auto y_val =
fft2(std::move(x_val));
106 auto y_d =
fft2(std::move(x_d));
108 using out_t = Eigen::Matrix<scalar_type_t<M>, -1, -1>;
110 = y_val.binaryExpr(y_d, [](
const complex_t& val,
const complex_t& der) {
111 return std::complex<fvar_t>{fvar_t(val.real(), der.real()),
112 fvar_t(val.imag(), der.imag())};
125template <
typename M, require_eigen_dense_dynamic_vt<is_complex, M>* =
nullptr,
126 require_fvar_t<base_type_t<value_type_t<M>>>* =
nullptr>
127inline Eigen::Matrix<scalar_type_t<M>, -1, -1>
inv_fft2(M&& y) {
130 using complex_t = std::complex<partials_type_t<fvar_t>>;
131 decltype(
auto) y_ref =
to_ref(std::forward<M>(y));
132 Eigen::Matrix<complex_t, -1, -1> y_val =
value_of(y_ref);
133 Eigen::Matrix<complex_t, -1, -1> y_d = y_ref.unaryExpr(
134 [](
const auto& z) {
return complex_t(z.real().d(), z.imag().d()); });
136 auto x_val =
inv_fft2(std::move(y_val));
137 auto x_d =
inv_fft2(std::move(y_d));
139 using out_t = Eigen::Matrix<scalar_type_t<M>, -1, -1>;
141 = x_val.binaryExpr(x_d, [](
const complex_t& val,
const complex_t& der) {
142 return std::complex<fvar_t>{fvar_t(val.real(), der.real()),
143 fvar_t(val.imag(), der.imag())};
Eigen::Matrix< scalar_type_t< V >, -1, 1 > inv_fft(V &&y)
Return the inverse discrete Fourier transform of the specified complex vector for forward-mode autodi...
Eigen::Matrix< scalar_type_t< M >, -1, -1 > inv_fft2(M &&y)
Return the two-dimensional inverse discrete Fourier transform of the specified complex matrix for for...
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Eigen::Matrix< scalar_type_t< M >, -1, -1 > fft2(M &&x)
Return the two-dimensional discrete Fourier transform of the specified complex matrix for forward-mod...
Eigen::Matrix< scalar_type_t< V >, -1, 1 > fft(V &&x)
Return the discrete Fourier transform of the specified complex vector for forward-mode autodiff.
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
typename scalar_type< T >::type scalar_type_t
typename base_type< T >::type base_type_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...