update boost on linux

This commit is contained in:
Bassem Girgis
2019-08-10 16:06:25 -05:00
parent 76ad52be58
commit 861b918727
5363 changed files with 483306 additions and 116507 deletions

View File

@@ -15,14 +15,16 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/config/suffix.hpp>
#include <boost/function.hpp>
#ifdef BOOST_NO_CXX11_LAMBDAS
#include <boost/lambda/lambda.hpp>
#endif
#include <boost/math/tools/rational.hpp>
#include <boost/math/tools/real_cast.hpp>
#include <boost/math/policies/error_handling.hpp>
#include <boost/math/special_functions/binomial.hpp>
#include <boost/operators.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/math/tools/detail/is_const_iterable.hpp>
#include <vector>
#include <ostream>
@@ -197,7 +199,7 @@ division(polynomial<T> u, const polynomial<T>& v)
BOOST_ASSERT(u);
typedef typename polynomial<T>::size_type N;
N const m = u.size() - 1, n = v.size() - 1;
N k = m - n;
polynomial<T> q;
@@ -213,13 +215,35 @@ division(polynomial<T> u, const polynomial<T>& v)
return std::make_pair(q, u);
}
template <class T>
struct identity
//
// These structures are the same as the void specializations of the functors of the same name
// in the std lib from C++14 onwards:
//
struct negate
{
T operator()(T const &x) const
{
return x;
}
template <class T>
T operator()(T const &x) const
{
return -x;
}
};
struct plus
{
template <class T, class U>
T operator()(T const &x, U const& y) const
{
return x + y;
}
};
struct minus
{
template <class T, class U>
T operator()(T const &x, U const& y) const
{
return x - y;
}
};
} // namespace detail
@@ -255,12 +279,7 @@ quotient_remainder(const polynomial<T>& dividend, const polynomial<T>& divisor)
template <class T>
class polynomial :
equality_comparable< polynomial<T>,
dividable< polynomial<T>,
dividable2< polynomial<T>, T,
modable< polynomial<T>,
modable2< polynomial<T>, T > > > > >
class polynomial
{
public:
// typedefs:
@@ -284,13 +303,26 @@ public:
normalize();
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
polynomial(std::vector<T>&& p) : m_data(std::move(p))
{
normalize();
}
#endif
template <class U>
explicit polynomial(const U& point)
explicit polynomial(const U& point, typename boost::enable_if<boost::is_convertible<U, T> >::type* = 0)
{
if (point != U(0))
m_data.push_back(point);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// move:
polynomial(polynomial&& p) BOOST_NOEXCEPT
: m_data(std::move(p.m_data)) { }
#endif
// copy:
polynomial(const polynomial& p)
: m_data(p.m_data) { }
@@ -298,17 +330,24 @@ public:
template <class U>
polynomial(const polynomial<U>& p)
{
m_data.resize(p.size());
for(unsigned i = 0; i < p.size(); ++i)
{
m_data.push_back(boost::math::tools::real_cast<T>(p[i]));
m_data[i] = boost::math::tools::real_cast<T>(p[i]);
}
}
#ifdef BOOST_MATH_HAS_IS_CONST_ITERABLE
template <class Range>
explicit polynomial(const Range& r, typename boost::enable_if<boost::math::tools::detail::is_const_iterable<Range> >::type* = 0)
: polynomial(r.begin(), r.end())
{
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500)
polynomial(std::initializer_list<T> l) : polynomial(std::begin(l), std::end(l))
{
}
polynomial&
operator=(std::initializer_list<T> l)
{
@@ -320,26 +359,32 @@ public:
// access:
size_type size()const { return m_data.size(); }
size_type degree()const
size_type size() const { return m_data.size(); }
size_type degree() const
{
if (size() == 0)
throw std::logic_error("degree() is undefined for the zero polynomial.");
return m_data.size() - 1;
}
}
value_type& operator[](size_type i)
{
return m_data[i];
}
const value_type& operator[](size_type i)const
const value_type& operator[](size_type i) const
{
return m_data[i];
}
T evaluate(T z)const
T evaluate(T z) const
{
return m_data.size() > 0 ? boost::math::tools::evaluate_polynomial(&m_data[0], z, m_data.size()) : 0;
return this->operator()(z);
}
std::vector<T> chebyshev()const
T operator()(T z) const
{
return m_data.size() > 0 ? boost::math::tools::evaluate_polynomial(&m_data[0], z, m_data.size()) : T(0);
}
std::vector<T> chebyshev() const
{
return polynomial_to_chebyshev(m_data);
}
@@ -354,9 +399,48 @@ public:
return m_data;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
polynomial<T> prime() const
{
if (m_data.size() == 0)
{
return polynomial<T>({});
}
std::vector<T> p_data(m_data.size() - 1);
for (size_t i = 0; i < p_data.size(); ++i) {
p_data[i] = m_data[i+1]*static_cast<T>(i+1);
}
return polynomial<T>(std::move(p_data));
}
polynomial<T> integrate() const
{
std::vector<T> i_data(m_data.size() + 1);
// Choose integration constant such that P(0) = 0.
i_data[0] = T(0);
for (size_t i = 1; i < i_data.size(); ++i)
{
i_data[i] = m_data[i-1]/static_cast<T>(i);
}
return polynomial<T>(std::move(i_data));
}
// operators:
polynomial& operator =(polynomial&& p) BOOST_NOEXCEPT
{
m_data = std::move(p.m_data);
return *this;
}
#endif
polynomial& operator =(const polynomial& p)
{
m_data = p.m_data;
return *this;
}
template <class U>
polynomial& operator +=(const U& value)
typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial&>::type operator +=(const U& value)
{
addition(value);
normalize();
@@ -364,7 +448,7 @@ public:
}
template <class U>
polynomial& operator -=(const U& value)
typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial&>::type operator -=(const U& value)
{
subtraction(value);
normalize();
@@ -372,7 +456,7 @@ public:
}
template <class U>
polynomial& operator *=(const U& value)
typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial&>::type operator *=(const U& value)
{
multiplication(value);
normalize();
@@ -380,7 +464,7 @@ public:
}
template <class U>
polynomial& operator /=(const U& value)
typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial&>::type operator /=(const U& value)
{
division(value);
normalize();
@@ -388,7 +472,7 @@ public:
}
template <class U>
polynomial& operator %=(const U& /*value*/)
typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial&>::type operator %=(const U& /*value*/)
{
// We can always divide by a scalar, so there is no remainder:
this->set_zero();
@@ -410,20 +494,25 @@ public:
normalize();
return *this;
}
template <typename U, typename V>
void multiply(const polynomial<U>& a, const polynomial<V>& b) {
if (!a || !b)
{
this->set_zero();
return;
}
std::vector<T> prod(a.size() + b.size() - 1, T(0));
for (unsigned i = 0; i < a.size(); ++i)
for (unsigned j = 0; j < b.size(); ++j)
prod[i+j] += a.m_data[i] * b.m_data[j];
m_data.swap(prod);
}
template <class U>
polynomial& operator *=(const polynomial<U>& value)
{
// TODO: FIXME: use O(N log(N)) algorithm!!!
if (!value)
{
this->set_zero();
return *this;
}
std::vector<T> prod(size() + value.size() - 1, T(0));
for (size_type i = 0; i < value.size(); ++i)
for (size_type j = 0; j < size(); ++j)
prod[i+j] += m_data[j] * value[i];
m_data.swap(prod);
this->multiply(*this, value);
return *this;
}
@@ -456,13 +545,13 @@ public:
normalize();
return *this;
}
// Convenient and efficient query for zero.
bool is_zero() const
{
return m_data.empty();
}
// Conversion to bool.
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
typedef bool (polynomial::*unmentionable_type)() const;
@@ -483,74 +572,84 @@ public:
{
m_data.clear();
}
/** Remove zero coefficients 'from the top', that is for which there are no
* non-zero coefficients of higher degree. */
void normalize()
{
#ifndef BOOST_NO_CXX11_LAMBDAS
m_data.erase(std::find_if(m_data.rbegin(), m_data.rend(), [](const T& x)->bool { return x != T(0); }).base(), m_data.end());
#else
using namespace boost::lambda;
m_data.erase(std::find_if(m_data.rbegin(), m_data.rend(), _1 != T(0)).base(), m_data.end());
#endif
}
private:
template <class U, class R1, class R2>
polynomial& addition(const U& value, R1 sign, R2 op)
template <class U, class R>
polynomial& addition(const U& value, R op)
{
if(m_data.size() == 0)
m_data.push_back(sign(value));
else
m_data[0] = op(m_data[0], value);
m_data.resize(1, 0);
m_data[0] = op(m_data[0], value);
return *this;
}
template <class U>
polynomial& addition(const U& value)
{
return addition(value, detail::identity<U>(), std::plus<U>());
return addition(value, detail::plus());
}
template <class U>
polynomial& subtraction(const U& value)
{
return addition(value, std::negate<U>(), std::minus<U>());
return addition(value, detail::minus());
}
template <class U, class R1, class R2>
polynomial& addition(const polynomial<U>& value, R1 sign, R2 op)
template <class U, class R>
polynomial& addition(const polynomial<U>& value, R op)
{
size_type s1 = (std::min)(m_data.size(), value.size());
for(size_type i = 0; i < s1; ++i)
if (m_data.size() < value.size())
m_data.resize(value.size(), 0);
for(size_type i = 0; i < value.size(); ++i)
m_data[i] = op(m_data[i], value[i]);
for(size_type i = s1; i < value.size(); ++i)
m_data.push_back(sign(value[i]));
return *this;
}
template <class U>
polynomial& addition(const polynomial<U>& value)
{
return addition(value, detail::identity<U>(), std::plus<U>());
return addition(value, detail::plus());
}
template <class U>
polynomial& subtraction(const polynomial<U>& value)
{
return addition(value, std::negate<U>(), std::minus<U>());
return addition(value, detail::minus());
}
template <class U>
polynomial& multiplication(const U& value)
{
#ifndef BOOST_NO_CXX11_LAMBDAS
std::transform(m_data.begin(), m_data.end(), m_data.begin(), [&](const T& x)->T { return x * value; });
#else
using namespace boost::lambda;
std::transform(m_data.begin(), m_data.end(), m_data.begin(), ret<T>(_1 * value));
#endif
return *this;
}
template <class U>
polynomial& division(const U& value)
{
#ifndef BOOST_NO_CXX11_LAMBDAS
std::transform(m_data.begin(), m_data.end(), m_data.begin(), [&](const T& x)->T { return x / value; });
#else
using namespace boost::lambda;
std::transform(m_data.begin(), m_data.end(), m_data.begin(), ret<T>(_1 / value));
#endif
return *this;
}
@@ -565,6 +664,26 @@ inline polynomial<T> operator + (const polynomial<T>& a, const polynomial<T>& b)
result += b;
return result;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T>
inline polynomial<T> operator + (polynomial<T>&& a, const polynomial<T>& b)
{
a += b;
return a;
}
template <class T>
inline polynomial<T> operator + (const polynomial<T>& a, polynomial<T>&& b)
{
b += a;
return b;
}
template <class T>
inline polynomial<T> operator + (polynomial<T>&& a, polynomial<T>&& b)
{
a += b;
return a;
}
#endif
template <class T>
inline polynomial<T> operator - (const polynomial<T>& a, const polynomial<T>& b)
@@ -573,61 +692,101 @@ inline polynomial<T> operator - (const polynomial<T>& a, const polynomial<T>& b)
result -= b;
return result;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T>
inline polynomial<T> operator - (polynomial<T>&& a, const polynomial<T>& b)
{
a -= b;
return a;
}
template <class T>
inline polynomial<T> operator - (const polynomial<T>& a, polynomial<T>&& b)
{
b -= a;
return -b;
}
template <class T>
inline polynomial<T> operator - (polynomial<T>&& a, polynomial<T>&& b)
{
a -= b;
return a;
}
#endif
template <class T>
inline polynomial<T> operator * (const polynomial<T>& a, const polynomial<T>& b)
{
polynomial<T> result(a);
result *= b;
polynomial<T> result;
result.multiply(a, b);
return result;
}
template <class T>
inline polynomial<T> operator / (const polynomial<T>& a, const polynomial<T>& b)
{
return quotient_remainder(a, b).first;
}
template <class T>
inline polynomial<T> operator % (const polynomial<T>& a, const polynomial<T>& b)
{
return quotient_remainder(a, b).second;
}
template <class T, class U>
inline polynomial<T> operator + (const polynomial<T>& a, const U& b)
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator + (polynomial<T> a, const U& b)
{
polynomial<T> result(a);
result += b;
return result;
a += b;
return a;
}
template <class T, class U>
inline polynomial<T> operator - (const polynomial<T>& a, const U& b)
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator - (polynomial<T> a, const U& b)
{
polynomial<T> result(a);
result -= b;
return result;
a -= b;
return a;
}
template <class T, class U>
inline polynomial<T> operator * (const polynomial<T>& a, const U& b)
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator * (polynomial<T> a, const U& b)
{
polynomial<T> result(a);
result *= b;
return result;
a *= b;
return a;
}
template <class T, class U>
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator / (polynomial<T> a, const U& b)
{
a /= b;
return a;
}
template <class T, class U>
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator % (const polynomial<T>&, const U&)
{
// Since we can always divide by a scalar, result is always an empty polynomial:
return polynomial<T>();
}
template <class U, class T>
inline polynomial<T> operator + (const U& a, const polynomial<T>& b)
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator + (const U& a, polynomial<T> b)
{
polynomial<T> result(b);
result += a;
return result;
b += a;
return b;
}
template <class U, class T>
inline polynomial<T> operator - (const U& a, const polynomial<T>& b)
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator - (const U& a, polynomial<T> b)
{
polynomial<T> result(a);
result -= b;
return result;
b -= a;
return -b;
}
template <class U, class T>
inline polynomial<T> operator * (const U& a, const polynomial<T>& b)
inline typename boost::enable_if_c<boost::is_constructible<T, U>::value, polynomial<T> >::type operator * (const U& a, polynomial<T> b)
{
polynomial<T> result(b);
result *= a;
return result;
b *= a;
return b;
}
template <class T>
@@ -636,27 +795,31 @@ bool operator == (const polynomial<T> &a, const polynomial<T> &b)
return a.data() == b.data();
}
template <typename T, typename U>
polynomial<T> operator >> (const polynomial<T>& a, const U& b)
template <class T>
bool operator != (const polynomial<T> &a, const polynomial<T> &b)
{
polynomial<T> result(a);
result >>= b;
return result;
return a.data() != b.data();
}
template <typename T, typename U>
polynomial<T> operator << (const polynomial<T>& a, const U& b)
polynomial<T> operator >> (polynomial<T> a, const U& b)
{
polynomial<T> result(a);
result <<= b;
return result;
a >>= b;
return a;
}
template <typename T, typename U>
polynomial<T> operator << (polynomial<T> a, const U& b)
{
a <<= b;
return a;
}
// Unary minus (negate).
template <class T>
polynomial<T> operator - (polynomial<T> a)
{
std::transform(a.data().begin(), a.data().end(), a.data().begin(), std::negate<T>());
std::transform(a.data().begin(), a.data().end(), a.data().begin(), detail::negate());
return a;
}
@@ -713,7 +876,9 @@ inline std::basic_ostream<charT, traits>& operator << (std::basic_ostream<charT,
} // namespace math
} // namespace boost
//
// Polynomial specific overload of gcd algorithm:
//
#include <boost/math/tools/polynomial_gcd.hpp>
#endif // BOOST_MATH_TOOLS_POLYNOMIAL_HPP