Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with atan2 at 0 #120

Closed
artivis opened this issue Sep 19, 2021 · 4 comments
Closed

Issue with atan2 at 0 #120

artivis opened this issue Sep 19, 2021 · 4 comments

Comments

@artivis
Copy link

artivis commented Sep 19, 2021

Hi,

The following snippet does not run successfully whereas I would expect it to,

bool atan2_at_zero() {

    using CppAD::AD;
    using CppAD::NearEqual;

    bool ok = true;
    double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

    CPPAD_TESTVECTOR(AD<double>) v(2);
    v[0] = 1; // real: cos(0)
    v[1] = 0; // imag: sin(0)

    Independent(v);

    CPPAD_TESTVECTOR(AD<double>) t(1);
    t[0] = atan2(v[1], v[0]);

    CppAD::ADFun<double> f(v, t);

    CPPAD_TESTVECTOR(double) vv(2);
    vv[0] = CppAD::Value(v[0]);
    vv[1] = CppAD::Value(v[1]);

    auto grad = f.Jacobian(vv);

    ok   &= NearEqual(t[0], 0., eps99, eps99);       // ok
    ok   &= NearEqual(grad[0], 1., eps99, eps99);    // fails
    ok   &= NearEqual(grad[1], 0., eps99, eps99);    // ok

    return ok;
}

Being new to CppAD, I'm not sure if I'm doing it wrong or if this is an actual bug.

@bradbell
Copy link
Contributor

bradbell commented Sep 24, 2021

This seems to be a bug. The following code passes (fails) its test when y is VALUE_OF_Y_OK (VALUE_OF_Y_FAILS):

# include <cppad/cppad.hpp>

# define VALUE_OF_Y_FAILS 0.0
# define VALUE_OF_Y_OK    1e-200
int main ()
{   using CppAD::AD;
    using CppAD::NearEqual;
    //
    bool ok      = true;
    double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
    double x     = 1.0;                    // r*cos(0)
    double y     = VALUE_OF_Y_FAILS;       // r*sin(0)
    double r     = std::sqrt( x*x + y*y ); // r
    //
    CppAD::vector< AD<double> > av(2);
    av[0] = x; 
    av[1] = y;
    Independent(av);
    //
    CppAD::vector< AD<double> > at(1);
    at[0] = atan2(av[1], av[0]);
    CppAD::ADFun<double> f(av, at);
    //
    CppAD::vector<double> v(2);
    v[0] = x;
    v[1] = y;
    CppAD::vector<double>  grad = f.Jacobian(v);
    std::cout << "grad  = " << grad << "\n";
    //
    // see https://en.wikipedia.org/wiki/Atan2#Derivative
    ok   &= NearEqual( CppAD::Value(at[0]), 0., eps99, eps99);       // atan2
    ok   &= NearEqual(grad[0], -y / r, eps99, eps99);                // fails
    ok   &= NearEqual(grad[1],  x / r, eps99, eps99);                // ok
    //
    std::cout << "ok = " << ok << "\n";
    //
    return int( ! ok );
}

@bradbell
Copy link
Contributor

@artivis
I think this has been fixed by the change to atan2.hpp in
a1d19b7

Please close this bug If you are satisfied with this correction.

@artivis
Copy link
Author

artivis commented Sep 26, 2021

@bradbell, Thanks for the quick fix 👍 .
I'll give it a try asap.

@artivis
Copy link
Author

artivis commented Sep 27, 2021

I can confirm that the issue is fixed. Thanks again @bradbell.

@artivis artivis closed this as completed Sep 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants