27 if constexpr (std::is_integral_v<T>) {
28 return std::abs(std::gcd(
a,
b));
30 else if constexpr (std::is_same_v<T, BigInt>) {
31 return BigInt::gcd(
a,
b);
33 else if constexpr (std::is_same_v<T, Rational>) {
51template <
typename CoeffType>
69 Polynomial(
const std::vector<CoeffType>&
c,
const std::string& var =
"x")
86 while (
coeffs.size() > 0 &&
coeffs.back() == CoeffType(0)) {
101 if (
coeffs.empty())
return -1;
102 return static_cast<int>(
coeffs.size()) - 1;
110 if (
coeffs.empty())
return CoeffType(0);
124 size_t n = std::max(
coeffs.size(), other.
coeffs.size());
127 for (
size_t i = 0; i < n; ++i) {
128 CoeffType
a = (i <
coeffs.size()) ?
coeffs[i] : CoeffType(0);
129 CoeffType
b = (i < other.
coeffs.size()) ? other.
coeffs[i] : CoeffType(0);
146 size_t n = std::max(
coeffs.size(), other.
coeffs.size());
149 for (
size_t i = 0; i < n; ++i) {
150 CoeffType
a = (i <
coeffs.size()) ?
coeffs[i] : CoeffType(0);
151 CoeffType
b = (i < other.
coeffs.size()) ? other.
coeffs[i] : CoeffType(0);
171 for (
size_t i = 0; i <
coeffs.size(); ++i) {
172 for (
size_t j = 0; j < other.
coeffs.size(); ++j) {
192 for (
size_t i = 0; i <
coeffs.size(); ++i) {
208 if (other.
is_zero())
throw std::runtime_error(
"Division by zero polynomial");
217 int deg_rem = remainder.
degree();
218 int deg_div = other.
degree();
221 if (deg_rem < deg_div) {
222 return {quotient, remainder};
225 quotient.
coeffs.resize(deg_rem - deg_div + 1, CoeffType(0));
227 while (deg_rem >= deg_div && !remainder.
is_zero()) {
229 CoeffType factor = remainder.
lead_coeff() / lc_div;
230 int deg_diff = deg_rem - deg_div;
232 quotient.
coeffs[deg_diff] = factor;
235 term.
coeffs.resize(deg_diff + 1, CoeffType(0));
236 term.
coeffs[deg_diff] = factor;
239 remainder = remainder - subtrahend;
240 deg_rem = remainder.
degree();
244 return {quotient, remainder};
253 static CoeffType
gcd_coeff(
const CoeffType&
a,
const CoeffType&
b) {
254 if constexpr (std::is_same_v<CoeffType, BigInt>) {
255 return BigInt::gcd(
a,
b);
256 }
else if constexpr (std::is_same_v<CoeffType, Rational>) {
260 if constexpr (std::is_integral_v<CoeffType>) {
261 return std::gcd(
a,
b);
294 CoeffType
eval(
const CoeffType& val)
const {
295 if (
coeffs.empty())
return CoeffType(0);
296 CoeffType res =
coeffs.back();
297 for (
int i = (
int)
coeffs.size() - 2; i >= 0; --i) {
298 res = res * val +
coeffs[i];
311 for (
size_t i = 1; i <
coeffs.size(); ++i) {
314 res.
coeffs[i-1] =
c * CoeffType(i);
327 if (lc == CoeffType(1))
return *
this;
368 for (
int i =
degree(); i >= 0; --i) {
369 if (
coeffs[i] == CoeffType(0)) {
374 return s.empty() ?
"0" : s;
384 throw std::invalid_argument(
385 std::string(operation) +
": variable name mismatch ('" +
391 const bool positive = !(coefficient < CoeffType(0));
393 text += positive ?
" + " :
" - ";
394 }
else if (!positive) {
398 coefficient = coefficient * CoeffType(-1);
400 if (!(coefficient == CoeffType(1)) || power == 0) {
401 if constexpr (std::is_same_v<CoeffType, BigInt> ||
402 std::is_same_v<CoeffType, Rational>) {
403 text += coefficient.to_string();
405 text += std::to_string(coefficient);
415 text +=
"^" + std::to_string(power);
432 for (
int i = p.
degree(); i >= 0; --i) {
444 }
else if (
c < T(0)) {
448 T abs_c = (
c < T(0)) ? (
c * T(-1)) :
c;
449 if (abs_c != T(1) || i == 0) {
任意精度整数 BigInt,底层调用 LMMP 实现高性能大数运算。
static Polynomial gcd(Polynomial a, Polynomial b)
计算两个多项式的最大公因式
Polynomial(const std::vector< CoeffType > &c, const std::string &var="x")
从系数向量构造多项式
Polynomial pseudo_div_mod_rem(const Polynomial &other) const
伪除法取余数
CoeffType eval(const CoeffType &val) const
对多项式求值(Horner 法)
Polynomial differentiate() const
求导
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
void require_compatible_variables(const Polynomial &other, const char *operation) const
Polynomial(const std::string &var="x")
构造零多项式
Polynomial operator+(const Polynomial &other) const
多项式加法
std::string variable_name
static CoeffType gcd_coeff(const CoeffType &a, const CoeffType &b)
计算两个系数的 GCD(静态方法)
bool is_zero() const
判断是否为零多项式
std::vector< Rational > coeffs
Polynomial(const CoeffType &c, const std::string &var="x")
从单个常数构造常数多项式
Polynomial primitive_part() const
计算多项式的本原部分(除以容度)
Polynomial square_free_part() const
计算无平方因子部分
std::string to_string() const
转换为字符串表示
std::pair< Polynomial, Polynomial > pseudo_div_mod(const Polynomial &other) const
通过系数缩放执行伪除法,运算保持在原系数环
CoeffType lead_coeff() const
获取首项系数
void append_string_term(std::string &text, Rational coefficient, int power) const
Polynomial operator-(const Polynomial &other) const
多项式减法
int degree() const
获取多项式的次数
CoeffType content() const
计算多项式的容度(所有系数的 GCD)
Polynomial make_monic() const
首一化(使首项系数为 1)
bool variables_compatible(const Polynomial &other) const
bool operator==(const Polynomial &other) const
多项式判等
Polynomial operator*(const Polynomial &other) const
多项式乘法
const VectorField const VectorField & c
T gcd_coeff_impl(const T &a, const T &b)
计算两个系数的最大公约数(泛型实现)
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
std::ostream & operator<<(std::ostream &os, const Polynomial< T > &p)
多项式流输出运算符
精确有理数 Rational,基于 BigInt 分子/分母表示,自动约分。