mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2026-06-02 14:04:55 -04:00
Squashed 'boost/' content from commit b4feb19f2
git-subtree-dir: boost git-subtree-split: b4feb19f287ee92d87a9624b5d36b7cf46aeadeb
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
/* Boost example/filter.cpp
|
||||
* two examples of filters for computing the sign of a determinant
|
||||
* the second filter is based on an idea presented in
|
||||
* "Interval arithmetic yields efficient dynamic filters for computational
|
||||
* geometry" by Brönnimann, Burnikel and Pion, 2001
|
||||
*
|
||||
* Copyright 2003 Guillaume Melquiond
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or
|
||||
* copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/numeric/interval.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace dummy {
|
||||
using namespace boost;
|
||||
using namespace numeric;
|
||||
using namespace interval_lib;
|
||||
typedef save_state<rounded_arith_opp<double> > R;
|
||||
typedef checking_no_nan<double, checking_no_empty<double> > P;
|
||||
typedef interval<double, policies<R, P> > I;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class vector {
|
||||
T* ptr;
|
||||
public:
|
||||
vector(int d) { ptr = (T*)malloc(sizeof(T) * d); }
|
||||
~vector() { free(ptr); }
|
||||
const T& operator[](int i) const { return ptr[i]; }
|
||||
T& operator[](int i) { return ptr[i]; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class matrix {
|
||||
int dim;
|
||||
T* ptr;
|
||||
public:
|
||||
matrix(int d): dim(d) { ptr = (T*)malloc(sizeof(T) * dim * dim); }
|
||||
~matrix() { free(ptr); }
|
||||
int get_dim() const { return dim; }
|
||||
void assign(const matrix<T> &a) { memcpy(ptr, a.ptr, sizeof(T) * dim * dim); }
|
||||
const T* operator[](int i) const { return &(ptr[i * dim]); }
|
||||
T* operator[](int i) { return &(ptr[i * dim]); }
|
||||
};
|
||||
|
||||
typedef dummy::I I_dbl;
|
||||
|
||||
/* compute the sign of a determinant using an interval LU-decomposition; the
|
||||
function answers 1 or -1 if the determinant is positive or negative (and
|
||||
more importantly, the result must be provable), or 0 if the algorithm was
|
||||
unable to get a correct sign */
|
||||
int det_sign_algo1(const matrix<double> &a) {
|
||||
int dim = a.get_dim();
|
||||
vector<int> p(dim);
|
||||
for(int i = 0; i < dim; i++) p[i] = i;
|
||||
int sig = 1;
|
||||
I_dbl::traits_type::rounding rnd;
|
||||
typedef boost::numeric::interval_lib::unprotect<I_dbl>::type I;
|
||||
matrix<I> u(dim);
|
||||
for(int i = 0; i < dim; i++) {
|
||||
const double* line1 = a[i];
|
||||
I* line2 = u[i];
|
||||
for(int j = 0; j < dim; j++)
|
||||
line2[j] = line1[j];
|
||||
}
|
||||
// computation of L and U
|
||||
for(int i = 0; i < dim; i++) {
|
||||
// partial pivoting
|
||||
{
|
||||
int pivot = i;
|
||||
double max = 0;
|
||||
for(int j = i; j < dim; j++) {
|
||||
const I &v = u[p[j]][i];
|
||||
if (zero_in(v)) continue;
|
||||
double m = norm(v);
|
||||
if (m > max) { max = m; pivot = j; }
|
||||
}
|
||||
if (max == 0) return 0;
|
||||
if (pivot != i) {
|
||||
sig = -sig;
|
||||
int tmp = p[i];
|
||||
p[i] = p[pivot];
|
||||
p[pivot] = tmp;
|
||||
}
|
||||
}
|
||||
// U[i,?]
|
||||
{
|
||||
I *line1 = u[p[i]];
|
||||
const I &pivot = line1[i];
|
||||
if (boost::numeric::interval_lib::cerlt(pivot, 0.)) sig = -sig;
|
||||
for(int k = i + 1; k < dim; k++) {
|
||||
I *line2 = u[p[k]];
|
||||
I fact = line2[i] / pivot;
|
||||
for(int j = i + 1; j < dim; j++) line2[j] -= fact * line1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return sig;
|
||||
}
|
||||
|
||||
/* compute the sign of a determinant using a floating-point LU-decomposition
|
||||
and an a posteriori interval validation; the meaning of the answer is the
|
||||
same as previously */
|
||||
int det_sign_algo2(const matrix<double> &a) {
|
||||
int dim = a.get_dim();
|
||||
vector<int> p(dim);
|
||||
for(int i = 0; i < dim; i++) p[i] = i;
|
||||
int sig = 1;
|
||||
matrix<double> lui(dim);
|
||||
{
|
||||
// computation of L and U
|
||||
matrix<double> lu(dim);
|
||||
lu.assign(a);
|
||||
for(int i = 0; i < dim; i++) {
|
||||
// partial pivoting
|
||||
{
|
||||
int pivot = i;
|
||||
double max = std::abs(lu[p[i]][i]);
|
||||
for(int j = i + 1; j < dim; j++) {
|
||||
double m = std::abs(lu[p[j]][i]);
|
||||
if (m > max) { max = m; pivot = j; }
|
||||
}
|
||||
if (max == 0) return 0;
|
||||
if (pivot != i) {
|
||||
sig = -sig;
|
||||
int tmp = p[i];
|
||||
p[i] = p[pivot];
|
||||
p[pivot] = tmp;
|
||||
}
|
||||
}
|
||||
// L[?,i] and U[i,?]
|
||||
{
|
||||
double *line1 = lu[p[i]];
|
||||
double pivot = line1[i];
|
||||
if (pivot < 0) sig = -sig;
|
||||
for(int k = i + 1; k < dim; k++) {
|
||||
double *line2 = lu[p[k]];
|
||||
double fact = line2[i] / pivot;
|
||||
line2[i] = fact;
|
||||
for(int j = i + 1; j < dim; j++) line2[j] -= line1[j] * fact;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// computation of approximate inverses: Li and Ui
|
||||
for(int j = 0; j < dim; j++) {
|
||||
for(int i = j + 1; i < dim; i++) {
|
||||
double *line = lu[p[i]];
|
||||
double s = - line[j];
|
||||
for(int k = j + 1; k < i; k++) s -= line[k] * lui[k][j];
|
||||
lui[i][j] = s;
|
||||
}
|
||||
lui[j][j] = 1 / lu[p[j]][j];
|
||||
for(int i = j - 1; i >= 0; i--) {
|
||||
double *line = lu[p[i]];
|
||||
double s = 0;
|
||||
for(int k = i + 1; k <= j; k++) s -= line[k] * lui[k][j];
|
||||
lui[i][j] = s / line[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// norm of PAUiLi-I computed with intervals
|
||||
{
|
||||
I_dbl::traits_type::rounding rnd;
|
||||
typedef boost::numeric::interval_lib::unprotect<I_dbl>::type I;
|
||||
vector<I> m1(dim);
|
||||
vector<I> m2(dim);
|
||||
for(int i = 0; i < dim; i++) {
|
||||
for(int j = 0; j < dim; j++) m1[j] = 0;
|
||||
const double *l1 = a[p[i]];
|
||||
for(int j = 0; j < dim; j++) {
|
||||
double v = l1[j]; // PA[i,j]
|
||||
double *l2 = lui[j]; // Ui[j,?]
|
||||
for(int k = j; k < dim; k++) {
|
||||
using boost::numeric::interval_lib::mul;
|
||||
m1[k] += mul<I>(v, l2[k]); // PAUi[i,k]
|
||||
}
|
||||
}
|
||||
for(int j = 0; j < dim; j++) m2[j] = m1[j]; // PAUi[i,j] * Li[j,j]
|
||||
for(int j = 1; j < dim; j++) {
|
||||
const I &v = m1[j]; // PAUi[i,j]
|
||||
double *l2 = lui[j]; // Li[j,?]
|
||||
for(int k = 0; k < j; k++)
|
||||
m2[k] += v * l2[k]; // PAUiLi[i,k]
|
||||
}
|
||||
m2[i] -= 1; // PAUiLi-I
|
||||
double ss = 0;
|
||||
for(int i = 0; i < dim; i++) ss = rnd.add_up(ss, norm(m2[i]));
|
||||
if (ss >= 1) return 0;
|
||||
}
|
||||
}
|
||||
return sig;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int dim = 20;
|
||||
matrix<double> m(dim);
|
||||
for(int i = 0; i < dim; i++) for(int j = 0; j < dim; j++)
|
||||
m[i][j] = /*1 / (i-j-0.001)*/ cos(1+i*sin(1 + j)) /*1./(1+i+j)*/;
|
||||
|
||||
// compute the sign of the determinant of a "strange" matrix with the two
|
||||
// algorithms, the first should fail and the second succeed
|
||||
std::cout << det_sign_algo1(m) << " " << det_sign_algo2(m) << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/* Boost example/findroot_demo.cpp
|
||||
* find zero points of some function by dichotomy
|
||||
*
|
||||
* Copyright 2000 Jens Maurer
|
||||
* Copyright 2002-2003 Guillaume Melquiond
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or
|
||||
* copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* The idea and the 2D function are based on RVInterval,
|
||||
* which contains the following copyright notice:
|
||||
|
||||
This file is copyrighted 1996 by Ronald Van Iwaarden.
|
||||
|
||||
Permission is hereby granted, without written agreement and
|
||||
without license or royalty fees, to use, copy, modify, and
|
||||
distribute this software and its documentation for any
|
||||
purpose, subject to the following conditions:
|
||||
|
||||
The above license notice and this permission notice shall
|
||||
appear in all copies or substantial portions of this software.
|
||||
|
||||
The name "RVInterval" cannot be used for any modified form of
|
||||
this software that does not originate from the authors.
|
||||
Nevertheless, the name "RVInterval" may and should be used to
|
||||
designate the optimization software implemented and described
|
||||
in this package, even if embedded in any other system, as long
|
||||
as any portion of this code remains.
|
||||
|
||||
The authors specifically disclaim any warranties, including,
|
||||
but not limited to, the implied warranties of merchantability
|
||||
and fitness for a particular purpose. The software provided
|
||||
hereunder is on an "as is" basis, and the authors have no
|
||||
obligation to provide maintenance, support, updates,
|
||||
enhancements, or modifications. In no event shall the authors
|
||||
be liable to any party for direct, indirect, special,
|
||||
incidental, or consequential damages arising out of the use of
|
||||
this software and its documentation.
|
||||
*/
|
||||
|
||||
#include <boost/numeric/interval.hpp> // must be first for <limits> workaround
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
template<class T>
|
||||
struct test_func2d
|
||||
{
|
||||
T operator()(T x, T y) const
|
||||
{
|
||||
return sin(x)*cos(y) - exp(x*y)/45.0 * (pow(x+y, 2)+100.0) -
|
||||
cos(sin(y))*y/4.0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct test_func1d
|
||||
{
|
||||
T operator()(T x) const
|
||||
{
|
||||
return sin(x)/(x*x+1.0);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct test_func1d_2
|
||||
{
|
||||
T operator()(T x) const
|
||||
{
|
||||
using std::sqrt;
|
||||
return sqrt(x*x-1.0);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Function, class I>
|
||||
void find_zeros(std::ostream & os, Function f, I searchrange)
|
||||
{
|
||||
std::list<I> l, done;
|
||||
l.push_back(searchrange);
|
||||
while(!l.empty()) {
|
||||
I range = l.front();
|
||||
l.pop_front();
|
||||
I val = f(range);
|
||||
if (zero_in(val)) {
|
||||
if(width(range) < 1e-6) {
|
||||
os << range << '\n';
|
||||
continue;
|
||||
}
|
||||
// there's still a solution hidden somewhere
|
||||
std::pair<I,I> p = bisect(range);
|
||||
l.push_back(p.first);
|
||||
l.push_back(p.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::ostream &operator<<(std::ostream &os, const std::pair<T, T> &x) {
|
||||
os << "(" << x.first << ", " << x.second << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class T, class Policies>
|
||||
std::ostream &operator<<(std::ostream &os,
|
||||
const boost::numeric::interval<T, Policies> &x) {
|
||||
os << "[" << x.lower() << ", " << x.upper() << "]";
|
||||
return os;
|
||||
}
|
||||
|
||||
static const double epsilon = 5e-3;
|
||||
|
||||
template<class Function, class I>
|
||||
void find_zeros(std::ostream & os, Function f, I rx, I ry)
|
||||
{
|
||||
typedef std::pair<I, I> rectangle;
|
||||
typedef std::deque<rectangle> container;
|
||||
container l, done;
|
||||
// l.reserve(50);
|
||||
l.push_back(std::make_pair(rx, ry));
|
||||
for(int i = 1; !l.empty(); ++i) {
|
||||
rectangle rect = l.front();
|
||||
l.pop_front();
|
||||
I val = f(rect.first, rect.second);
|
||||
if (zero_in(val)) {
|
||||
if(width(rect.first) < epsilon && width(rect.second) < epsilon) {
|
||||
os << median(rect.first) << " " << median(rect.second) << " "
|
||||
<< lower(rect.first) << " " << upper(rect.first) << " "
|
||||
<< lower(rect.second) << " " << upper(rect.second)
|
||||
<< '\n';
|
||||
} else {
|
||||
if(width(rect.first) > width(rect.second)) {
|
||||
std::pair<I,I> p = bisect(rect.first);
|
||||
l.push_back(std::make_pair(p.first, rect.second));
|
||||
l.push_back(std::make_pair(p.second, rect.second));
|
||||
} else {
|
||||
std::pair<I,I> p = bisect(rect.second);
|
||||
l.push_back(std::make_pair(rect.first, p.first));
|
||||
l.push_back(std::make_pair(rect.first, p.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(i % 10000 == 0)
|
||||
std::cerr << "\rIteration " << i << ", l.size() = " << l.size();
|
||||
}
|
||||
std::cerr << '\n';
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace numeric;
|
||||
using namespace interval_lib;
|
||||
|
||||
typedef interval<double,
|
||||
policies<save_state<rounded_transc_opp<double> >,
|
||||
checking_base<double> > > I;
|
||||
|
||||
std::cout << "Zero points of sin(x)/(x*x+1)\n";
|
||||
find_zeros(std::cout, test_func1d<I>(), I(-11, 10));
|
||||
std::cout << "Zero points of sqrt(x*x-1)\n";
|
||||
find_zeros(std::cout, test_func1d_2<I>(), I(-5, 6));
|
||||
std::cout << "Zero points of Van Iwaarden's 2D function\n";
|
||||
std::ofstream f("func2d.data");
|
||||
find_zeros(f, test_func2d<I>(), I(-20, 20), I(-20, 20));
|
||||
std::cout << "Use gnuplot, command 'plot \"func2d.data\" with dots' to plot\n";
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/* Boost example/horner.cpp
|
||||
* example of unprotecting rounding for a whole function computation
|
||||
*
|
||||
* Copyright 2002-2003 Guillaume Melquiond
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or
|
||||
* copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/numeric/interval.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// I is an interval class, the polynom is a simple array
|
||||
template<class I>
|
||||
I horner(const I& x, const I p[], int n) {
|
||||
|
||||
// initialize and restore the rounding mode
|
||||
typename I::traits_type::rounding rnd;
|
||||
|
||||
// define the unprotected version of the interval type
|
||||
typedef typename boost::numeric::interval_lib::unprotect<I>::type R;
|
||||
|
||||
const R& a = x;
|
||||
R y = p[n - 1];
|
||||
for(int i = n - 2; i >= 0; i--) {
|
||||
y = y * a + (const R&)(p[i]);
|
||||
}
|
||||
return y;
|
||||
|
||||
// restore the rounding mode with the destruction of rnd
|
||||
}
|
||||
|
||||
template<class T, class Policies>
|
||||
std::ostream &operator<<(std::ostream &os,
|
||||
const boost::numeric::interval<T, Policies> &x) {
|
||||
os << "[" << x.lower() << ", " << x.upper() << "]";
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
typedef boost::numeric::interval<double> I;
|
||||
I p[3] = { -1.0, 0, 1.0 };
|
||||
I x = 1.0;
|
||||
std::cout << horner(x, p, 3) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/* Boost examples/io.cpp
|
||||
* show some exampleso of i/o operators
|
||||
* thanks to all the people who commented on this point, particularly on
|
||||
* the Boost mailing-list
|
||||
*
|
||||
* Copyright 2003 Guillaume Melquiond
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or
|
||||
* copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/numeric/interval.hpp>
|
||||
#include <boost/io/ios_state.hpp>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
|
||||
namespace io_std {
|
||||
|
||||
template<class T, class Policies, class CharType, class CharTraits>
|
||||
std::basic_ostream<CharType, CharTraits> &operator<<
|
||||
(std::basic_ostream<CharType, CharTraits> &stream,
|
||||
const boost::numeric::interval<T, Policies> &value)
|
||||
{
|
||||
if (empty(value)) {
|
||||
return stream << "[]";
|
||||
} else {
|
||||
return stream << '[' << lower(value) << ',' << upper(value) << ']';
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace io_std
|
||||
|
||||
namespace io_sngl {
|
||||
|
||||
template<class T, class Policies, class CharType, class CharTraits>
|
||||
std::basic_ostream<CharType, CharTraits> &operator<<
|
||||
(std::basic_ostream<CharType, CharTraits> &stream,
|
||||
const boost::numeric::interval<T, Policies> &value)
|
||||
{
|
||||
if (empty(value)) {
|
||||
return stream << "[]";
|
||||
} else if (singleton(value)) {
|
||||
return stream << '[' << lower(value) << ']';
|
||||
} else {
|
||||
return stream << '[' << lower(value) << ',' << upper(value) << ']';
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace io_sngl
|
||||
|
||||
namespace io_wdth {
|
||||
|
||||
template<class T, class Policies, class CharType, class CharTraits>
|
||||
std::basic_ostream<CharType, CharTraits> &operator<<
|
||||
(std::basic_ostream<CharType, CharTraits> &stream,
|
||||
const boost::numeric::interval<T, Policies> &value)
|
||||
{
|
||||
if (empty(value)) {
|
||||
return stream << "nothing";
|
||||
} else {
|
||||
return stream << median(value) << " ± " << width(value) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace io_wdth
|
||||
|
||||
namespace io_prec {
|
||||
|
||||
template<class T, class Policies, class CharType, class CharTraits>
|
||||
std::basic_ostream<CharType, CharTraits> &operator<<
|
||||
(std::basic_ostream<CharType, CharTraits> &stream,
|
||||
const boost::numeric::interval<T, Policies> &value)
|
||||
{
|
||||
if (empty(value)) {
|
||||
return stream << "nothing";
|
||||
} else if (singleton(value)) {
|
||||
boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10);
|
||||
return stream << lower(value);
|
||||
} else if (zero_in(value)) {
|
||||
return stream << "0~";
|
||||
} else {
|
||||
const T rel = width(value) / norm(value);
|
||||
int range = - (int)std::log10(rel);
|
||||
boost::io::ios_precision_saver state(stream, range);
|
||||
return stream << median(value);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace io_prec
|
||||
|
||||
namespace io_wide {
|
||||
|
||||
template<class T, class Policies, class CharType, class CharTraits>
|
||||
std::basic_ostream<CharType, CharTraits> &operator<<
|
||||
(std::basic_ostream<CharType, CharTraits> &stream,
|
||||
const boost::numeric::interval<T, Policies> &value)
|
||||
{
|
||||
if (empty(value)) {
|
||||
return stream << "nothing";
|
||||
} else if (singleton(value)) {
|
||||
boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10);
|
||||
return stream << lower(value);
|
||||
} else if (zero_in(value)) {
|
||||
return stream << "0~";
|
||||
} else {
|
||||
std::streamsize p = stream.precision();
|
||||
// FIXME poor man's power of 10, only up to 1E-15
|
||||
p = (p > 15) ? 15 : p - 1;
|
||||
double eps = 1.0; for(; p > 0; --p) { eps /= 10; }
|
||||
T eps2 = static_cast<T>(eps / 2) * norm(value);
|
||||
boost::numeric::interval<T, Policies> r = widen(value, eps2);
|
||||
return stream << '[' << lower(r) << ',' << upper(r) << ']';
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace io_wide
|
||||
|
||||
template<class T, class Policies, class CharType, class CharTraits> inline
|
||||
std::basic_istream<CharType, CharTraits> &operator>>
|
||||
(std::basic_istream<CharType, CharTraits> &stream,
|
||||
boost::numeric::interval<T, Policies> &value)
|
||||
{
|
||||
T l, u;
|
||||
char c = 0;
|
||||
stream >> c;
|
||||
if (c == '[') {
|
||||
stream >> l >> c;
|
||||
if (c == ',') stream >> u >> c; else u = l;
|
||||
if (c != ']') stream.setstate(stream.failbit);
|
||||
} else {
|
||||
stream.putback(c);
|
||||
stream >> l;
|
||||
u = l;
|
||||
}
|
||||
if (stream)
|
||||
value.assign(l, u);
|
||||
else
|
||||
value = boost::numeric::interval<T, Policies>::empty();
|
||||
return stream;
|
||||
}
|
||||
|
||||
// Test program
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace numeric;
|
||||
using namespace interval_lib;
|
||||
|
||||
typedef interval<double,
|
||||
policies<rounded_math<double>,
|
||||
checking_base<double> > > I;
|
||||
|
||||
I tab[] = { I::empty(), I(1,1), I(1,2), I(-1,1), I(12.34,12.35),
|
||||
I(1234.56,1234.57), I(123456.78, 123456.79), I::empty() };
|
||||
unsigned int len = sizeof(tab) / sizeof(I);
|
||||
std::cout << "Enter an interval: (it will be the last shown)\n";
|
||||
std::cin >> tab[len - 1];
|
||||
|
||||
for(unsigned int i = 0; i < len; ++i) {
|
||||
{ using namespace io_std; std::cout << tab[i] << '\n'; }
|
||||
{ using namespace io_sngl; std::cout << tab[i] << '\n'; }
|
||||
{ using namespace io_wdth; std::cout << tab[i] << '\n'; }
|
||||
{ using namespace io_prec; std::cout << tab[i] << '\n'; }
|
||||
{ using namespace io_wide; std::cout << tab[i] << '\n'; }
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/* Boost example/newton-raphson.cpp
|
||||
* Newton iteration for intervals
|
||||
*
|
||||
* Copyright 2003 Guillaume Melquiond
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or
|
||||
* copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/numeric/interval.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
template <class I> I f(const I& x)
|
||||
{ return x * (x - 1.) * (x - 2.) * (x - 3.) * (x - 4.); }
|
||||
template <class I> I f_diff(const I& x)
|
||||
{ return (((5. * x - 40.) * x + 105.) * x - 100.) * x + 24.; }
|
||||
|
||||
static const double max_width = 1e-10;
|
||||
static const double alpha = 0.75;
|
||||
|
||||
using namespace boost;
|
||||
using namespace numeric;
|
||||
using namespace interval_lib;
|
||||
|
||||
// First method: no empty intervals
|
||||
|
||||
typedef interval<double> I1_aux;
|
||||
typedef unprotect<I1_aux>::type I1;
|
||||
|
||||
std::vector<I1> newton_raphson(const I1& xs) {
|
||||
std::vector<I1> l, res;
|
||||
I1 vf, vd, x, x1, x2;
|
||||
l.push_back(xs);
|
||||
while (!l.empty()) {
|
||||
x = l.back();
|
||||
l.pop_back();
|
||||
bool x2_used;
|
||||
double xx = median(x);
|
||||
vf = f<I1>(xx);
|
||||
vd = f_diff<I1>(x);
|
||||
if (zero_in(vf) && zero_in(vd)) {
|
||||
x1 = I1::whole();
|
||||
x2_used = false;
|
||||
} else {
|
||||
x1 = xx - division_part1(vf, vd, x2_used);
|
||||
if (x2_used) x2 = xx - division_part2(vf, vd);
|
||||
}
|
||||
if (overlap(x1, x)) x1 = intersect(x, x1);
|
||||
else if (x2_used) { x1 = x2; x2_used = false; }
|
||||
else continue;
|
||||
if (x2_used) {
|
||||
if (overlap(x2, x)) x2 = intersect(x, x2);
|
||||
else x2_used = false;
|
||||
}
|
||||
if (x2_used && width(x2) > width(x1)) std::swap(x1, x2);
|
||||
if (!zero_in(f(x1))) {
|
||||
if (x2_used) { x1 = x2; x2_used = false; }
|
||||
else continue;
|
||||
}
|
||||
if (width(x1) < max_width) res.push_back(x1);
|
||||
else if (width(x1) > alpha * width(x)) {
|
||||
std::pair<I1, I1> p = bisect(x);
|
||||
if (zero_in(f(p.first))) l.push_back(p.first);
|
||||
x2 = p.second;
|
||||
x2_used = true;
|
||||
} else l.push_back(x1);
|
||||
if (x2_used && zero_in(f(x2))) {
|
||||
if (width(x2) < max_width) res.push_back(x2);
|
||||
else l.push_back(x2);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Second method: with empty intervals
|
||||
|
||||
typedef change_checking<I1_aux, checking_no_nan<double> >::type I2_aux;
|
||||
typedef unprotect<I2_aux>::type I2;
|
||||
|
||||
std::vector<I2> newton_raphson(const I2& xs) {
|
||||
std::vector<I2> l, res;
|
||||
I2 vf, vd, x, x1, x2;
|
||||
l.push_back(xs);
|
||||
while (!l.empty()) {
|
||||
x = l.back();
|
||||
l.pop_back();
|
||||
double xx = median(x);
|
||||
vf = f<I2>(xx);
|
||||
vd = f_diff<I2>(x);
|
||||
if (zero_in(vf) && zero_in(vd)) {
|
||||
x1 = x;
|
||||
x2 = I2::empty();
|
||||
} else {
|
||||
bool x2_used;
|
||||
x1 = intersect(x, xx - division_part1(vf, vd, x2_used));
|
||||
x2 = intersect(x, xx - division_part2(vf, vd, x2_used));
|
||||
}
|
||||
if (width(x2) > width(x1)) std::swap(x1, x2);
|
||||
if (empty(x1) || !zero_in(f(x1))) {
|
||||
if (!empty(x2)) { x1 = x2; x2 = I2::empty(); }
|
||||
else continue;
|
||||
}
|
||||
if (width(x1) < max_width) res.push_back(x1);
|
||||
else if (width(x1) > alpha * width(x)) {
|
||||
std::pair<I2, I2> p = bisect(x);
|
||||
if (zero_in(f(p.first))) l.push_back(p.first);
|
||||
x2 = p.second;
|
||||
} else l.push_back(x1);
|
||||
if (!empty(x2) && zero_in(f(x2))) {
|
||||
if (width(x2) < max_width) res.push_back(x2);
|
||||
else l.push_back(x2);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T, class Policies>
|
||||
std::ostream &operator<<(std::ostream &os,
|
||||
const boost::numeric::interval<T, Policies> &x) {
|
||||
os << "[" << x.lower() << ", " << x.upper() << "]";
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
{
|
||||
I1_aux::traits_type::rounding rnd;
|
||||
std::vector<I1> res = newton_raphson(I1(-1, 5.1));
|
||||
std::cout << "Results: " << std::endl << std::setprecision(12);
|
||||
for(std::vector<I1>::const_iterator i = res.begin(); i != res.end(); ++i)
|
||||
std::cout << " " << *i << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
{
|
||||
I2_aux::traits_type::rounding rnd;
|
||||
std::vector<I2> res = newton_raphson(I2(-1, 5.1));
|
||||
std::cout << "Results: " << std::endl << std::setprecision(12);
|
||||
for(std::vector<I2>::const_iterator i = res.begin(); i != res.end(); ++i)
|
||||
std::cout << " " << *i << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Boost example/rational.cpp
|
||||
* example program of how to use interval< rational<> >
|
||||
*
|
||||
* Copyright 2002-2003 Guillaume Melquiond, Sylvain Pion
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or
|
||||
* copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
// it would have been enough to only include:
|
||||
// <boost/numeric/interval.hpp>
|
||||
// but it's a bit overkill to include processor intrinsics
|
||||
// and transcendental functions, so we do it by ourselves
|
||||
|
||||
#include <boost/numeric/interval/interval.hpp> // base class
|
||||
#include <boost/numeric/interval/rounded_arith.hpp> // default arithmetic rounding policy
|
||||
#include <boost/numeric/interval/checking.hpp> // default checking policy
|
||||
#include <boost/numeric/interval/arith.hpp> // += *= -= etc
|
||||
#include <boost/numeric/interval/policies.hpp> // default policy
|
||||
|
||||
#include <boost/rational.hpp>
|
||||
#include <iostream>
|
||||
|
||||
typedef boost::rational<int> Rat;
|
||||
typedef boost::numeric::interval<Rat> Interval;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Interval& r) {
|
||||
os << "[" << r.lower() << "," << r.upper() << "]";
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Rat p(2, 3), q(3, 4);
|
||||
Interval z(4, 5);
|
||||
Interval a(p, q);
|
||||
a += z;
|
||||
z *= q;
|
||||
a -= p;
|
||||
a /= q;
|
||||
std::cout << z << std::endl;
|
||||
std::cout << a << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/* Boost example/transc.cpp
|
||||
* how to use an external library (GMP/MPFR in this case) in order to
|
||||
* get correct transcendental functions on intervals
|
||||
*
|
||||
* Copyright 2003 Guillaume Melquiond
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or
|
||||
* copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/numeric/interval.hpp>
|
||||
//extern "C" {
|
||||
#include <gmp.h>
|
||||
#include <mpfr.h>
|
||||
//}
|
||||
#include <iostream>
|
||||
|
||||
struct full_rounding:
|
||||
boost::numeric::interval_lib::rounded_arith_opp<double>
|
||||
{
|
||||
private:
|
||||
typedef int mpfr_func(mpfr_t, const __mpfr_struct*, mp_rnd_t);
|
||||
double invoke_mpfr(double x, mpfr_func f, mp_rnd_t r) {
|
||||
mpfr_t xx;
|
||||
mpfr_init_set_d(xx, x, GMP_RNDN);
|
||||
f(xx, xx, r);
|
||||
double res = mpfr_get_d(xx, r);
|
||||
mpfr_clear(xx);
|
||||
return res;
|
||||
}
|
||||
public:
|
||||
# define GENR_FUNC(name) \
|
||||
double name##_down(double x) { return invoke_mpfr(x, mpfr_##name, GMP_RNDD); } \
|
||||
double name##_up (double x) { return invoke_mpfr(x, mpfr_##name, GMP_RNDU); }
|
||||
GENR_FUNC(exp)
|
||||
GENR_FUNC(log)
|
||||
GENR_FUNC(sin)
|
||||
GENR_FUNC(cos)
|
||||
GENR_FUNC(tan)
|
||||
GENR_FUNC(asin)
|
||||
GENR_FUNC(acos)
|
||||
GENR_FUNC(atan)
|
||||
GENR_FUNC(sinh)
|
||||
GENR_FUNC(cosh)
|
||||
GENR_FUNC(tanh)
|
||||
GENR_FUNC(asinh)
|
||||
GENR_FUNC(acosh)
|
||||
GENR_FUNC(atanh)
|
||||
};
|
||||
|
||||
namespace dummy {
|
||||
using namespace boost;
|
||||
using namespace numeric;
|
||||
using namespace interval_lib;
|
||||
typedef save_state<full_rounding> R;
|
||||
typedef checking_strict<double> P;
|
||||
typedef interval<double, policies<R, P> > I;
|
||||
};
|
||||
|
||||
typedef dummy::I I;
|
||||
|
||||
template<class os_t>
|
||||
os_t& operator<<(os_t &os, const I &a) {
|
||||
os << '[' << a.lower() << ',' << a.upper() << ']';
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
I x(0.5, 2.5);
|
||||
std::cout << "x = " << x << std::endl;
|
||||
std::cout.precision(16);
|
||||
# define GENR_TEST(name) \
|
||||
std::cout << #name "(x) = " << name(x) << std::endl
|
||||
GENR_TEST(exp);
|
||||
GENR_TEST(log);
|
||||
GENR_TEST(sin);
|
||||
GENR_TEST(cos);
|
||||
GENR_TEST(tan);
|
||||
GENR_TEST(asin);
|
||||
GENR_TEST(acos);
|
||||
GENR_TEST(atan);
|
||||
GENR_TEST(sinh);
|
||||
GENR_TEST(cosh);
|
||||
GENR_TEST(tanh);
|
||||
GENR_TEST(asinh);
|
||||
GENR_TEST(acosh);
|
||||
GENR_TEST(atanh);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user