@@ -20,12 +20,12 @@ namespace impl
2020template<class F, typename float_t, uint32_t Depth> // F has function __call(x)
2121struct 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
4444template<class F, typename float_t>
4545struct 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>
6565template<class F, typename float_t, uint32_t Depth=6 > // F has function __call(x)
6666struct 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