42MultiPoly::MultiPoly(std::vector<Term> terms, std::vector<std::string> vars,
43 MonomialOrderType order)
44 : terms_(std::move(terms)), vars_(std::move(
vars)), order_(
order)
47 for (
auto& term : terms_) {
48 if (term.first.size() < vars_.size()) {
49 term.first.resize(vars_.size(), 0);
64MultiPoly::MultiPoly(
const Rational& constant,
const std::vector<std::string>& vars)
65 : terms_(), vars_(
vars), order_(MonomialOrderType::
GrevLex)
67 if (!constant.is_zero()) {
68 Monomial zero_mono(vars_.size(), 0);
69 terms_.emplace_back(std::move(zero_mono), constant);
85void MultiPoly::normalize()
87 if (terms_.empty())
return;
90 MonomialOrder cmp(order_);
91 std::sort(terms_.begin(), terms_.end(),
92 [&cmp](
const Term& a,
const Term& b) {
93 return cmp(a.first, b.first);
97 std::vector<Term> merged;
98 merged.reserve(terms_.size());
100 for (
size_t i = 0; i < terms_.size(); ) {
101 Monomial current_mono = terms_[i].first;
102 Rational coeff_sum = terms_[i].second;
106 while (j < terms_.size() && terms_[j].first == current_mono) {
107 coeff_sum = coeff_sum + terms_[j].second;
112 if (!coeff_sum.is_zero()) {
113 merged.emplace_back(std::move(current_mono), std::move(coeff_sum));
119 terms_ = std::move(merged);
123bool MultiPoly::is_zero()
const
125 return terms_.empty();
128bool MultiPoly::is_constant()
const
130 if (terms_.empty())
return true;
131 if (terms_.size() != 1)
return false;
133 for (
int exp : terms_[0].first) {
134 if (exp != 0)
return false;
139bool MultiPoly::is_univariate()
const
141 if (terms_.empty())
return true;
143 int active_count = 0;
144 for (
size_t vi = 0; vi < vars_.size(); ++vi) {
146 for (
const auto& term : terms_) {
147 if (vi < term.first.size() && term.first[vi] != 0) {
152 if (active) ++active_count;
153 if (active_count > 1)
return false;
158bool MultiPoly::is_homogeneous()
const
160 if (terms_.empty())
return true;
162 for (
size_t i = 1; i < terms_.size(); ++i) {
168int MultiPoly::num_terms()
const
170 return static_cast<int>(terms_.size());
173int MultiPoly::num_vars()
const
175 return static_cast<int>(vars_.size());
178const std::vector<std::string>& MultiPoly::variables()
const
183const std::vector<MultiPoly::Term>& MultiPoly::terms()
const
188int MultiPoly::total_degree()
const
190 if (terms_.empty())
return -1;
192 for (
const auto& term : terms_) {
194 if (deg > max_deg) max_deg = deg;
199int MultiPoly::degree(
const std::string& var)
const
201 if (terms_.empty())
return -1;
204 for (
size_t i = 0; i < vars_.size(); ++i) {
205 if (vars_[i] == var) {
206 var_idx =
static_cast<int>(i);
210 if (var_idx < 0)
return 0;
213 for (
const auto& term : terms_) {
214 if (
static_cast<size_t>(var_idx) < term.first.size()) {
215 if (term.first[var_idx] > max_exp) {
216 max_exp = term.first[var_idx];
232MultiPoly MultiPoly::leading_coeff(
const std::string& var)
const
234 if (terms_.empty()) {
240 for (
size_t i = 0; i < vars_.size(); ++i) {
241 if (vars_[i] == var) {
242 var_idx =
static_cast<int>(i);
254 for (
const auto& term : terms_) {
255 if (
static_cast<size_t>(var_idx) < term.first.size()) {
256 if (term.first[var_idx] > max_exp) {
257 max_exp = term.first[var_idx];
263 std::vector<std::string> remaining_vars;
264 remaining_vars.reserve(vars_.size() - 1);
265 for (
size_t i = 0; i < vars_.size(); ++i) {
266 if (
static_cast<int>(i) != var_idx) {
267 remaining_vars.push_back(vars_[i]);
272 std::vector<Term> lc_terms;
273 for (
const auto& term : terms_) {
274 int exp_val = (
static_cast<size_t>(var_idx) < term.first.size())
275 ? term.first[var_idx] : 0;
276 if (exp_val == max_exp) {
278 reduced_mono.reserve(vars_.size() - 1);
279 for (
size_t i = 0; i < term.first.size(); ++i) {
280 if (
static_cast<int>(i) != var_idx) {
281 reduced_mono.push_back(term.first[i]);
284 lc_terms.emplace_back(std::move(reduced_mono), term.second);
288 return MultiPoly(std::move(lc_terms), std::move(remaining_vars), order_);
303std::string MultiPoly::to_string()
const
305 if (terms_.empty()) {
309 std::ostringstream oss;
311 for (
size_t i = 0; i < terms_.size(); ++i) {
312 const Rational& coeff = terms_[i].second;
313 const Monomial& mono = terms_[i].first;
316 bool is_const_term =
true;
317 for (
size_t vi = 0; vi < mono.size(); ++vi) {
319 is_const_term =
false;
325 bool negative = coeff <
Rational(0);
330 if (negative) oss <<
"-";
341 oss << abs_coeff.to_string();
346 bool coeff_is_one = (abs_coeff ==
Rational(1));
348 oss << abs_coeff.to_string() <<
"*";
352 bool first_var =
true;
353 for (
size_t vi = 0; vi < mono.size() && vi < vars_.size(); ++vi) {
354 if (mono[vi] == 0)
continue;
363 oss <<
"^" << mono[vi];
多元多项式类 MultiPoly,稀疏表示,支持任意数量变量上的环运算。
ExpressionResult normalize(const Node &value, ComputationContext &context)
std::vector< int > Monomial
单项式类型,以整数向量表示各变量的指数
__attribute__((visibility("default"))) VectorCalculusFieldResult gradient_checked(const std __attribute__((visibility("default"))) VectorCalculusFieldResult gradient_checked(const std __attribute__((visibility("default"))) VectorField gradient(const std const std::vector< std::string > & vars
const std::vector< FGLMPoly > const MonomialOrder & order
@ Rational
Rational numbers
int total_degree(const Monomial &m)
计算单项式的全次数
MonomialOrderType
单项式序的类型枚举