double root(double a, int n) { double d, x = 1; if (!a) return 0; if (n < 1 || (a < 0 && !(n&1))) return 0./0.; /* NaN */ do { d = (a / pow_(x, n - 1) - x) / n; x+= d; } while (abs_(d) >= abs_(x) * (DBL_EPSILON * 10)); return x; }
double pow_(double x, int n) { int flag = 0; double r; if (n == 0) return 1.; if (n == 1) return x; if (n < 0) { n = -n; flag = 1; } r = pow_(x, n/2); r = r*r; if (n%2==1) r *= x; if (flag == 1) return 1/r; return r; }
void test_pow_() { printf("%f\n", pow_(3,-2)); }
prod(LgM, rhs, M_AB); } }; auto M2M = [&](int L, const source_box_type& sbox) { const point_type& s_center = sbox.center(); const point_type s_scale = 1. / sbox.extents(); for (source_box_type cbox : children(sbox)) { const point_type& c_center = cbox.center(); const point_type& c_extent = cbox.extents(); // Define the child box chebyshev grid std::array<point_type,pow_(Q,D)> c_cheb; auto cbi = c_cheb.begin(); for (auto&& i : TensorIndexGridRange<D,Q>()) { for (unsigned d = 0; d < D; ++d) (*cbi)[d] = c_center[d] + Chebyshev<double,Q>::x[i[d]] * c_extent[d]; ++cbi; } // Precompute Lagrange interp matrix with points transformed to ref grid // XXX: Avoid computing at all for quad/octrees auto make_ref = [&](const point_type& c) { return (c - s_center) * s_scale; }; auto LgM = LagrangeMatrix<D,Q>( boost::make_transform_iterator(c_cheb.begin(), make_ref), boost::make_transform_iterator(c_cheb.end(), make_ref));