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 )
50 auto perform_refinement = [&] () -> T
54 if( (depth >= depth_max) || (level[dimension] == 0) )
61 for(
size_t i = 0; i < dimension; ++i )
67 std::array<T, Util::pow(3, N)> f_evaluated_l;
68 std::array<T, Util::pow(3, N)> f_evaluated_r;
70 size_t refinement_index = 0;
71 std::array<T, N> position;
74 for(
size_t i = 0; i < Util::pow<size_t>(3, N); ++i )
81 for(
size_t k = 0; k < N; ++k )
87 refinement_index = (tmp%3);
101 position[k] = (x1[k] + x2[k]) * (T) 0.5;
120 switch( refinement_index )
125 f_evaluated_l[i] = f_evaluated[i];
126 f_evaluated_r[i] = f_evaluated[i + stride];
132 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.25;
133 f_evaluated_l[i] = f(position);
135 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.75;
136 f_evaluated_r[i] = f(position);
141 f_evaluated_l[i] = f_evaluated[i - stride];
142 f_evaluated_r[i] = f_evaluated[i];
153 T correction = (T) 0.0;
156 bool refine2 =
false;
159 T center = (x1[dimension] + x2[dimension]) * (T) 0.5;
165 index[dimension] *= 2;
168 T tmp = x2[dimension];
169 x2[dimension] = center;
172 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 );
180 x1[dimension] = center;
183 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 );
190 index[dimension] /= 2;
204 T local_integral = integral_aux_boundary( f, f_evaluated, x1, x2, volume, epsilon, level, index, dimension-1, refine, depth, depth_min, depth_max, gamma );
210 local_integral += perform_refinement();
214 return local_integral;
226 for(
size_t i = 0; i < Util::pow<size_t>(3, N); ++i )
239 for(
size_t k = 0; k < N; ++k )
244 if( (level[k] == 0) && ( (tmp%3) != index[k] ) )
270 w += wcoeff * f_evaluated[i];
277 T local_integral = (Util::pow<T>(0.5, N) * volume) * w;
280 if( (depth < depth_min) || (Util::abs(w) > epsilon) )
282 local_integral += perform_refinement();
291 return local_integral;
324template <
typename T,
typename F,
size_t N>
325 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 )
331 auto perform_refinement = [&] () -> T
335 if( depth >= depth_max )
342 for(
size_t i = 0; i < dimension; ++i )
348 std::array<T, Util::pow(3, N)> f_evaluated_l;
349 std::array<T, Util::pow(3, N)> f_evaluated_r;
351 size_t refinement_index = 0;
352 std::array<T, N> position;
355 for(
size_t i = 0; i < Util::pow<size_t>(3, N); ++i )
362 for(
size_t k = 0; k < N; ++k )
367 refinement_index = (tmp%3);
381 position[k] = (x1[k] + x2[k]) * (T) 0.5;
400 switch( refinement_index )
405 f_evaluated_l[i] = f_evaluated[i];
406 f_evaluated_r[i] = f_evaluated[i + stride];
412 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.25;
413 f_evaluated_l[i] = f(position);
415 position[dimension] = x1[dimension] + (x2[dimension] - x1[dimension]) * (T) 0.75;
416 f_evaluated_r[i] = f(position);
421 f_evaluated_l[i] = f_evaluated[i - stride];
422 f_evaluated_r[i] = f_evaluated[i];
433 T correction = (T) 0.0;
436 bool refine2 =
false;
439 T center = (x1[dimension] + x2[dimension]) * (T) 0.5;
442 T tmp = x2[dimension];
443 x2[dimension] = center;
446 correction += integral_aux( f, f_evaluated_l, x1, x2, volume*(T)0.5, epsilon, dimension, refine2, depth+1, depth_min, depth_max, gamma );
451 x1[dimension] = center;
454 correction += integral_aux( f, f_evaluated_r, x1, x2, volume*(T)0.5, epsilon, dimension, refine2, depth+1, depth_min, depth_max, gamma );
467 T local_integral = integral_aux( f, f_evaluated, x1, x2, volume, epsilon, dimension-1, refine, depth, depth_min, depth_max, gamma );
473 local_integral += perform_refinement();
477 return local_integral;
489 for(
size_t i = 0; i < Util::pow<size_t>(3, N); ++i )
499 for(
size_t k = 0; k < N; ++k )
513 w += wcoeff * f_evaluated[i];
521 T local_integral = (Util::pow<T>(0.5, N)) * volume * w;
524 if( (depth < depth_min) || (Util::abs(w) > epsilon) )
526 local_integral += perform_refinement();
535 return local_integral;
561template <
typename T,
typename F,
size_t N>
562 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 )
566 T integral = (T) 0.0;
571 for(
size_t i = 0; i < N; ++i )
573 volume *= (x2[i] - x1[i]);
579 std::array<T, N> position;
580 std::array<T, Util::pow(3, N)> f_evaluated;
583 for(
size_t i = 0; i < Util::pow<size_t>(3, N); ++i )
586 bool boundary =
true;
591 for(
size_t k = 0; k < N; ++k )
603 position[k] = (x1[k] + x2[k]) * (T) 0.5;
621 f_evaluated[i] = f(position);
625 integral += volume * (Util::pow<T>(0.5, N)) * f_evaluated[i];
636 std::array<size_t, N> level;
637 std::array<size_t, N> index;
640 for(
size_t i = 0; i < Util::pow<size_t>(2, N); ++i )
647 for(
size_t k = 0; k < N; ++k )
649 if( (i & (1<<k)) > 0 )
661 if( (ones == 0) || (ones == N) )
667 for(
size_t j = 0; j < Util::pow<size_t>(2, N); ++j )
674 for(
size_t k = 0; k < N; ++k )
681 index[k] = (( j & (1<<k) ) >> k) * 2;
684 if( (level[k] == 1) && (index[k] == 2) )
699 integral += integral_aux_boundary( f, f_evaluated, x1, x2, volume, epsilon, level, index, N-1, refine, 0, depth_min, depth_max, gamma );
706 integral += integral_aux( f, f_evaluated, x1, x2, volume, epsilon, N-1, refine, 0, depth_min, depth_max, gamma );