| 267 | } // namespace interval_lib |
| 268 | |
| 269 | template< class T, class Policies > inline |
| 270 | interval<T, Policies> nth_root(interval<T, Policies> const &x, int k) |
| 271 | { |
| 272 | typedef interval<T, Policies> I; |
| 273 | if (interval_lib::detail::test_input(x)) return I::empty(); |
| 274 | assert(k > 0); |
| 275 | if (k == 1) return x; |
| 276 | typename Policies::rounding rnd; |
| 277 | typedef typename interval_lib::unprotect<I>::type R; |
| 278 | if (!interval_lib::user::is_pos(x.upper())) { |
| 279 | if (interval_lib::user::is_zero(x.upper())) { |
| 280 | T zero(0); |
| 281 | if (!(k & 1) || interval_lib::user::is_zero(x.lower())) // [-1,0]^/2 or [0,0] |
| 282 | return I(zero, zero, true); |
| 283 | else // [-1,0]^/3 |
| 284 | return I(-interval_lib::detail::root_aux_up<R>(-x.lower(), k), zero, true); |
| 285 | } else if (!(k & 1)) // [-2,-1]^/2 |
| 286 | return I::empty(); |
| 287 | else { // [-2,-1]^/3 |
| 288 | return I(-interval_lib::detail::root_aux_up<R>(-x.lower(), k), |
| 289 | -interval_lib::detail::root_aux_dn<R>(-x.upper(), k), true); |
| 290 | } |
| 291 | } |
| 292 | T u = interval_lib::detail::root_aux_up<R>(x.upper(), k); |
| 293 | if (!interval_lib::user::is_pos(x.lower())) |
| 294 | if (!(k & 1) || interval_lib::user::is_zero(x.lower())) // [-1,1]^/2 or [0,1] |
| 295 | return I(static_cast<T>(0), u, true); |
| 296 | else // [-1,1]^/3 |
| 297 | return I(-interval_lib::detail::root_aux_up<R>(-x.lower(), k), u, true); |
| 298 | else // [1,2] |
| 299 | return I(interval_lib::detail::root_aux_dn<R>(x.lower(), k), u, true); |
| 300 | } |
| 301 | |
| 302 | } // namespace numeric |
| 303 | } // namespace gecode_boost |