#include <boost/math/tools/polynomial.hpp>
namespace boost { namespace math {
namespace tools {
template <class T>
class polynomial
{
public:
typedef typename std::vector<T>::value_type value_type;
typedef typename std::vector<T>::size_type size_type;
polynomial(){}
template <class U>
polynomial(const U* data, unsigned order);
template <class I>
polynomial(I first, I last);
template <class U>
explicit polynomial(const U& point);
polynomial(std::initializer_list<T> l);
size_type size()const;
size_type degree()const;
value_type& operator[](size_type i);
const value_type& operator[](size_type i)const;
std::vector<T> const& data() const;
std::vector<T>& data();
explicit operator bool() const;
void set_zero();
template <class U>
polynomial& operator +=(const U& value);
template <class U>
polynomial& operator -=(const U& value);
template <class U>
polynomial& operator *=(const U& value);
template <class U>
polynomial& operator /=(const U& value);
template <class U>
polynomial& operator %=(const U& value);
template <class U>
polynomial& operator +=(const polynomial<U>& value);
template <class U>
polynomial& operator -=(const polynomial<U>& value);
template <class U>
polynomial& operator *=(const polynomial<U>& value);
template <class U>
polynomial& operator /=(const polynomial<U>& value);
template <class U>
polynomial& operator %=(const polynomial<U>& value);
};
template <class T>
polynomial<T> operator + (const polynomial<T>& a, const polynomial<T>& b);
template <class T>
polynomial<T> operator - (const polynomial<T>& a, const polynomial<T>& b);
template <class T>
polynomial<T> operator * (const polynomial<T>& a, const polynomial<T>& b);
template <class T>
polynomial<T> operator / (const polynomial<T>& a, const polynomial<T>& b);
template <class T>
polynomial<T> operator % (const polynomial<T>& a, const polynomial<T>& b);
template <class T, class U>
polynomial<T> operator + (const polynomial<T>& a, const U& b);
template <class T, class U>
polynomial<T> operator - (const polynomial<T>& a, const U& b);
template <class T, class U>
polynomial<T> operator * (const polynomial<T>& a, const U& b);
template <class T, class U>
polynomial<T> operator / (const polynomial<T>& a, const U& b);
template <class T, class U>
polynomial<T> operator % (const polynomial<T>& a, const U& b);
template <class U, class T>
polynomial<T> operator + (const U& a, const polynomial<T>& b);
template <class U, class T>
polynomial<T> operator - (const U& a, const polynomial<T>& b);
template <class U, class T>
polynomial<T> operator * (const U& a, const polynomial<T>& b);
template <class T>
polynomial<T> operator - (const polynomial<T>& a);
template <class T>
polynomial<T> operator >>= (const U& a);
template <class T>
polynomial<T> operator >> (polynomial<T> const &a, const U& b);
template <class T>
polynomial<T> operator <<= (const U& a);
template <class T>
polynomial<T> operator << (polynomial<T> const &a, const U& b);
template <class T>
bool operator == (const polynomial<T> &a, const polynomial<T> &b);
template <class T>
bool operator != (const polynomial<T> &a, const polynomial<T> &b);
template <class T>
polynomial<T> pow(polynomial<T> base, int exp);
template <class charT, class traits, class T>
std::basic_ostream<charT, traits>& operator <<
(std::basic_ostream<charT, traits>& os, const polynomial<T>& poly);
template <typename T>
std::pair< polynomial<T>, polynomial<T> >
quotient_remainder(const polynomial<T>& a, const polynomial<T>& b);
}
}}
Это несколько тривиальный класс для полиномиальных манипуляций.
Видишь?
- Полиномиали
- Donald E. Knuth, The Art of Computer Programming: Volume 2, Third edition, (1998) Chapter 4.6.1, Algorithm D: Division of polynomials over a field.
Реализация в настоящее время является «наивной» разновидностью, например, с умножением 𝑶 (N2). Этот класс не должен использоваться в высокопроизводительных вычислительных средах: он предназначен для простого манипулирования малыми многочленами, обычно генерируемыми для аппроксимации специальных функций.
Он имеет деление на полиномы пополю(здесь плавающая точка, комплекс и т. д.) и по уникальной области факторизации (интегралы). Разделение полиномов по полю совместимо севклидовым GCD.
Продвинутые манипуляции: FFT, факторизация и т. д. в настоящее время не предоставляются. Предложения для них, конечно, приветствуются :-
Во-первых, включите основной многочленный заголовок (и другие), чтобы привести пример:
#include <boost/math/tools/polynomial.hpp>
А некоторые с помощью высказываний удобны:
using std::string;
using std::exception;
using std::cout;
using std::abs;
using std::pair;
using namespace boost::math;
using namespace boost::math::tools;
using boost::lexical_cast;
Храните коэффициенты удобным способом, чтобы получить к ним доступ, затем создайте несколько полиномов, используя конструкцию из диапазона итераторов, и, наконец, выводите в формате «красивой» формулы.
![[Tip]](/img/tip.png) |
Tip |
Хотя мы могли бы условно написать многочлен слева направо в порядке убывания степени, Boost. Математические магазины впорядке возрастания степени. |
Read/write for humans: 3x^3 - 4x^2 - 6x + 10
Boost polynomial storage: [ 10, -6, -4, 3 ]
boost::array<double, 4> const d3a = {{10, -6, -4, 3}};
polynomial<double> const a(d3a.begin(), d3a.end());
polynomial<double> const b{{-2.0, 1.0}};
cout << "a = " << formula_format(a)
<< "\nb = " << formula_format(b) << "\n\n";
для выхода:
a = 3x^3 - 4x^2 - 6x + 10
b = x - 2
polynomial<double> s = a + b;
cout << "a + b = " << formula_format(s) << "\n";
polynomial<double> d = a - b;
cout << "a - b = " << formula_format(d) << "\n";
polynomial<double> p = a * b;
cout << "a * b = " << formula_format(p) << "\n";
polynomial<double> q = a / b;
cout << "a / b = " << formula_format(q) << "\n";
polynomial<double> r = a % b;
cout << "a % b = " << formula_format(r) << "\n";
для выпуска
a + b = 3x^3 - 4x^2 - 5x + 8
a - b = 3x^3 - 4x^2 - 7x + 12
a * b = 3x^4 - 10x^3 + 2x^2 + 22x - 20
a / b = 3x^2 + 2x - 2
a % b = 6
Подразделение — это особый случай, когда можно рассчитать два по цене одного.
На самом деле коэффициент и остаток всегда рассчитываются вместе из-за характера алгоритма: фиксирующие операторы возвращают один результат и выбрасывают другой.
Если вы делаете много деления и хотите и коэффициент, и остаток, то вы не хотите делать вдвое больше работы, необходимой.
В этом случае вы можете назвать основную функцию<quotient_remainder
>, чтобы получить оба результата вместе.
pair< polynomial<double>, polynomial<double> > result;
result = quotient_remainder(a, b);
BOOST_ASSERT(result.first == q);
BOOST_ASSERT(result.second == r);
Исходный код наpolynomial_arithmetic.cpp