vgvassilev / clad

clad -- automatic differentiation for C/C++
GNU Lesser General Public License v3.0
291 stars 122 forks source link

clad::gradient and clad::differentiate produce different results under certain numerical conditions #1108

Open ZeptoStarling opened 1 month ago

ZeptoStarling commented 1 month ago

clad::gradient returns NaN values due to (unused) std::acos in the function definition receiving invalid input, while clad::differentiate calculates the derivatives. So this:

double f(double C, double A)
{
    double a = std::acos(-C / A); // valid input is -1 <= -C/A <= 1
    return 2 * C * C * A;
}

int main()
{
    auto f_grad = clad::gradient(f);
    double dC = 0, dA = 0;
    f_grad.execute(/*C=*/5, /*A=*/3, &dC, &dA);
    std::cout << "clad::gradient results: " << std::endl;
    std::cout << dC << " " << dA << std::endl;
    std::cout << "clad::differentiate results: " << std::endl;
    auto f_dC = clad::differentiate(f, "C");
    std::cout << f_dC.execute(/*C=*/5, /*A=*/3) << " ";
    auto f_dA = clad::differentiate(f, "A");
    std::cout << f_dA.execute(/*C=*/5, /*A=*/3) << std::endl;
}

on Clad version 1.8~dev produces these results:

clad::gradient results: 
nan -nan
clad::differentiate results: 
60 50