roots.hpp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. // (C) Copyright John Maddock 2006.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP
  6. #define BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP
  7. #ifdef _MSC_VER
  8. #pragma once
  9. #endif
  10. #include <boost/math/tools/complex.hpp> // test for multiprecision types in complex Newton
  11. #include <utility>
  12. #include <cmath>
  13. #include <tuple>
  14. #include <cstdint>
  15. #include <boost/math/tools/config.hpp>
  16. #include <boost/math/tools/cxx03_warn.hpp>
  17. #include <boost/math/special_functions/sign.hpp>
  18. #include <boost/math/special_functions/next.hpp>
  19. #include <boost/math/tools/toms748_solve.hpp>
  20. #include <boost/math/policies/error_handling.hpp>
  21. namespace boost {
  22. namespace math {
  23. namespace tools {
  24. namespace detail {
  25. namespace dummy {
  26. template<int n, class T>
  27. typename T::value_type get(const T&) BOOST_MATH_NOEXCEPT(T);
  28. }
  29. template <class Tuple, class T>
  30. void unpack_tuple(const Tuple& t, T& a, T& b) BOOST_MATH_NOEXCEPT(T)
  31. {
  32. using dummy::get;
  33. // Use ADL to find the right overload for get:
  34. a = get<0>(t);
  35. b = get<1>(t);
  36. }
  37. template <class Tuple, class T>
  38. void unpack_tuple(const Tuple& t, T& a, T& b, T& c) BOOST_MATH_NOEXCEPT(T)
  39. {
  40. using dummy::get;
  41. // Use ADL to find the right overload for get:
  42. a = get<0>(t);
  43. b = get<1>(t);
  44. c = get<2>(t);
  45. }
  46. template <class Tuple, class T>
  47. inline void unpack_0(const Tuple& t, T& val) BOOST_MATH_NOEXCEPT(T)
  48. {
  49. using dummy::get;
  50. // Rely on ADL to find the correct overload of get:
  51. val = get<0>(t);
  52. }
  53. template <class T, class U, class V>
  54. inline void unpack_tuple(const std::pair<T, U>& p, V& a, V& b) BOOST_MATH_NOEXCEPT(T)
  55. {
  56. a = p.first;
  57. b = p.second;
  58. }
  59. template <class T, class U, class V>
  60. inline void unpack_0(const std::pair<T, U>& p, V& a) BOOST_MATH_NOEXCEPT(T)
  61. {
  62. a = p.first;
  63. }
  64. template <class F, class T>
  65. void handle_zero_derivative(F f,
  66. T& last_f0,
  67. const T& f0,
  68. T& delta,
  69. T& result,
  70. T& guess,
  71. const T& min,
  72. const T& max) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  73. {
  74. if (last_f0 == 0)
  75. {
  76. // this must be the first iteration, pretend that we had a
  77. // previous one at either min or max:
  78. if (result == min)
  79. {
  80. guess = max;
  81. }
  82. else
  83. {
  84. guess = min;
  85. }
  86. unpack_0(f(guess), last_f0);
  87. delta = guess - result;
  88. }
  89. if (sign(last_f0) * sign(f0) < 0)
  90. {
  91. // we've crossed over so move in opposite direction to last step:
  92. if (delta < 0)
  93. {
  94. delta = (result - min) / 2;
  95. }
  96. else
  97. {
  98. delta = (result - max) / 2;
  99. }
  100. }
  101. else
  102. {
  103. // move in same direction as last step:
  104. if (delta < 0)
  105. {
  106. delta = (result - max) / 2;
  107. }
  108. else
  109. {
  110. delta = (result - min) / 2;
  111. }
  112. }
  113. }
  114. } // namespace
  115. template <class F, class T, class Tol, class Policy>
  116. std::pair<T, T> bisect(F f, T min, T max, Tol tol, std::uintmax_t& max_iter, const Policy& pol) noexcept(policies::is_noexcept_error_policy<Policy>::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  117. {
  118. T fmin = f(min);
  119. T fmax = f(max);
  120. if (fmin == 0)
  121. {
  122. max_iter = 2;
  123. return std::make_pair(min, min);
  124. }
  125. if (fmax == 0)
  126. {
  127. max_iter = 2;
  128. return std::make_pair(max, max);
  129. }
  130. //
  131. // Error checking:
  132. //
  133. static const char* function = "boost::math::tools::bisect<%1%>";
  134. if (min >= max)
  135. {
  136. return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function,
  137. "Arguments in wrong order in boost::math::tools::bisect (first arg=%1%)", min, pol));
  138. }
  139. if (fmin * fmax >= 0)
  140. {
  141. return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function,
  142. "No change of sign in boost::math::tools::bisect, either there is no root to find, or there are multiple roots in the interval (f(min) = %1%).", fmin, pol));
  143. }
  144. //
  145. // Three function invocations so far:
  146. //
  147. std::uintmax_t count = max_iter;
  148. if (count < 3)
  149. count = 0;
  150. else
  151. count -= 3;
  152. while (count && (0 == tol(min, max)))
  153. {
  154. T mid = (min + max) / 2;
  155. T fmid = f(mid);
  156. if ((mid == max) || (mid == min))
  157. break;
  158. if (fmid == 0)
  159. {
  160. min = max = mid;
  161. break;
  162. }
  163. else if (sign(fmid) * sign(fmin) < 0)
  164. {
  165. max = mid;
  166. }
  167. else
  168. {
  169. min = mid;
  170. fmin = fmid;
  171. }
  172. --count;
  173. }
  174. max_iter -= count;
  175. #ifdef BOOST_MATH_INSTRUMENT
  176. std::cout << "Bisection required " << max_iter << " iterations.\n";
  177. #endif
  178. return std::make_pair(min, max);
  179. }
  180. template <class F, class T, class Tol>
  181. inline std::pair<T, T> bisect(F f, T min, T max, Tol tol, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  182. {
  183. return bisect(f, min, max, tol, max_iter, policies::policy<>());
  184. }
  185. template <class F, class T, class Tol>
  186. inline std::pair<T, T> bisect(F f, T min, T max, Tol tol) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  187. {
  188. std::uintmax_t m = (std::numeric_limits<std::uintmax_t>::max)();
  189. return bisect(f, min, max, tol, m, policies::policy<>());
  190. }
  191. template <class F, class T>
  192. T newton_raphson_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  193. {
  194. BOOST_MATH_STD_USING
  195. static const char* function = "boost::math::tools::newton_raphson_iterate<%1%>";
  196. if (min > max)
  197. {
  198. return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::newton_raphson_iterate(first arg=%1%)", min, boost::math::policies::policy<>());
  199. }
  200. T f0(0), f1, last_f0(0);
  201. T result = guess;
  202. T factor = static_cast<T>(ldexp(1.0, 1 - digits));
  203. T delta = tools::max_value<T>();
  204. T delta1 = tools::max_value<T>();
  205. T delta2 = tools::max_value<T>();
  206. //
  207. // We use these to sanity check that we do actually bracket a root,
  208. // we update these to the function value when we update the endpoints
  209. // of the range. Then, provided at some point we update both endpoints
  210. // checking that max_range_f * min_range_f <= 0 verifies there is a root
  211. // to be found somewhere. Note that if there is no root, and we approach
  212. // a local minima, then the derivative will go to zero, and hence the next
  213. // step will jump out of bounds (or at least past the minima), so this
  214. // check *should* happen in pathological cases.
  215. //
  216. T max_range_f = 0;
  217. T min_range_f = 0;
  218. std::uintmax_t count(max_iter);
  219. #ifdef BOOST_MATH_INSTRUMENT
  220. std::cout << "Newton_raphson_iterate, guess = " << guess << ", min = " << min << ", max = " << max
  221. << ", digits = " << digits << ", max_iter = " << max_iter << "\n";
  222. #endif
  223. do {
  224. last_f0 = f0;
  225. delta2 = delta1;
  226. delta1 = delta;
  227. detail::unpack_tuple(f(result), f0, f1);
  228. --count;
  229. if (0 == f0)
  230. break;
  231. if (f1 == 0)
  232. {
  233. // Oops zero derivative!!!
  234. detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max);
  235. }
  236. else
  237. {
  238. delta = f0 / f1;
  239. }
  240. #ifdef BOOST_MATH_INSTRUMENT
  241. std::cout << "Newton iteration " << max_iter - count << ", delta = " << delta << ", residual = " << f0 << "\n";
  242. #endif
  243. if (fabs(delta * 2) > fabs(delta2))
  244. {
  245. // Last two steps haven't converged.
  246. T shift = (delta > 0) ? (result - min) / 2 : (result - max) / 2;
  247. if ((result != 0) && (fabs(shift) > fabs(result)))
  248. {
  249. delta = sign(delta) * fabs(result); // protect against huge jumps!
  250. }
  251. else
  252. delta = shift;
  253. // reset delta1/2 so we don't take this branch next time round:
  254. delta1 = 3 * delta;
  255. delta2 = 3 * delta;
  256. }
  257. guess = result;
  258. result -= delta;
  259. if (result <= min)
  260. {
  261. delta = 0.5F * (guess - min);
  262. result = guess - delta;
  263. if ((result == min) || (result == max))
  264. break;
  265. }
  266. else if (result >= max)
  267. {
  268. delta = 0.5F * (guess - max);
  269. result = guess - delta;
  270. if ((result == min) || (result == max))
  271. break;
  272. }
  273. // Update brackets:
  274. if (delta > 0)
  275. {
  276. max = guess;
  277. max_range_f = f0;
  278. }
  279. else
  280. {
  281. min = guess;
  282. min_range_f = f0;
  283. }
  284. //
  285. // Sanity check that we bracket the root:
  286. //
  287. if (max_range_f * min_range_f > 0)
  288. {
  289. return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>());
  290. }
  291. }while(count && (fabs(result * factor) < fabs(delta)));
  292. max_iter -= count;
  293. #ifdef BOOST_MATH_INSTRUMENT
  294. std::cout << "Newton Raphson required " << max_iter << " iterations\n";
  295. #endif
  296. return result;
  297. }
  298. template <class F, class T>
  299. inline T newton_raphson_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  300. {
  301. std::uintmax_t m = (std::numeric_limits<std::uintmax_t>::max)();
  302. return newton_raphson_iterate(f, guess, min, max, digits, m);
  303. }
  304. namespace detail {
  305. struct halley_step
  306. {
  307. template <class T>
  308. static T step(const T& /*x*/, const T& f0, const T& f1, const T& f2) noexcept(BOOST_MATH_IS_FLOAT(T))
  309. {
  310. using std::fabs;
  311. T denom = 2 * f0;
  312. T num = 2 * f1 - f0 * (f2 / f1);
  313. T delta;
  314. BOOST_MATH_INSTRUMENT_VARIABLE(denom);
  315. BOOST_MATH_INSTRUMENT_VARIABLE(num);
  316. if ((fabs(num) < 1) && (fabs(denom) >= fabs(num) * tools::max_value<T>()))
  317. {
  318. // possible overflow, use Newton step:
  319. delta = f0 / f1;
  320. }
  321. else
  322. delta = denom / num;
  323. return delta;
  324. }
  325. };
  326. template <class F, class T>
  327. T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())));
  328. template <class F, class T>
  329. T bracket_root_towards_max(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  330. {
  331. using std::fabs;
  332. using std::ldexp;
  333. using std::abs;
  334. using std::frexp;
  335. if(count < 2)
  336. return guess - (max + min) / 2; // Not enough counts left to do anything!!
  337. //
  338. // Move guess towards max until we bracket the root, updating min and max as we go:
  339. //
  340. int e;
  341. frexp(max / guess, &e);
  342. e = abs(e);
  343. T guess0 = guess;
  344. T multiplier = e < 64 ? static_cast<T>(2) : static_cast<T>(ldexp(T(1), e / 32));
  345. T f_current = f0;
  346. if (fabs(min) < fabs(max))
  347. {
  348. while (--count && ((f_current < 0) == (f0 < 0)))
  349. {
  350. min = guess;
  351. guess *= multiplier;
  352. if (guess > max)
  353. {
  354. guess = max;
  355. f_current = -f_current; // There must be a change of sign!
  356. break;
  357. }
  358. multiplier *= e > 1024 ? 8 : 2;
  359. unpack_0(f(guess), f_current);
  360. }
  361. }
  362. else
  363. {
  364. //
  365. // If min and max are negative we have to divide to head towards max:
  366. //
  367. while (--count && ((f_current < 0) == (f0 < 0)))
  368. {
  369. min = guess;
  370. guess /= multiplier;
  371. if (guess > max)
  372. {
  373. guess = max;
  374. f_current = -f_current; // There must be a change of sign!
  375. break;
  376. }
  377. multiplier *= e > 1024 ? 8 : 2;
  378. unpack_0(f(guess), f_current);
  379. }
  380. }
  381. if (count)
  382. {
  383. max = guess;
  384. if (multiplier > 16)
  385. return (guess0 - guess) + bracket_root_towards_min(f, guess, f_current, min, max, count);
  386. }
  387. return guess0 - (max + min) / 2;
  388. }
  389. template <class F, class T>
  390. T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  391. {
  392. using std::fabs;
  393. using std::ldexp;
  394. using std::abs;
  395. using std::frexp;
  396. if (count < 2)
  397. return guess - (max + min) / 2; // Not enough counts left to do anything!!
  398. //
  399. // Move guess towards min until we bracket the root, updating min and max as we go:
  400. //
  401. int e;
  402. frexp(guess / min, &e);
  403. e = abs(e);
  404. T guess0 = guess;
  405. T multiplier = e < 64 ? static_cast<T>(2) : static_cast<T>(ldexp(T(1), e / 32));
  406. T f_current = f0;
  407. if (fabs(min) < fabs(max))
  408. {
  409. while (--count && ((f_current < 0) == (f0 < 0)))
  410. {
  411. max = guess;
  412. guess /= multiplier;
  413. if (guess < min)
  414. {
  415. guess = min;
  416. f_current = -f_current; // There must be a change of sign!
  417. break;
  418. }
  419. multiplier *= e > 1024 ? 8 : 2;
  420. unpack_0(f(guess), f_current);
  421. }
  422. }
  423. else
  424. {
  425. //
  426. // If min and max are negative we have to multiply to head towards min:
  427. //
  428. while (--count && ((f_current < 0) == (f0 < 0)))
  429. {
  430. max = guess;
  431. guess *= multiplier;
  432. if (guess < min)
  433. {
  434. guess = min;
  435. f_current = -f_current; // There must be a change of sign!
  436. break;
  437. }
  438. multiplier *= e > 1024 ? 8 : 2;
  439. unpack_0(f(guess), f_current);
  440. }
  441. }
  442. if (count)
  443. {
  444. min = guess;
  445. if (multiplier > 16)
  446. return (guess0 - guess) + bracket_root_towards_max(f, guess, f_current, min, max, count);
  447. }
  448. return guess0 - (max + min) / 2;
  449. }
  450. template <class Stepper, class F, class T>
  451. T second_order_root_finder(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  452. {
  453. BOOST_MATH_STD_USING
  454. #ifdef BOOST_MATH_INSTRUMENT
  455. std::cout << "Second order root iteration, guess = " << guess << ", min = " << min << ", max = " << max
  456. << ", digits = " << digits << ", max_iter = " << max_iter << "\n";
  457. #endif
  458. static const char* function = "boost::math::tools::halley_iterate<%1%>";
  459. if (min >= max)
  460. {
  461. return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::halley_iterate(first arg=%1%)", min, boost::math::policies::policy<>());
  462. }
  463. T f0(0), f1, f2;
  464. T result = guess;
  465. T factor = ldexp(static_cast<T>(1.0), 1 - digits);
  466. T delta = (std::max)(T(10000000 * guess), T(10000000)); // arbitrarily large delta
  467. T last_f0 = 0;
  468. T delta1 = delta;
  469. T delta2 = delta;
  470. bool out_of_bounds_sentry = false;
  471. #ifdef BOOST_MATH_INSTRUMENT
  472. std::cout << "Second order root iteration, limit = " << factor << "\n";
  473. #endif
  474. //
  475. // We use these to sanity check that we do actually bracket a root,
  476. // we update these to the function value when we update the endpoints
  477. // of the range. Then, provided at some point we update both endpoints
  478. // checking that max_range_f * min_range_f <= 0 verifies there is a root
  479. // to be found somewhere. Note that if there is no root, and we approach
  480. // a local minima, then the derivative will go to zero, and hence the next
  481. // step will jump out of bounds (or at least past the minima), so this
  482. // check *should* happen in pathological cases.
  483. //
  484. T max_range_f = 0;
  485. T min_range_f = 0;
  486. std::uintmax_t count(max_iter);
  487. do {
  488. last_f0 = f0;
  489. delta2 = delta1;
  490. delta1 = delta;
  491. #ifndef BOOST_MATH_NO_EXCEPTIONS
  492. try
  493. #endif
  494. {
  495. detail::unpack_tuple(f(result), f0, f1, f2);
  496. }
  497. #ifndef BOOST_MATH_NO_EXCEPTIONS
  498. catch (const std::overflow_error&)
  499. {
  500. f0 = max > 0 ? tools::max_value<T>() : -tools::min_value<T>();
  501. f1 = f2 = 0;
  502. }
  503. #endif
  504. --count;
  505. BOOST_MATH_INSTRUMENT_VARIABLE(f0);
  506. BOOST_MATH_INSTRUMENT_VARIABLE(f1);
  507. BOOST_MATH_INSTRUMENT_VARIABLE(f2);
  508. if (0 == f0)
  509. break;
  510. if (f1 == 0)
  511. {
  512. // Oops zero derivative!!!
  513. detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max);
  514. }
  515. else
  516. {
  517. if (f2 != 0)
  518. {
  519. delta = Stepper::step(result, f0, f1, f2);
  520. if (delta * f1 / f0 < 0)
  521. {
  522. // Oh dear, we have a problem as Newton and Halley steps
  523. // disagree about which way we should move. Probably
  524. // there is cancelation error in the calculation of the
  525. // Halley step, or else the derivatives are so small
  526. // that their values are basically trash. We will move
  527. // in the direction indicated by a Newton step, but
  528. // by no more than twice the current guess value, otherwise
  529. // we can jump way out of bounds if we're not careful.
  530. // See https://svn.boost.org/trac/boost/ticket/8314.
  531. delta = f0 / f1;
  532. if (fabs(delta) > 2 * fabs(result))
  533. delta = (delta < 0 ? -1 : 1) * 2 * fabs(result);
  534. }
  535. }
  536. else
  537. delta = f0 / f1;
  538. }
  539. #ifdef BOOST_MATH_INSTRUMENT
  540. std::cout << "Second order root iteration, delta = " << delta << ", residual = " << f0 << "\n";
  541. #endif
  542. // We need to avoid delta/delta2 overflowing here:
  543. T convergence = (fabs(delta2) > 1) || (fabs(tools::max_value<T>() * delta2) > fabs(delta)) ? fabs(delta / delta2) : tools::max_value<T>();
  544. if ((convergence > 0.8) && (convergence < 2))
  545. {
  546. // last two steps haven't converged.
  547. if (fabs(min) < 1 ? fabs(1000 * min) < fabs(max) : fabs(max / min) > 1000)
  548. {
  549. if(delta > 0)
  550. delta = bracket_root_towards_min(f, result, f0, min, max, count);
  551. else
  552. delta = bracket_root_towards_max(f, result, f0, min, max, count);
  553. }
  554. else
  555. {
  556. delta = (delta > 0) ? (result - min) / 2 : (result - max) / 2;
  557. if ((result != 0) && (fabs(delta) > result))
  558. delta = sign(delta) * fabs(result) * 0.9f; // protect against huge jumps!
  559. }
  560. // reset delta2 so that this branch will *not* be taken on the
  561. // next iteration:
  562. delta2 = delta * 3;
  563. delta1 = delta * 3;
  564. BOOST_MATH_INSTRUMENT_VARIABLE(delta);
  565. }
  566. guess = result;
  567. result -= delta;
  568. BOOST_MATH_INSTRUMENT_VARIABLE(result);
  569. // check for out of bounds step:
  570. if (result < min)
  571. {
  572. T diff = ((fabs(min) < 1) && (fabs(result) > 1) && (tools::max_value<T>() / fabs(result) < fabs(min)))
  573. ? T(1000)
  574. : (fabs(min) < 1) && (fabs(tools::max_value<T>() * min) < fabs(result))
  575. ? ((min < 0) != (result < 0)) ? -tools::max_value<T>() : tools::max_value<T>() : T(result / min);
  576. if (fabs(diff) < 1)
  577. diff = 1 / diff;
  578. if (!out_of_bounds_sentry && (diff > 0) && (diff < 3))
  579. {
  580. // Only a small out of bounds step, lets assume that the result
  581. // is probably approximately at min:
  582. delta = 0.99f * (guess - min);
  583. result = guess - delta;
  584. out_of_bounds_sentry = true; // only take this branch once!
  585. }
  586. else
  587. {
  588. if (fabs(float_distance(min, max)) < 2)
  589. {
  590. result = guess = (min + max) / 2;
  591. break;
  592. }
  593. delta = bracket_root_towards_min(f, guess, f0, min, max, count);
  594. result = guess - delta;
  595. if (result <= min)
  596. result = float_next(min);
  597. if (result >= max)
  598. result = float_prior(max);
  599. guess = min;
  600. continue;
  601. }
  602. }
  603. else if (result > max)
  604. {
  605. T diff = ((fabs(max) < 1) && (fabs(result) > 1) && (tools::max_value<T>() / fabs(result) < fabs(max))) ? T(1000) : T(result / max);
  606. if (fabs(diff) < 1)
  607. diff = 1 / diff;
  608. if (!out_of_bounds_sentry && (diff > 0) && (diff < 3))
  609. {
  610. // Only a small out of bounds step, lets assume that the result
  611. // is probably approximately at min:
  612. delta = 0.99f * (guess - max);
  613. result = guess - delta;
  614. out_of_bounds_sentry = true; // only take this branch once!
  615. }
  616. else
  617. {
  618. if (fabs(float_distance(min, max)) < 2)
  619. {
  620. result = guess = (min + max) / 2;
  621. break;
  622. }
  623. delta = bracket_root_towards_max(f, guess, f0, min, max, count);
  624. result = guess - delta;
  625. if (result >= max)
  626. result = float_prior(max);
  627. if (result <= min)
  628. result = float_next(min);
  629. guess = min;
  630. continue;
  631. }
  632. }
  633. // update brackets:
  634. if (delta > 0)
  635. {
  636. max = guess;
  637. max_range_f = f0;
  638. }
  639. else
  640. {
  641. min = guess;
  642. min_range_f = f0;
  643. }
  644. //
  645. // Sanity check that we bracket the root:
  646. //
  647. if (max_range_f * min_range_f > 0)
  648. {
  649. return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>());
  650. }
  651. } while(count && (fabs(result * factor) < fabs(delta)));
  652. max_iter -= count;
  653. #ifdef BOOST_MATH_INSTRUMENT
  654. std::cout << "Second order root finder required " << max_iter << " iterations.\n";
  655. #endif
  656. return result;
  657. }
  658. } // T second_order_root_finder
  659. template <class F, class T>
  660. T halley_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  661. {
  662. return detail::second_order_root_finder<detail::halley_step>(f, guess, min, max, digits, max_iter);
  663. }
  664. template <class F, class T>
  665. inline T halley_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  666. {
  667. std::uintmax_t m = (std::numeric_limits<std::uintmax_t>::max)();
  668. return halley_iterate(f, guess, min, max, digits, m);
  669. }
  670. namespace detail {
  671. struct schroder_stepper
  672. {
  673. template <class T>
  674. static T step(const T& x, const T& f0, const T& f1, const T& f2) noexcept(BOOST_MATH_IS_FLOAT(T))
  675. {
  676. using std::fabs;
  677. T ratio = f0 / f1;
  678. T delta;
  679. if ((x != 0) && (fabs(ratio / x) < 0.1))
  680. {
  681. delta = ratio + (f2 / (2 * f1)) * ratio * ratio;
  682. // check second derivative doesn't over compensate:
  683. if (delta * ratio < 0)
  684. delta = ratio;
  685. }
  686. else
  687. delta = ratio; // fall back to Newton iteration.
  688. return delta;
  689. }
  690. };
  691. }
  692. template <class F, class T>
  693. T schroder_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  694. {
  695. return detail::second_order_root_finder<detail::schroder_stepper>(f, guess, min, max, digits, max_iter);
  696. }
  697. template <class F, class T>
  698. inline T schroder_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  699. {
  700. std::uintmax_t m = (std::numeric_limits<std::uintmax_t>::max)();
  701. return schroder_iterate(f, guess, min, max, digits, m);
  702. }
  703. //
  704. // These two are the old spelling of this function, retained for backwards compatibility just in case:
  705. //
  706. template <class F, class T>
  707. T schroeder_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  708. {
  709. return detail::second_order_root_finder<detail::schroder_stepper>(f, guess, min, max, digits, max_iter);
  710. }
  711. template <class F, class T>
  712. inline T schroeder_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
  713. {
  714. std::uintmax_t m = (std::numeric_limits<std::uintmax_t>::max)();
  715. return schroder_iterate(f, guess, min, max, digits, m);
  716. }
  717. #ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS
  718. /*
  719. * Why do we set the default maximum number of iterations to the number of digits in the type?
  720. * Because for double roots, the number of digits increases linearly with the number of iterations,
  721. * so this default should recover full precision even in this somewhat pathological case.
  722. * For isolated roots, the problem is so rapidly convergent that this doesn't matter at all.
  723. */
  724. template<class ComplexType, class F>
  725. ComplexType complex_newton(F g, ComplexType guess, int max_iterations = std::numeric_limits<typename ComplexType::value_type>::digits)
  726. {
  727. typedef typename ComplexType::value_type Real;
  728. using std::norm;
  729. using std::abs;
  730. using std::max;
  731. // z0, z1, and z2 cannot be the same, in case we immediately need to resort to Muller's Method:
  732. ComplexType z0 = guess + ComplexType(1, 0);
  733. ComplexType z1 = guess + ComplexType(0, 1);
  734. ComplexType z2 = guess;
  735. do {
  736. auto pair = g(z2);
  737. if (norm(pair.second) == 0)
  738. {
  739. // Muller's method. Notation follows Numerical Recipes, 9.5.2:
  740. ComplexType q = (z2 - z1) / (z1 - z0);
  741. auto P0 = g(z0);
  742. auto P1 = g(z1);
  743. ComplexType qp1 = static_cast<ComplexType>(1) + q;
  744. ComplexType A = q * (pair.first - qp1 * P1.first + q * P0.first);
  745. ComplexType B = (static_cast<ComplexType>(2) * q + static_cast<ComplexType>(1)) * pair.first - qp1 * qp1 * P1.first + q * q * P0.first;
  746. ComplexType C = qp1 * pair.first;
  747. ComplexType rad = sqrt(B * B - static_cast<ComplexType>(4) * A * C);
  748. ComplexType denom1 = B + rad;
  749. ComplexType denom2 = B - rad;
  750. ComplexType correction = (z1 - z2) * static_cast<ComplexType>(2) * C;
  751. if (norm(denom1) > norm(denom2))
  752. {
  753. correction /= denom1;
  754. }
  755. else
  756. {
  757. correction /= denom2;
  758. }
  759. z0 = z1;
  760. z1 = z2;
  761. z2 = z2 + correction;
  762. }
  763. else
  764. {
  765. z0 = z1;
  766. z1 = z2;
  767. z2 = z2 - (pair.first / pair.second);
  768. }
  769. // See: https://math.stackexchange.com/questions/3017766/constructing-newton-iteration-converging-to-non-root
  770. // If f' is continuous, then convergence of x_n -> x* implies f(x*) = 0.
  771. // This condition approximates this convergence condition by requiring three consecutive iterates to be clustered.
  772. Real tol = (max)(abs(z2) * std::numeric_limits<Real>::epsilon(), std::numeric_limits<Real>::epsilon());
  773. bool real_close = abs(z0.real() - z1.real()) < tol && abs(z0.real() - z2.real()) < tol && abs(z1.real() - z2.real()) < tol;
  774. bool imag_close = abs(z0.imag() - z1.imag()) < tol && abs(z0.imag() - z2.imag()) < tol && abs(z1.imag() - z2.imag()) < tol;
  775. if (real_close && imag_close)
  776. {
  777. return z2;
  778. }
  779. } while (max_iterations--);
  780. // The idea is that if we can get abs(f) < eps, we should, but if we go through all these iterations
  781. // and abs(f) < sqrt(eps), then roundoff error simply does not allow that we can evaluate f to < eps
  782. // This is somewhat awkward as it isn't scale invariant, but using the Daubechies coefficient example code,
  783. // I found this condition generates correct roots, whereas the scale invariant condition discussed here:
  784. // https://scicomp.stackexchange.com/questions/30597/defining-a-condition-number-and-termination-criteria-for-newtons-method
  785. // allows nonroots to be passed off as roots.
  786. auto pair = g(z2);
  787. if (abs(pair.first) < sqrt(std::numeric_limits<Real>::epsilon()))
  788. {
  789. return z2;
  790. }
  791. return { std::numeric_limits<Real>::quiet_NaN(),
  792. std::numeric_limits<Real>::quiet_NaN() };
  793. }
  794. #endif
  795. #if !defined(BOOST_MATH_NO_CXX17_IF_CONSTEXPR)
  796. // https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711
  797. namespace detail
  798. {
  799. #if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1)
  800. inline float fma_workaround(float x, float y, float z) { return ::fmaf(x, y, z); }
  801. inline double fma_workaround(double x, double y, double z) { return ::fma(x, y, z); }
  802. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  803. inline long double fma_workaround(long double x, long double y, long double z) { return ::fmal(x, y, z); }
  804. #endif
  805. #endif
  806. template<class T>
  807. inline T discriminant(T const& a, T const& b, T const& c)
  808. {
  809. T w = 4 * a * c;
  810. #if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1)
  811. T e = fma_workaround(-c, 4 * a, w);
  812. T f = fma_workaround(b, b, -w);
  813. #else
  814. T e = std::fma(-c, 4 * a, w);
  815. T f = std::fma(b, b, -w);
  816. #endif
  817. return f + e;
  818. }
  819. template<class T>
  820. std::pair<T, T> quadratic_roots_imp(T const& a, T const& b, T const& c)
  821. {
  822. #if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1)
  823. using boost::math::copysign;
  824. #else
  825. using std::copysign;
  826. #endif
  827. using std::sqrt;
  828. if constexpr (std::is_floating_point<T>::value)
  829. {
  830. T nan = std::numeric_limits<T>::quiet_NaN();
  831. if (a == 0)
  832. {
  833. if (b == 0 && c != 0)
  834. {
  835. return std::pair<T, T>(nan, nan);
  836. }
  837. else if (b == 0 && c == 0)
  838. {
  839. return std::pair<T, T>(0, 0);
  840. }
  841. return std::pair<T, T>(-c / b, -c / b);
  842. }
  843. if (b == 0)
  844. {
  845. T x0_sq = -c / a;
  846. if (x0_sq < 0) {
  847. return std::pair<T, T>(nan, nan);
  848. }
  849. T x0 = sqrt(x0_sq);
  850. return std::pair<T, T>(-x0, x0);
  851. }
  852. T discriminant = detail::discriminant(a, b, c);
  853. // Is there a sane way to flush very small negative values to zero?
  854. // If there is I don't know of it.
  855. if (discriminant < 0)
  856. {
  857. return std::pair<T, T>(nan, nan);
  858. }
  859. T q = -(b + copysign(sqrt(discriminant), b)) / T(2);
  860. T x0 = q / a;
  861. T x1 = c / q;
  862. if (x0 < x1)
  863. {
  864. return std::pair<T, T>(x0, x1);
  865. }
  866. return std::pair<T, T>(x1, x0);
  867. }
  868. else if constexpr (boost::math::tools::is_complex_type<T>::value)
  869. {
  870. typename T::value_type nan = std::numeric_limits<typename T::value_type>::quiet_NaN();
  871. if (a.real() == 0 && a.imag() == 0)
  872. {
  873. using std::norm;
  874. if (b.real() == 0 && b.imag() && norm(c) != 0)
  875. {
  876. return std::pair<T, T>({ nan, nan }, { nan, nan });
  877. }
  878. else if (b.real() == 0 && b.imag() && c.real() == 0 && c.imag() == 0)
  879. {
  880. return std::pair<T, T>({ 0,0 }, { 0,0 });
  881. }
  882. return std::pair<T, T>(-c / b, -c / b);
  883. }
  884. if (b.real() == 0 && b.imag() == 0)
  885. {
  886. T x0_sq = -c / a;
  887. T x0 = sqrt(x0_sq);
  888. return std::pair<T, T>(-x0, x0);
  889. }
  890. // There's no fma for complex types:
  891. T discriminant = b * b - T(4) * a * c;
  892. T q = -(b + sqrt(discriminant)) / T(2);
  893. return std::pair<T, T>(q / a, c / q);
  894. }
  895. else // Most likely the type is a boost.multiprecision.
  896. { //There is no fma for multiprecision, and in addition it doesn't seem to be useful, so revert to the naive computation.
  897. T nan = std::numeric_limits<T>::quiet_NaN();
  898. if (a == 0)
  899. {
  900. if (b == 0 && c != 0)
  901. {
  902. return std::pair<T, T>(nan, nan);
  903. }
  904. else if (b == 0 && c == 0)
  905. {
  906. return std::pair<T, T>(0, 0);
  907. }
  908. return std::pair<T, T>(-c / b, -c / b);
  909. }
  910. if (b == 0)
  911. {
  912. T x0_sq = -c / a;
  913. if (x0_sq < 0) {
  914. return std::pair<T, T>(nan, nan);
  915. }
  916. T x0 = sqrt(x0_sq);
  917. return std::pair<T, T>(-x0, x0);
  918. }
  919. T discriminant = b * b - 4 * a * c;
  920. if (discriminant < 0)
  921. {
  922. return std::pair<T, T>(nan, nan);
  923. }
  924. T q = -(b + copysign(sqrt(discriminant), b)) / T(2);
  925. T x0 = q / a;
  926. T x1 = c / q;
  927. if (x0 < x1)
  928. {
  929. return std::pair<T, T>(x0, x1);
  930. }
  931. return std::pair<T, T>(x1, x0);
  932. }
  933. }
  934. } // namespace detail
  935. template<class T1, class T2 = T1, class T3 = T1>
  936. inline std::pair<typename tools::promote_args<T1, T2, T3>::type, typename tools::promote_args<T1, T2, T3>::type> quadratic_roots(T1 const& a, T2 const& b, T3 const& c)
  937. {
  938. typedef typename tools::promote_args<T1, T2, T3>::type value_type;
  939. return detail::quadratic_roots_imp(static_cast<value_type>(a), static_cast<value_type>(b), static_cast<value_type>(c));
  940. }
  941. #endif
  942. } // namespace tools
  943. } // namespace math
  944. } // namespace boost
  945. #endif // BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP