clad
clad copied to clipboard
Custom derivatives are not detected and used correctly when namespaces are present.
When implementing custom derivatives for one of the still unsupported std::erf built-ins, I noticed that custom derivatives were not being found and used correctly.
For example:
namespace clad { namespace custom_derivatives {
namespace std {
template <typename T>
ValueAndPushforward<T, T> erf_pushforward(T x, T d_x) {
return {::std::erf(x), M_2_SQRTPI*::std::exp(-::std::pow(x,2.0)) * d_x};
}
}
using std::erf_pushforward; // Required if we use C style function call erf(...) instead C++ std::erf(...)
}}
double f(double x) {
return std::erf(x) + 1;
}
int main() {
auto df = clad::differentiate(f, 0);
df.dump();
std::cout << "f(3)=" << f(3.0) << "; df(3)=" << df.execute(3.0) << std::endl;
return 0;
}
Dimps:
The code is:
double f_darg0(double x) {
double _d_x = 1;
ValueAndPushforward<double, double> _t0 = clad::custom_derivatives::erf_pushforward(x, _d_x);
return _t0.pushforward + 0;
}
f(3)=1.99998; df(3)=0.000139253
but we expect this:
... = clad::custom_derivatives::std::erf_pushforward(x, _d_x);
In contrast, in this case:
double f(double x) {
return erf(x) + 1;
}
we must generate:
... = clad::custom_derivatives::erf_pushforward(x, _d_x);
The problem is not only in the print/dump. This is easily seen if, instead of using
, we define non-std pushforward function, which returns, for example, a different result.