Skip to content

Commit c792164

Browse files
Fermats-Last-TheoremShubham Shukla
andauthored
Add custom derivative for std::expint (#1745)
Co-authored-by: Shubham Shukla <shubham@localhost>
1 parent 5f5bb28 commit c792164

3 files changed

Lines changed: 81 additions & 1 deletion

File tree

include/clad/Differentiator/BuiltinDerivatives.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,51 @@ CUDA_HOST_DEVICE ValueAndPushforward<T, dT> expm1l_pushforward(T x, dT d_x) {
557557
return expm1_pushforward(x, d_x);
558558
}
559559

560+
#if __cplusplus >= 201703L
561+
// 2.4 expint, expintf, expintl
562+
template <typename T> CUDA_HOST_DEVICE inline T expint_primal(T x) {
563+
#if defined(__cpp_lib_math_special_funcs) || defined(__STDCPP_MATH_SPEC_FUNCS__)
564+
return ::std ::expint(x);
565+
#else
566+
return T(0);
567+
#endif
568+
}
569+
570+
template <typename T> CUDA_HOST_DEVICE inline T expintf_primal(T x) {
571+
#if defined(__cpp_lib_math_special_funcs) || defined(__STDCPP_MATH_SPEC_FUNCS__)
572+
return ::std ::expintf(x);
573+
#else
574+
return T(0);
575+
#endif
576+
}
577+
578+
template <typename T> CUDA_HOST_DEVICE inline T expintl_primal(T x) {
579+
#if defined(__cpp_lib_math_special_funcs) || defined(__STDCPP_MATH_SPEC_FUNCS__)
580+
return ::std ::expintl(x);
581+
#else
582+
return T(0);
583+
#endif
584+
}
585+
586+
template <typename T, typename dT>
587+
CUDA_HOST_DEVICE ValueAndPushforward<T, dT> expint_pushforward(T x, dT d_x) {
588+
return {static_cast<T>(expint_primal(x)),
589+
static_cast<dT>((::std ::exp(x) / x) * d_x)};
590+
}
591+
592+
template <typename T, typename dT>
593+
CUDA_HOST_DEVICE ValueAndPushforward<T, dT> expintf_pushforward(T x, dT d_x) {
594+
return {static_cast<T>(expintf_primal(x)),
595+
static_cast<dT>((::std ::exp(x) / x) * d_x)};
596+
}
597+
598+
template <typename T, typename dT>
599+
CUDA_HOST_DEVICE ValueAndPushforward<T, dT> expintl_pushforward(T x, dT d_x) {
600+
return {static_cast<T>(expintl_primal(x)),
601+
static_cast<dT>((::std ::exp(x) / x) * d_x)};
602+
}
603+
#endif
604+
560605
// 3. Logarithmic Functions
561606

562607
// 3.1 log, logf, logl
@@ -1351,6 +1396,11 @@ using std::expl_pushforward;
13511396
using std::expm1_pushforward;
13521397
using std::expm1f_pushforward;
13531398
using std::expm1l_pushforward;
1399+
#if __cplusplus >= 201703L
1400+
using std::expint_pushforward;
1401+
using std::expintf_pushforward;
1402+
using std::expintl_pushforward;
1403+
#endif
13541404

13551405
// 3. Logarithmic Functions
13561406
using std::log10_pushforward;

test/Features/stl-cmath.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
// D ellint_1/ f / l (C++17) incomplete elliptic integral (1st kind)
110110
// D ellint_2/ f / l (C++17) incomplete elliptic integral (2nd kind)
111111
// D ellint_3/ f / l (C++17) incomplete elliptic integral (3rd kind)
112-
// D expint/ expintf/ expintl (C++17) exponential integral
112+
// DS expint/ expintf/ expintl (C++17) exponential integral
113113
// D hermite/ hermitef/ hermitel (C++17) Hermite polynomials
114114
// D legendre/ legendref/ legendrel (C++17) Legendre polynomials
115115
// D laguerre/ laguerref/ laguerrel (C++17) Laguerre polynomials
@@ -262,6 +262,12 @@ long double f_fmal(long double x){ return fmal(x,2.0L, 1.0L); }
262262
DEFINE_FUNCTIONS(exp) // x in (-inf,+inf)
263263
DEFINE_FUNCTIONS(exp2) // x in (-inf,+inf)
264264
DEFINE_FUNCTIONS(expm1) // x in (-inf,+inf)
265+
#if __cplusplus >= 201703L && (defined(__cpp_lib_math_special_funcs) || defined(__STDCPP_MATH_SPEC_FUNCS__))
266+
template <typename T>
267+
T f_expint(T x) { return ::std ::expint(x); } // x in (-inf,0) U (0,+inf)
268+
inline float f_expintf(float x) { return ::std ::expintf(x); }
269+
inline long double f_expintl(long double x) { return ::std ::expintl(x); }
270+
#endif
265271
DEFINE_FUNCTIONS(log) // x in (0,+inf)
266272
DEFINE_FUNCTIONS(log10) // x in (0,+inf)
267273
DEFINE_FUNCTIONS(log2) // x in (0,+inf)
@@ -323,6 +329,10 @@ int main() {
323329
CHECK_ALL(exp);
324330
CHECK_ALL(exp2);
325331
CHECK_ALL(expm1);
332+
#if __cplusplus >= 201703L && (defined(__cpp_lib_math_special_funcs) || defined(__STDCPP_MATH_SPEC_FUNCS__))
333+
CHECK_ALL_RANGE(expint, {-2.0, -1.0, -0.5, 0.5, 1.0, 2.0, 3.0});
334+
#endif
335+
326336
CHECK_ALL(log);
327337
CHECK_ALL(log10);
328338
CHECK_ALL(log2);

test/FirstDerivative/BuiltinDerivatives.C

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ namespace std {
1818
#endif
1919

2020
extern "C" int printf(const char* fmt, ...);
21+
#include <cmath>
22+
23+
#if !defined(__cpp_lib_math_special_functions)
24+
namespace std {
25+
// std::expint mock for osx systems
26+
inline double expint(double x) { return 0.0; }
27+
inline float expintf(float x) { return 0.0f; }
28+
inline long double expintl(long double x) { return 0.0L; }
29+
}
30+
#endif
2131

2232

2333
namespace N {
@@ -453,6 +463,13 @@ double f_expm1l(double x) { return std::expm1l(x); }
453463
// CHECK-NEXT: return _t0.pushforward;
454464
// CHECK-NEXT: }
455465

466+
double f_expint(double x) { return std::expint(x); }
467+
// CHECK: double f_expint_darg0(double x) {
468+
// CHECK-NEXT: double _d_x = 1;
469+
// CHECK-NEXT: {{.*}}ValueAndPushforward<double, double> _t0 = {{.*}}expint_pushforward(x, _d_x);
470+
// CHECK-NEXT: return _t0.pushforward;
471+
// CHECK-NEXT: }
472+
456473
double f_log1pl(double x) { return std::log1pl(x); }
457474
// CHECK: double f_log1pl_darg0(double x) {
458475
// CHECK-NEXT: double _d_x = 1;
@@ -684,6 +701,9 @@ int main () { //expected-no-diagnostics
684701
auto d_expm1l = clad::differentiate(f_expm1l, 0);
685702
printf("Result is = %.6f\n", d_expm1l.execute(0.5)); // CHECK-EXEC: Result is = 1.648721
686703

704+
auto d_expint = clad::differentiate(f_expint, 0);
705+
printf("Result is = %.6f\n", d_expint.execute(0.5)); // CHECK-EXEC: Result is = 3.297443
706+
687707
auto d_log1pl = clad::differentiate(f_log1pl, 0);
688708
printf("Result is = %.6f\n", d_log1pl.execute(0.5)); // CHECK-EXEC: Result is = 0.666667
689709

0 commit comments

Comments
 (0)