6 const std::string& var,
12 std::vector<std::pair<std::vector<Polynomial<Rational>>,
13 std::vector<Polynomial<Rational>>>> parts;
14 parts.reserve(
add.operands().size());
15 for (
const auto&
op :
add.operands()) {
16 std::vector<Polynomial<Rational>> sub_num, sub_den;
18 if (!collected || !collected.value()) {
return collected; }
19 parts.push_back({std::move(sub_num), std::move(sub_den)});
25 std::vector<Polynomial<Rational>> Q_per_term;
26 Q_per_term.reserve(parts.size());
27 for (
const auto& [pn, pd] : parts) {
29 for (
const auto& d : pd) q = q * d;
30 Q_per_term.push_back(q);
31 total_den = total_den * q;
34 for (
size_t i = 0; i < parts.size(); ++i) {
36 for (
const auto& nn : parts[i].first) p = p * nn;
37 for (
size_t j = 0; j < parts.size(); ++j) {
38 if (j == i) {
continue; }
39 p = p * Q_per_term[j];
41 total_num = total_num + p;
44 num.push_back(total_num);
45 den.push_back(total_den);
51 auto en = std::dynamic_pointer_cast<const NumberNode>(pw.
exponent());
52 if (!en) {
return false; }
55 if (!bounded_exponent) {
return false; }
57 std::vector<Polynomial<Rational>> bn, bd;
59 if (!collected || !collected.value()) {
return collected; }
62 for (
const auto& p : bn) base_num = base_num * p;
64 for (
const auto& p : bd) base_den = base_den * p;
66 if (*bounded_exponent == 0) {
70 const int power_count = *bounded_exponent < 0 ? -*bounded_exponent : *bounded_exponent;
73 for (
int i = 0; i < power_count; ++i) {
74 n_pow = n_pow * base_num;
75 d_pow = d_pow * base_den;
77 if (*bounded_exponent > 0) {
88 const std::string& var,
91 if (!node) {
return false; }
93 if (
auto n = std::dynamic_pointer_cast<const NumberNode>(node)) {
99 num.push_back(std::move(p.value()));
102 if (
auto v = std::dynamic_pointer_cast<const VariableNode>(node)) {
103 if (!
v->is_constant() &&
v->name() == var) {
110 if (
auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
113 if (
auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
114 for (
const auto&
op :
mul->operands()) {
116 if (!collected || !collected.value()) {
return collected; }
121 if (
auto power = std::dynamic_pointer_cast<const PowerNode>(node)) {
128 const std::string& var) {
134 if (pq.second.is_zero() && qq.second.is_zero()) {
143 if (!(lc == Rational(1)) && !(lc == Rational(0))) {
146 for (
const auto&
c : P.
coeffs) { P_scaled.
coeffs.push_back(
c / lc); }
149 for (
const auto&
c : Q.
coeffs) { Q_scaled.
coeffs.push_back(
c / lc); }
161 const SymbolicExpr& expr,
const std::string& var,
164 std::vector<Polynomial<Rational>> nums, dens;
166 if (!collected || !collected.value()) {
return collected; }
169 for (
const auto& p : nums) { P = P * p; }
171 for (
const auto& p : dens) { Q = Q * p; }
173 if (Q.is_zero()) {
return false; }
175 rd_normalize_fraction(P, Q, var);
static Polynomial gcd(Polynomial a, Polynomial b)
计算两个多项式的最大公因式
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
CoeffType lead_coeff() const
获取首项系数
int degree() const
获取多项式的次数
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
static Result failure(CasErrc code, std::string message, std::string operation={})
Result< bool > rd_collect_power(const PowerNode &pw, const std::string &var, std::vector< Polynomial< Rational > > &num, std::vector< Polynomial< Rational > > &den)
Result< bool > rd_collect_rational(const std::shared_ptr< const SymbolicNode > &node, const std::string &var, std::vector< Polynomial< Rational > > &num, std::vector< Polynomial< Rational > > &den)
void rd_normalize_fraction(Polynomial< Rational > &P, Polynomial< Rational > &Q, const std::string &var)
Result< bool > rd_collect_sum(const AddNode &add, const std::string &var, std::vector< Polynomial< Rational > > &num, std::vector< Polynomial< Rational > > &den)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
Result< bool > extract_rational(const SymbolicExpr &expr, const std::string &var, Polynomial< Rational > &numerator, Polynomial< Rational > &denominator)
std::shared_ptr< SymbolicExpr > num(int value)
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string & v
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const VectorField const VectorField & c
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const ExprPtr RelationOp op
std::optional< int > integration_bounded_exponent(const NumberNode &number, int minimum_exponent, int maximum_exponent)