Skip to content

Commit 30b15ce

Browse files
lucascolleyizaid
authored andcommitted
MAINT: xsf: add erf, faddeeva, log_ndtr
Co-authored-by: Irwin Zaid <[email protected]>
1 parent b75ec5a commit 30b15ce

File tree

3 files changed

+1949
-0
lines changed

3 files changed

+1949
-0
lines changed

include/xsf/erf.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#pragma once
2+
3+
#include "faddeeva.h"
4+
#include "cephes/ndtr.h"
5+
#include "config.h"
6+
7+
namespace xsf {
8+
9+
inline double erf(double x) { return cephes::erf(x); }
10+
11+
inline float erf(float x) { return erf(static_cast<double>(x)); }
12+
13+
inline std::complex<double> erf(std::complex<double> z) { return Faddeeva::erf(z); }
14+
15+
inline std::complex<float> erf(std::complex<float> x) {
16+
return static_cast<std::complex<float>>(erf(static_cast<std::complex<double>>(x)));
17+
}
18+
19+
inline double erfc(double x) { return cephes::erfc(x); }
20+
21+
inline float erfc(float x) { return erfc(static_cast<double>(x)); }
22+
23+
inline std::complex<double> erfc(std::complex<double> z) { return Faddeeva::erfc(z); }
24+
25+
inline std::complex<float> erfc(std::complex<float> x) {
26+
return static_cast<std::complex<float>>(erfc(static_cast<std::complex<double>>(x)));
27+
}
28+
29+
inline double erfcx(double x) { return Faddeeva::erfcx(x); }
30+
31+
inline float erfcx(float x) { return erfcx(static_cast<double>(x)); }
32+
33+
inline std::complex<double> erfcx(std::complex<double> z) { return Faddeeva::erfcx(z); }
34+
35+
inline std::complex<float> erfcx(std::complex<float> x) {
36+
return static_cast<std::complex<float>>(erfcx(static_cast<std::complex<double>>(x)));
37+
}
38+
39+
inline double erfi(double x) { return Faddeeva::erfi(x); }
40+
41+
inline float erfi(float x) { return erfi(static_cast<double>(x)); }
42+
43+
inline std::complex<double> erfi(std::complex<double> z) { return Faddeeva::erfi(z); }
44+
45+
inline std::complex<float> erfi(std::complex<float> z) {
46+
return static_cast<std::complex<float>>(erfi(static_cast<std::complex<double>>(z)));
47+
}
48+
49+
inline double voigt_profile(double x, double sigma, double gamma) {
50+
const double INV_SQRT_2 = 0.707106781186547524401;
51+
const double SQRT_2PI = 2.5066282746310002416123552393401042;
52+
53+
if (sigma == 0) {
54+
if (gamma == 0) {
55+
if (std::isnan(x))
56+
return x;
57+
if (x == 0)
58+
return INFINITY;
59+
return 0;
60+
}
61+
return gamma / M_PI / (x * x + gamma * gamma);
62+
}
63+
if (gamma == 0) {
64+
return 1 / SQRT_2PI / sigma * exp(-(x / sigma) * (x / sigma) / 2);
65+
}
66+
67+
double zreal = x / sigma * INV_SQRT_2;
68+
double zimag = gamma / sigma * INV_SQRT_2;
69+
std::complex<double> z(zreal, zimag);
70+
std::complex<double> w = Faddeeva::w(z);
71+
return w.real() / sigma / SQRT_2PI;
72+
}
73+
74+
inline float voigt_profile(float x, float sigma, float gamma) {
75+
return voigt_profile(static_cast<double>(x), static_cast<double>(sigma), static_cast<double>(gamma));
76+
}
77+
78+
inline std::complex<double> wofz(std::complex<double> z) { return Faddeeva::w(z); }
79+
80+
inline std::complex<float> wofz(std::complex<float> x) {
81+
return static_cast<std::complex<float>>(wofz(static_cast<std::complex<double>>(x)));
82+
}
83+
84+
inline double dawsn(double x) { return Faddeeva::Dawson(x); }
85+
86+
inline float dawsn(float x) { return dawsn(static_cast<double>(x)); }
87+
88+
inline std::complex<double> dawsn(std::complex<double> z) { return Faddeeva::Dawson(z); }
89+
90+
inline std::complex<float> dawsn(std::complex<float> x) {
91+
return static_cast<std::complex<float>>(dawsn(static_cast<std::complex<double>>(x)));
92+
}
93+
94+
} // namespace xsf

0 commit comments

Comments
 (0)