35#include <mx/math/constants.hpp>
48template <
typename realT>
75template <
typename realT>
82 realT a = 1 + pow( alpha, 2 );
85 realT sqab = sqrt( a * a - b * b );
91 ( atan( ( ( a - b ) * tan( wf / 2 ) / sqab ) ) - atan( ( ( a - b ) * tan( w0 / 2 ) ) / sqab ) );
107template <
typename realT>
109 const std::vector<realT> &f,
115 psd.resize( f.size() );
117 realT fmax = 2 * f.back();
119 for(
size_t n = 0; n < f.size(); ++n )
121 realT denom = 1 + alpha * alpha - 2 * alpha * cos(
math::two_pi<realT>() * ( f[n] - fpole ) / fmax );
123 psd[n] = beta / denom;
137template <
typename realT>
139 const std::vector<realT> &f,
141 std::complex<realT> alpha
144 realT fpole = atan2( alpha.imag(), alpha.real() ) * ( 2 * f.back() ) /
math::two_pi<realT>();
146 return ar1PSD( psd, f, beta, abs( alpha ), fpole );
149template <
typename realT>
150void arNPSD( std::vector<realT> &psd,
151 const std::vector<realT> &f,
154 std::vector<realT> alphaMag,
155 std::vector<realT> alphaPhase )
157 psd.resize( f.size() );
159 std::complex j = std::complex<realT>( 0, 1 );
160 std::vector<std::complex<realT>> alpha( alphaMag.size() );
162 for(
size_t n = 0; n < alphaMag.size(); ++n )
164 alpha[n] = alphaMag[n] * exp( j * alphaPhase[n] );
167 for(
size_t n = 0; n < f.size(); ++n )
170 std::complex<realT> denom = 1.0;
172 for(
size_t m = 0; m < alpha.size(); ++m )
174 denom -= alpha[m] * exp( -j *
math::two_pi<realT>() * f[n] * std::complex<realT>( ( m + 1 ), 0 ) / fmax );
177 psd[n] = var / std::norm( denom );
realT ar1PSDNorm(realT beta, realT alpha, realT fpole, realT fsamp)
Calculate the norm of an AR1 PSD.
void ar1PSD(std::vector< realT > &psd, const std::vector< realT > &f, realT beta, realT alpha, realT fpole)
Generate an AR1 PSD.
realT ar1FreqPhase(realT f, realT fsamp)
Get the phase of a given frequency.
constexpr floatT six_fifths()
Return 6/5 in the specified precision.