43template <
typename T,
typename F,
size_t N>
44 T integral_aux_boundary(
const F& f,
const std::array<T, Util::pow(3, N)>& f_evaluated, std::array<T, N>& x1, std::array<T, N> x2,
const T& volume,
const T& epsilon, std::array<size_t, N>& level, std::array<size_t, N>& index,
size_t dimension,
bool& refine,
size_t depth,
size_t depth_min,
size_t depth_max,
const T& gamma )
51 auto perform_refinement = [&] () -> T
55 if( (depth >= depth_max) || (level[dimension] == 0) )
62 for(
size_t i = 0; i < dimension; ++i )
68 std::array<T, Util::pow(3, N)> f_evaluated_l;
69 std::array<T, Util::pow(3, N)> f_evaluated_r;
71 size_t refinement_index = 0;
72 std::array<T, N> position;
73 size_t threeN = Util::pow<size_t>(3, N);
76 for(
size_t i = 0; i < threeN; ++i )
83 for(
size_t k = 0; k < N; ++k )
89 refinement_index = (tmp%3);
103 position[k] = (x1[k] + x2[k]) * (T) 0.5;
122 switch( refinement_index )
127 f_evaluated_l[i] = f_evaluated[i];
128 f_evaluated_r[i] = f_evaluated[i + stride];
134 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.25;
135 f_evaluated_l[i] = f(position);
137 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.75;
138 f_evaluated_r[i] = f(position);
143 f_evaluated_l[i] = f_evaluated[i - stride];
144 f_evaluated_r[i] = f_evaluated[i];
155 T correction = (T) 0.0;
158 bool refine2 =
false;
161 T center = (x1[dimension] + x2[dimension]) * (T) 0.5;
167 index[dimension] *= 2;
170 T tmp = x2[dimension];
171 x2[dimension] = center;
174 correction += integral_aux_boundary( f, f_evaluated_l, x1, x2, volume*(T)0.5, epsilon, level, index, dimension, refine2, depth+1, depth_min, depth_max, gamma );
182 x1[dimension] = center;
185 correction += integral_aux_boundary( f, f_evaluated_r, x1, x2, volume*(T)0.5, epsilon, level, index, dimension, refine2, depth+1, depth_min, depth_max, gamma );
192 index[dimension] /= 2;
206 T local_integral = integral_aux_boundary( f, f_evaluated, x1, x2, volume, epsilon, level, index, dimension-1, refine, depth, depth_min, depth_max, gamma );
212 local_integral += perform_refinement();
216 return local_integral;
228 for(
size_t i = 0; i < Util::pow<size_t>(3, N); ++i )
241 for(
size_t k = 0; k < N; ++k )
246 if( (level[k] == 0) && ( (tmp%3) != index[k] ) )
272 w += wcoeff * f_evaluated[i];
279 T local_integral = (Util::pow<T>(0.5, N) * volume) * w;
282 if( (depth < depth_min) || (Util::abs(w) > epsilon) )
284 local_integral += perform_refinement();
293 return local_integral;
326template <
typename T,
typename F,
size_t N>
327 T integral_aux(
const F& f,
const std::array<T, Util::pow(3, N)>& f_evaluated, std::array<T, N>& x1, std::array<T, N>& x2,
const T& volume,
const T& epsilon,
size_t dimension,
bool& refine,
size_t depth,
size_t depth_min,
size_t depth_max,
const T& gamma )
334 auto perform_refinement = [&] () -> T
338 if( depth >= depth_max )
345 for(
size_t i = 0; i < dimension; ++i )
351 std::array<T, Util::pow(3, N)> f_evaluated_l;
352 std::array<T, Util::pow(3, N)> f_evaluated_r;
354 size_t refinement_index = 0;
355 std::array<T, N> position;
357 size_t endi = Util::pow<size_t>(3, N);
359 for(
size_t i = 0; i < endi; ++i )
366 for(
size_t k = 0; k < N; ++k )
371 refinement_index = (tmp%3);
385 position[k] = (x1[k] + x2[k]) * (T) 0.5;
404 switch( refinement_index )
409 f_evaluated_l[i] = f_evaluated[i];
410 f_evaluated_r[i] = f_evaluated[i + stride];
416 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.25;
417 f_evaluated_l[i] = f(position);
419 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.75;
420 f_evaluated_r[i] = f(position);
425 f_evaluated_l[i] = f_evaluated[i - stride];
426 f_evaluated_r[i] = f_evaluated[i];
437 T correction = (T) 0.0;
440 bool refine2 =
false;
443 T center = (x1[dimension] + x2[dimension]) * (T) 0.5;
446 T tmp = x2[dimension];
447 x2[dimension] = center;
450 correction += integral_aux( f, f_evaluated_l, x1, x2, volume*(T)0.5, epsilon, dimension, refine2, depth+1, depth_min, depth_max, gamma );
455 x1[dimension] = center;
458 correction += integral_aux( f, f_evaluated_r, x1, x2, volume*(T)0.5, epsilon, dimension, refine2, depth+1, depth_min, depth_max, gamma );
471 T local_integral = integral_aux( f, f_evaluated, x1, x2, volume, epsilon, dimension-1, refine, depth, depth_min, depth_max, gamma );
477 local_integral += perform_refinement();
481 return local_integral;
493 for(
size_t i = 0; i < Util::pow<size_t>(3, N); ++i )
503 for(
size_t k = 0; k < N; ++k )
517 w += wcoeff * f_evaluated[i];
525 T local_integral = (Util::pow<T>(0.5, N)) * volume * w;
528 if( (depth < depth_min) || (Util::abs(w) > epsilon) )
530 local_integral += perform_refinement();
539 return local_integral;
565template <
typename T,
typename F,
size_t N>
566 T integral(
const F& f, std::array<T, N>& x1, std::array<T, N> x2,
const T& epsilon,
size_t depth_min = 0,
size_t depth_max = std::numeric_limits<size_t>::max(),
const T& gamma = (T) 1.0e12 )
570 T integral = (T) 0.0;
575 for(
size_t i = 0; i < N; ++i )
577 volume *= (x2[i] - x1[i]);
589 size_t array_size = Util::pow<size_t>(3, N);
590 T t = Util::pow<T>(0.5,N);
591 size_t twoN = Util::POW2(N);
595 std::array<T, N> position;
596 std::array<T, Util::pow(3, N)> f_evaluated;
599 for(
size_t i = 0; i < array_size; ++i )
602 bool boundary =
true;
607 for(
size_t k = 0; k < N; ++k )
619 position[k] = (x1[k] + x2[k]) * (T) 0.5;
637 f_evaluated[i] = f(position);
641 integral += volume * (t) * f_evaluated[i];
652 std::array<size_t, N> level;
653 std::array<size_t, N> index;
658 for(
size_t i = 0; i < twoN; ++i )
665 for(
size_t k = 0; k < N; ++k )
667 if( (i & (1<<k)) > 0 )
679 if( (ones == 0) || (ones == N) )
685 for(
size_t j = 0; j < twoN; ++j )
692 for(
size_t k = 0; k < N; ++k )
699 index[k] = (( j & (1<<k) ) >> k) * 2;
702 if( (level[k] == 1) && (index[k] == 2) )
719 integral += integral_aux_boundary( f, f_evaluated, x1, x2, volume, epsilon, level, index, N-1, refine, 0, depth_min, depth_max, gamma );
729 integral += integral_aux( f, f_evaluated, x1, x2, volume, epsilon, N-1, refine, 0, depth_min, depth_max, gamma );