LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
multivariate_poly_evaluation.cpp
浏览该文件的文档.
2#include <stdexcept>
3
4namespace LMCAS {
5
6/**
7 * @brief 将指定变量代入有理数值,返回降维后的多项式
8 *
9 * 对每一项,将 val 的对应指数次幂乘入系数,然后从单项式中移除该变量维度。
10 * 结果多项式的变量数减一(若变量存在于列表中)。
11 *
12 * @param[in] var 待代入的变量名
13 * @param[in] val 代入值
14 * @return 代入后的多项式(变量数减一或不变)
15 */
16MultiPoly MultiPoly::eval(const std::string& var, const Rational& val) const
17{
18 int var_idx = -1;
19 for (size_t i = 0; i < vars_.size(); ++i) {
20 if (vars_[i] == var) {
21 var_idx = static_cast<int>(i);
22 break;
23 }
24 }
25 if (var_idx < 0) {
26 return *this;
27 }
28
29 std::vector<std::string> new_vars;
30 new_vars.reserve(vars_.size() - 1);
31 for (size_t i = 0; i < vars_.size(); ++i) {
32 if (static_cast<int>(i) != var_idx) {
33 new_vars.push_back(vars_[i]);
34 }
35 }
36
37 std::vector<Term> new_terms;
38 new_terms.reserve(terms_.size());
39
40 for (const auto& term : terms_) {
41 int exp = (static_cast<size_t>(var_idx) < term.first.size())
42 ? term.first[var_idx] : 0;
43
44 Rational new_coeff = term.second;
45 if (exp > 0) {
46 if (val.is_zero()) {
47 continue;
48 }
49 new_coeff = new_coeff * val.power(BigInt(exp));
50 }
51 Monomial reduced_mono;
52 reduced_mono.reserve(vars_.size() - 1);
53 for (size_t i = 0; i < term.first.size(); ++i) {
54 if (static_cast<int>(i) != var_idx) {
55 reduced_mono.push_back(term.first[i]);
56 }
57 }
58
59 new_terms.emplace_back(std::move(reduced_mono), std::move(new_coeff));
60 }
61
62 return MultiPoly(std::move(new_terms), std::move(new_vars), order_);
63}
64
65/**
66 * @brief 将多个变量同时代入有理数值
67 *
68 * 依次对每个 (var, val) 对调用单变量 eval,逐步降维。
69 *
70 * @param[in] substitution 变量名到值的映射
71 * @return 代入后的多项式
72 */
73MultiPoly MultiPoly::eval(const std::map<std::string, Rational>& substitution) const
74{
75 MultiPoly result = *this;
76 for (const auto& [var, val] : substitution) {
77 result = result.eval(var, val);
78 }
79 return result;
80}
81
82
83/**
84 * @brief 将多元多项式转换为一元 Polynomial<Rational>
85 *
86 * 仅当多项式实际只含一个有效变量(或为常数/零多项式)时有效。
87 * 将单项式中该变量的指数映射为系数向量的下标。
88 *
89 * @return 等价的一元多项式
90 * @throw std::invalid_argument 含多个有效变量时抛出
91 */
92Polynomial<Rational> MultiPoly::to_univariate() const
93{
94 if (!is_univariate()) {
95 throw std::invalid_argument(
96 "MultiPoly::to_univariate: polynomial is not univariate");
97 }
98
99 if (terms_.empty()) {
100 return Polynomial<Rational>(vars_.empty() ? "x" : vars_[0]);
101 }
102 int active_idx = -1;
103 for (size_t vi = 0; vi < vars_.size(); ++vi) {
104 for (const auto& term : terms_) {
105 if (vi < term.first.size() && term.first[vi] != 0) {
106 active_idx = static_cast<int>(vi);
107 break;
108 }
109 }
110 if (active_idx >= 0) break;
111 }
112 std::string var_name = vars_.empty() ? "x" : vars_[0];
113 if (active_idx < 0) {
114 Rational c = terms_[0].second;
115 return Polynomial<Rational>(c, var_name);
116 }
117
118 var_name = vars_[static_cast<size_t>(active_idx)];
119
120 int max_deg = 0;
121 for (const auto& term : terms_) {
122 int exp = term.first[static_cast<size_t>(active_idx)];
123 if (exp > max_deg) max_deg = exp;
124 }
125 std::vector<Rational> coeffs(static_cast<size_t>(max_deg + 1), Rational(0));
126 for (const auto& term : terms_) {
127 int exp = term.first[static_cast<size_t>(active_idx)];
128 coeffs[static_cast<size_t>(exp)] = term.second;
129 }
130
131 return Polynomial<Rational>(coeffs, var_name);
132}
133
134/**
135 * @brief 从一元多项式构造多元多项式
136 *
137 * 将 Polynomial<Rational> 的每个非零系数映射为含单变量单项式的项。
138 *
139 * @param[in] poly 一元多项式
140 * @param[in] var 对应的变量名
141 * @return 等价的 MultiPoly 表示
142 */
143MultiPoly MultiPoly::from_univariate(const Polynomial<Rational>& poly,
144 const std::string& var)
145{
146 std::vector<std::string> vars = {var};
147
148 if (poly.is_zero()) {
149 return MultiPoly(std::vector<Term>{}, vars);
150 }
151
152 std::vector<Term> terms;
153 for (size_t i = 0; i < poly.coeffs.size(); ++i) {
154 if (!poly.coeffs[i].is_zero()) {
155 Monomial mono = {static_cast<int>(i)};
156 terms.emplace_back(std::move(mono), poly.coeffs[i]);
157 }
158 }
159
160 return MultiPoly(std::move(terms), std::move(vars));
161}
162
163}
一元多项式模板类
多元多项式类 MultiPoly,稀疏表示,支持任意数量变量上的环运算。
ExprResult exp(const ExprPtr &expression, 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
@ Rational
Rational numbers
const VectorField const VectorField & c