Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/numeric/interval/examples/findroot_demo.cpp @ 30

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

updated boost from 1_33_1 to 1_34_1

File size: 5.2 KB
Line 
1/* Boost example/findroot_demo.cpp
2 * find zero points of some function by dichotomy
3 *
4 * Copyright 2000 Jens Maurer
5 * Copyright 2002-2003 Guillaume Melquiond
6 *
7 * Distributed under the Boost Software License, Version 1.0.
8 * (See accompanying file LICENSE_1_0.txt or
9 * copy at http://www.boost.org/LICENSE_1_0.txt)
10 *
11 * The idea and the 2D function are based on RVInterval,
12 * which contains the following copyright notice:
13
14        This file is copyrighted 1996 by Ronald Van Iwaarden.
15
16        Permission is hereby granted, without written agreement and
17        without license or royalty fees, to use, copy, modify, and
18        distribute this software and its documentation for any
19        purpose, subject to the following conditions:
20       
21        The above license notice and this permission notice shall
22        appear in all copies or substantial portions of this software.
23       
24        The name "RVInterval" cannot be used for any modified form of
25        this software that does not originate from the authors.
26        Nevertheless, the name "RVInterval" may and should be used to
27        designate the optimization software implemented and described
28        in this package, even if embedded in any other system, as long
29        as any portion of this code remains.
30       
31        The authors specifically disclaim any warranties, including,
32        but not limited to, the implied warranties of merchantability
33        and fitness for a particular purpose.  The software provided
34        hereunder is on an "as is" basis, and the authors have no
35        obligation to provide maintenance, support, updates,
36        enhancements, or modifications.  In no event shall the authors
37        be liable to any party for direct, indirect, special,
38        incidental, or consequential damages arising out of the use of
39        this software and its documentation.     
40*/
41
42#include <boost/numeric/interval.hpp>    // must be first for <limits> workaround
43#include <list>
44#include <deque>
45#include <vector>
46#include <fstream>
47#include <iostream>
48
49
50template<class T>
51struct test_func2d
52{
53  T operator()(T x, T y) const
54  {
55    return sin(x)*cos(y) - exp(x*y)/45.0 * (pow(x+y, 2)+100.0) - 
56      cos(sin(y))*y/4.0;
57  }
58};
59
60template <class T>
61struct test_func1d
62{
63  T operator()(T x) const
64  {
65    return sin(x)/(x*x+1.0);
66  }
67};
68
69template<class T>
70struct test_func1d_2
71{
72  T operator()(T x) const
73  {
74    using std::sqrt;
75    return sqrt(x*x-1.0);
76  }
77};
78
79template<class Function, class I>
80void find_zeros(std::ostream & os, Function f, I searchrange)
81{
82  std::list<I> l, done;
83  l.push_back(searchrange);
84  while(!l.empty()) {
85    I range = l.front();
86    l.pop_front();
87    I val = f(range);
88    if (zero_in(val)) {
89      if(width(range) < 1e-6) {
90        os << range << '\n';
91        continue;
92      }
93      // there's still a solution hidden somewhere
94      std::pair<I,I> p = bisect(range);
95      l.push_back(p.first);
96      l.push_back(p.second);
97    }
98  }
99}
100
101template<class T>
102std::ostream &operator<<(std::ostream &os, const std::pair<T, T> &x) {
103  os << "(" << x.first << ", " << x.second << ")";
104  return os;
105}
106
107template<class T, class Policies>
108std::ostream &operator<<(std::ostream &os,
109                         const boost::numeric::interval<T, Policies> &x) {
110  os << "[" << x.lower() << ", " << x.upper() << "]";
111  return os;
112}
113
114static const double epsilon = 5e-3;
115
116template<class Function, class I>
117void find_zeros(std::ostream & os, Function f, I rx, I ry)
118{
119  typedef std::pair<I, I> rectangle;
120  typedef std::deque<rectangle> container;
121  container l, done;
122  // l.reserve(50);
123  l.push_back(std::make_pair(rx, ry));
124  for(int i = 1; !l.empty(); ++i) {
125    rectangle rect = l.front();
126    l.pop_front();
127    I val = f(rect.first, rect.second);
128    if (zero_in(val)) {
129      if(width(rect.first) < epsilon && width(rect.second) < epsilon) {
130        os << median(rect.first) << " " << median(rect.second) << " "
131           << lower(rect.first) << " " << upper(rect.first) << " "
132           << lower(rect.second) << " " << upper(rect.second) 
133           << '\n';
134      } else {
135        if(width(rect.first) > width(rect.second)) {
136          std::pair<I,I> p = bisect(rect.first);
137          l.push_back(std::make_pair(p.first, rect.second));
138          l.push_back(std::make_pair(p.second, rect.second));
139        } else {
140          std::pair<I,I> p = bisect(rect.second);
141          l.push_back(std::make_pair(rect.first, p.first));
142          l.push_back(std::make_pair(rect.first, p.second));
143        }
144      }
145    }
146    if(i % 10000 == 0)
147      std::cerr << "\rIteration " << i << ", l.size() = " << l.size();
148  }
149  std::cerr << '\n';
150}
151
152int main()
153{
154  using namespace boost;
155  using namespace numeric;
156  using namespace interval_lib;
157
158  typedef interval<double,
159                   policies<save_state<rounded_transc_opp<double> >,
160                            checking_base<double> > > I;
161
162  std::cout << "Zero points of sin(x)/(x*x+1)\n";
163  find_zeros(std::cout, test_func1d<I>(), I(-11, 10));
164  std::cout << "Zero points of sqrt(x*x-1)\n";
165  find_zeros(std::cout, test_func1d_2<I>(), I(-5, 6));
166  std::cout << "Zero points of Van Iwaarden's 2D function\n";
167  std::ofstream f("func2d.data");
168  find_zeros(f, test_func2d<I>(), I(-20, 20), I(-20, 20));
169  std::cout << "Use gnuplot, command 'plot \"func2d.data\" with dots'   to plot\n";
170}
Note: See TracBrowser for help on using the repository browser.