Skip to content

Commit 3354e6a

Browse files
committed
converted adaptive simpson 2d into templated structs
1 parent e9a325a commit 3354e6a

File tree

1 file changed

+62
-13
lines changed

1 file changed

+62
-13
lines changed

include/nbl/builtin/hlsl/math/quadrature/adaptive_simpson.hlsl

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ namespace impl
2020
template<class F, typename float_t, uint32_t Depth> // F has function __call(x)
2121
struct integrate_helper
2222
{
23-
static float_t __call(float_t a, float_t b, float_t c, float_t fa, float_t fb, float_t fc, float_t I, float_t eps, NBL_REF_ARG(int) count)
23+
static float_t __call(NBL_REF_ARG(F) f, float_t a, float_t b, float_t c, float_t fa, float_t fb, float_t fc, float_t I, float_t eps, NBL_REF_ARG(int) count)
2424
{
2525
float_t d = float_t(0.5) * (a + b);
2626
float_t e = float_t(0.5) * (b + c);
27-
float_t fd = F::__call(d);
28-
float_t fe = F::__call(e);
27+
float_t fd = f.__call(d);
28+
float_t fe = f.__call(e);
2929

3030
float_t h = c - a;
3131
float_t I0 = (float_t(1.0) / float_t(12.0)) * h * (fa + float_t(4.0) * fd + fb);
@@ -36,20 +36,20 @@ struct integrate_helper
3636
if (hlsl::abs(Ip - I) < float_t(15.0) * eps)
3737
return Ip + (float_t(1.0) / float_t(15.0)) * (Ip - I);
3838

39-
return integrate_helper<F, float_t, Depth-1>::__call(a, d, b, fa, fd, fb, I0, float_t(0.5) * eps, count) +
40-
integrate_helper<F, float_t, Depth-1>::__call(b, e, c, fb, fe, fc, I1, float_t(0.5) * eps, count);
39+
return integrate_helper<F, float_t, Depth-1>::__call(f, a, d, b, fa, fd, fb, I0, float_t(0.5) * eps, count) +
40+
integrate_helper<F, float_t, Depth-1>::__call(f, b, e, c, fb, fe, fc, I1, float_t(0.5) * eps, count);
4141
}
4242
};
4343

4444
template<class F, typename float_t>
4545
struct integrate_helper<F, float_t, 0>
4646
{
47-
static float_t __call(float_t a, float_t b, float_t c, float_t fa, float_t fb, float_t fc, float_t I, float_t eps, NBL_REF_ARG(int) count)
47+
static float_t __call(NBL_REF_ARG(F) f, float_t a, float_t b, float_t c, float_t fa, float_t fb, float_t fc, float_t I, float_t eps, NBL_REF_ARG(int) count)
4848
{
4949
float_t d = float_t(0.5) * (a + b);
5050
float_t e = float_t(0.5) * (b + c);
51-
float_t fd = F::__call(d);
52-
float_t fe = F::__call(e);
51+
float_t fd = f.__call(d);
52+
float_t fe = f.__call(e);
5353

5454
float_t h = c - a;
5555
float_t I0 = (float_t(1.0) / float_t(12.0)) * h * (fa + float_t(4.0) * fd + fb);
@@ -65,17 +65,66 @@ struct integrate_helper<F, float_t, 0>
6565
template<class F, typename float_t, uint32_t Depth=6> // F has function __call(x)
6666
struct AdaptiveSimpson
6767
{
68-
static float_t __call(float_t x0, float_t x1, float_t eps = 1e-6)
68+
static float_t __call(NBL_REF_ARG(F) f, float_t x0, float_t x1, float_t eps = 1e-6)
6969
{
7070
int count = 0;
7171
float_t a = x0;
7272
float_t b = float_t(0.5) * (x0 + x1);
7373
float_t c = x1;
74-
float_t fa = F::__call(a);
75-
float_t fb = F::__call(b);
76-
float_t fc = F::__call(c);
74+
float_t fa = f.__call(a);
75+
float_t fb = f.__call(b);
76+
float_t fc = f.__call(c);
7777
float_t I = (c - a) * (float_t(1.0) / float_t(6.0)) * (fa + float_t(4.0) * fb + fc);
78-
return impl::integrate_helper<F, float_t, Depth>::__call(a, b, c, fa, fb, fc, I, eps, count);
78+
return impl::integrate_helper<F, float_t, Depth>::__call(f, a, b, c, fa, fb, fc, I, eps, count);
79+
}
80+
};
81+
82+
83+
namespace impl
84+
{
85+
template<class F, typename float_t>
86+
struct InnerIntegrand
87+
{
88+
float __call(float_t x)
89+
{
90+
return f.__call(x, y);
91+
}
92+
93+
F f;
94+
float_t y;
95+
};
96+
97+
template<class F, typename float_t, uint32_t Depth>
98+
struct OuterIntegrand
99+
{
100+
float __call(float_t y)
101+
{
102+
using func_t = InnerIntegrand<F, float_t>;
103+
func_t innerFunc;
104+
innerFunc.f = f;
105+
innerFunc.y = y;
106+
return AdaptiveSimpson<func_t, float_t, Depth>::__call(innerFunc, x0, x1, eps);
107+
}
108+
109+
F f;
110+
float_t x0;
111+
float_t x1;
112+
float_t eps;
113+
};
114+
}
115+
116+
template<class F, typename float_t, uint32_t Depth=6> // F has function __call(x)
117+
struct AdaptiveSimpson2D
118+
{
119+
static float_t __call(NBL_REF_ARG(F) f, float32_t2 x0, float32_t2 x1, float_t eps = 1e-6)
120+
{
121+
using func_t = impl::OuterIntegrand<F, float_t, Depth>;
122+
func_t outerFunc;
123+
outerFunc.f = f;
124+
outerFunc.x0 = x0.x;
125+
outerFunc.x1 = x1.x;
126+
outerFunc.eps = eps;
127+
return AdaptiveSimpson<func_t, float_t, Depth>::__call(outerFunc, x0.y, x1.y, eps);
79128
}
80129
};
81130

0 commit comments

Comments
 (0)