kfrlib / kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
https://www.kfrlib.com
GNU General Public License v2.0
1.65k stars 253 forks source link

KFR complex arg function is flipped! #113

Closed tstrutz closed 3 years ago

tstrutz commented 3 years ago

A project I'm working on used KFR's complex arg function to calculate the phase angle for some input I/Q data.

However, the results we were getting from the function appear to have the x and y inputs to the internal atan2 function flipped. We had to do this in order to get the correct results:

    double RefinedDetection::get_frequency(const double sample_rate) const
    {
        // Compute and unwrap phase vector.
        real_signal<double> angle_data( m_detection_data.size());

        // kfr::arg has invalid implementation, so we convert to std::complex in order to call std::arg here.
        for (uint32_t i(0); i < angle_data.size(); ++i)
        {
            std::complex<double> value( m_detection_data[i].real(), m_detection_data[i].imag());
            angle_data[i] = std::arg(value);
        }
        // Function continues...
    }

To replicate the issue, I wrote this code:

int main(int argc, char **argv)
{
    kfr::c32 kfr_real_pos(1.0, 0.0);
    kfr::c32 kfr_imag_pos(0.0, 1.0);
    kfr::c32 kfr_real_neg(-1.0, 0.0);
    kfr::c32 kfr_imag_neg(0.0, -1.0);
    std::complex<float> std_real_pos(1.0, 0.0);
    std::complex<float> std_imag_pos(0.0, 1.0);
    std::complex<float> std_real_neg(-1.0, 0.0);
    std::complex<float> std_imag_neg(0.0, -1.0);

    std::cout << "CARG of (1,0) KFR: " << kfr::carg(kfr_real_pos) << ", STD LIB: " << std::arg( std_real_pos) << std::endl;
    std::cout << "CARG of (0,1) KFR: " << kfr::carg(kfr_imag_pos) << ", STD LIB: " << std::arg( std_imag_pos) << std::endl;
    std::cout << "CARG of (-1,0) KFR: " << kfr::carg(kfr_real_neg) << ", STD LIB: " << std::arg( std_real_neg) << std::endl;
    std::cout << "CARG of (0,-1) KFR: " << kfr::carg(kfr_imag_neg) << ", STD LIB: " << std::arg( std_imag_neg) << std::endl;
}

Output of code against Standard C++ Library:

CARG of (1,0) KFR: 1.5708, STD LIB: 0
CARG of (0,1) KFR: 0, STD LIB: 1.5708
CARG of (-1,0) KFR: -1.5708, STD LIB: 3.14159
CARG of (0,-1) KFR: 3.14159, STD LIB: -1.5708
dancazarin commented 3 years ago

Hi,

The issue has been fixed in master branch.