Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/numeric/interval/examples/newton-raphson.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 4.1 KB
Line 
1/* Boost example/newton-raphson.cpp
2 * Newton iteration for intervals
3 *
4 * Copyright 2003 Guillaume Melquiond
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or
8 * copy at http://www.boost.org/LICENSE_1_0.txt)
9 */
10
11#include <boost/numeric/interval.hpp>
12#include <vector>
13#include <algorithm>
14#include <utility>
15#include <iostream>
16#include <iomanip>
17
18template <class I> I f(const I& x)
19{ return x * (x - 1.) * (x - 2.) * (x - 3.) * (x - 4.); }
20template <class I> I f_diff(const I& x)
21{ return (((5. * x - 40.) * x + 105.) * x - 100.) * x + 24.; }
22
23static const double max_width = 1e-10;
24static const double alpha = 0.75;
25
26using namespace boost;
27using namespace numeric;
28using namespace interval_lib;
29
30// First method: no empty intervals
31
32typedef interval<double> I1_aux;
33typedef unprotect<I1_aux>::type I1;
34
35std::vector<I1> newton_raphson(const I1& xs) {
36  std::vector<I1> l, res;
37  I1 vf, vd, x, x1, x2;
38  l.push_back(xs);
39  while (!l.empty()) {
40    x = l.back();
41    l.pop_back();
42    bool x2_used;
43    double xx = median(x);
44    vf = f<I1>(xx);
45    vd = f_diff<I1>(x);
46    if (in_zero(vf) && in_zero(vd)) {
47      x1 = I1::whole();
48      x2_used = false;
49    } else {
50      x1 = xx - division_part1(vf, vd, x2_used);
51      if (x2_used) x2 = xx - division_part2(vf, vd);
52    }
53    if (overlap(x1, x)) x1 = intersect(x, x1);
54    else if (x2_used) { x1 = x2; x2_used = false; }
55    else continue;
56    if (x2_used)
57      if (overlap(x2, x)) x2 = intersect(x, x2);
58      else x2_used = false;
59    if (x2_used && width(x2) > width(x1)) std::swap(x1, x2);
60    if (!in_zero(f(x1)))
61      if (x2_used) { x1 = x2; x2_used = false; }
62      else continue;
63    if (width(x1) < max_width) res.push_back(x1);
64    else if (width(x1) > alpha * width(x)) {
65      std::pair<I1, I1> p = bisect(x);
66      if (in_zero(f(p.first))) l.push_back(p.first);
67      x2 = p.second;
68      x2_used = true;
69    } else l.push_back(x1);
70    if (x2_used && in_zero(f(x2)))
71      if (width(x2) < max_width) res.push_back(x2);
72      else l.push_back(x2);
73  }
74  return res;
75}
76
77// Second method: with empty intervals
78
79typedef change_checking<I1_aux, checking_no_nan<double> >::type I2_aux;
80typedef unprotect<I2_aux>::type I2;
81
82std::vector<I2> newton_raphson(const I2& xs) {
83  std::vector<I2> l, res;
84  I2 vf, vd, x, x1, x2;
85  l.push_back(xs);
86  while (!l.empty()) {
87    x = l.back();
88    l.pop_back();
89    double xx = median(x);
90    vf = f<I2>(xx);
91    vd = f_diff<I2>(x);
92    if (in_zero(vf) && in_zero(vd)) {
93      x1 = x;
94      x2 = I2::empty();
95    } else {
96      bool x2_used;
97      x1 = intersect(x, xx - division_part1(vf, vd, x2_used));
98      x2 = intersect(x, xx - division_part2(vf, vd, x2_used));
99    }
100    if (width(x2) > width(x1)) std::swap(x1, x2);
101    if (empty(x1) || !in_zero(f(x1)))
102      if (!empty(x2)) { x1 = x2; x2 = I2::empty(); }
103      else continue;
104    if (width(x1) < max_width) res.push_back(x1);
105    else if (width(x1) > alpha * width(x)) {
106      std::pair<I2, I2> p = bisect(x);
107      if (in_zero(f(p.first))) l.push_back(p.first);
108      x2 = p.second;
109    } else l.push_back(x1);
110    if (!empty(x2) && in_zero(f(x2)))
111      if (width(x2) < max_width) res.push_back(x2);
112      else l.push_back(x2);
113  }
114  return res;
115}
116
117template<class T, class Policies>
118std::ostream &operator<<(std::ostream &os,
119                         const boost::numeric::interval<T, Policies> &x) {
120  os << "[" << x.lower() << ", " << x.upper() << "]";
121  return os;
122}
123
124int main() {
125  {
126    I1_aux::traits_type::rounding rnd;
127    std::vector<I1> res = newton_raphson(I1(-1, 5.1));
128    std::cout << "Results: " << std::endl << std::setprecision(12);
129    for(std::vector<I1>::const_iterator i = res.begin(); i != res.end(); ++i)
130      std::cout << "  " << *i << std::endl;
131    std::cout << std::endl;
132  }
133  {
134    I2_aux::traits_type::rounding rnd;
135    std::vector<I2> res = newton_raphson(I2(-1, 5.1));
136    std::cout << "Results: " << std::endl << std::setprecision(12);
137    for(std::vector<I2>::const_iterator i = res.begin(); i != res.end(); ++i)
138      std::cout << "  " << *i << std::endl;
139    std::cout << std::endl;
140  }
141}
Note: See TracBrowser for help on using the repository browser.