29 (
context).limits().max_ast_nodes,
"transform");
41 if (std::holds_alternative<BigInt>(
num->value())) {
42 const auto&
value = std::get<BigInt>(
num->value());
43 if (
value.is_zero()) {
46 return value.is_negative() ? -1 : 1;
48 const auto&
value = std::get<Rational>(
num->value());
49 if (
value.get_numerator().is_zero()) {
52 return value.get_numerator().is_negative() ? -1 : 1;
58 (
context).limits().max_ast_nodes,
"transform");
81 if (std::holds_alternative<BigInt>(
num->value())) {
82 return std::get<BigInt>(
num->value()).is_negative() ? -1 : 1;
84 if (std::holds_alternative<Rational>(
num->value())) {
85 return std::get<Rational>(
num->value()).get_numerator().is_negative() ? -1 : 1;
102 const Rational candidate = Rational::from_double(*numeric);
103 if (!candidate.is_integer()) {
106 if (poly.
eval(candidate) == Rational(0)) {
107 return SymbolicExpr::number(candidate);
117 const std::vector<std::shared_ptr<SymbolicExpr>>&
roots,
119 for (
const auto& root :
roots) {
135 if (
a != Rational(0)) {
136 Rational root_val = Rational(0) -
b /
a;
137 auto root_expr = SymbolicExpr::number(root_val);
139 result.push_back({root_expr, mult});
151 Rational disc =
b *
b - Rational(4) *
a *
c;
152 if (disc < Rational(0)) {
155 double disc_val = disc.to_double();
157 double a_val =
a.to_double();
158 double b_val =
b.to_double();
159 double sqrt_disc = std::sqrt(disc_val);
163 if (sqrt_disc == 0.0) {
164 r1 = -b_val / (2.0 * a_val);
168 -0.5 * b_val - 0.5 * std::copysign(sqrt_disc, b_val);
170 r2 =
c.to_double() / q;
173 if (std::isfinite(r1)) {
175 result.push_back({root, mult});
177 if (std::isfinite(r2) && r2 != r1) {
179 result.push_back({root, mult});
186 std::vector<SymbolicPolyCoeff> spc_coeffs;
187 for (
int i = 0; i <= factor.
degree(); ++i) {
198 const std::shared_ptr<SymbolicExpr>& expr,
201 std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
int>> result;
203 auto converted = symbolic_to_poly<Rational>(expr,
variable);
204 if (!converted)
throw std::invalid_argument(converted.error().message);
205 const auto& poly_rat = converted.value();
206 if (poly_rat.is_zero() || poly_rat.degree() <= 0) {
211 if (factors.empty()) {
212 auto symbolic = symbolic_to_poly<SymbolicPolyCoeff>(expr,
variable);
213 if (!symbolic)
throw std::invalid_argument(symbolic.error().message);
214 const auto& poly_spc = symbolic.value();
215 if (!poly_spc.is_zero() && poly_spc.degree() >= 1) {
222 for (
const auto& [factor, mult] : factors) {
223 if (factor.degree() <= 0) {
226 if (factor.degree() == 1) {
228 }
else if (factor.degree() == 2) {
238 const std::vector<std::string>& parameters) {
242 for (
const auto& param : parameters) {
254 (
context).limits().max_ast_nodes,
"transform");
261 auto get_coeff = [&](
int d) -> std::shared_ptr<SymbolicExpr> {
262 if (d < 0 || d > deg) {
263 return SymbolicExpr::number(0);
265 return poly.
coeffs[d].val ? poly.
coeffs[d].val : SymbolicExpr::number(0);
272 auto neg_b = SymbolicExpr::multiply(
b, SymbolicExpr::number(-1));
CoeffType eval(const CoeffType &val) const
对多项式求值(Horner 法)
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
CoeffType lead_coeff() const
获取首项系数
int degree() const
获取多项式的次数
不等式求解器 InequalitySolver,支持多项式,有理式,参数化不等式.
static void append_affine_root(RootMultiplicityList &result, const Polynomial< Rational > &factor, int mult, ComputationContext &context)
static void append_quadratic_roots(RootMultiplicityList &result, const Polynomial< Rational > &factor, int mult, ComputationContext &context)
static void append_verified_roots(RootMultiplicityList &result, const Polynomial< Rational > &polynomial, const std::vector< std::shared_ptr< SymbolicExpr > > &roots, int multiplicity, ComputationContext &context)
std::vector< std::pair< std::shared_ptr< SymbolicExpr >, int > > find_roots_with_multiplicity(const std::shared_ptr< SymbolicExpr > &expr, const std::string &variable, ComputationContext &context)
static std::shared_ptr< SymbolicExpr > snap_verified_integer_root(const Polynomial< Rational > &poly, const std::shared_ptr< SymbolicExpr > &root, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > solve_symbolic_poly(const Polynomial< SymbolicPolyCoeff > &poly, const std::string &variable, ComputationContext &context)
static void append_factor_roots(RootMultiplicityList &result, const Polynomial< Rational > &factor, int mult, const std::string &variable, ComputationContext &context)
int exact_numeric_sign(const std::shared_ptr< SymbolicExpr > &expr, ComputationContext &context)
std::vector< std::pair< std::shared_ptr< SymbolicExpr >, int > > RootMultiplicityList
std::optional< double > try_checked_numeric_constant(const SymbolicExpr &expr, ComputationContext &context)
bool depends_on_any_param(const std::shared_ptr< SymbolicExpr > &expr, const std::vector< std::string > ¶meters)
int determine_leading_sign(const Polynomial< SymbolicPolyCoeff > &poly, ComputationContext &context)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
const std::string & variable
std::size_t std::size_t multiplicity
std::optional< double > try_finite_numeric(const SymbolicExpr &expression, ComputationContext &context)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::size_t std::size_t ComputationContext & context
std::shared_ptr< SymbolicExpr > num(int value)
std::vector< std::shared_ptr< SymbolicExpr > > solve_by_factoring_impl(const Polynomial< SymbolicPolyCoeff > &polynomial, const std::string &variable, ComputationContext &context)
std::vector< std::pair< Polynomial< Rational >, int > > square_free_factorization(const Polynomial< Rational > &poly)
const VectorField const VectorField & c
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)
__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::shared_ptr< SymbolicExpr > get_coeff(const Polynomial< SymbolicPolyCoeff > &p, int deg)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
const std::string const ExprPtr & value
方程求解策略调度器 solve_dispatch 及相关选项结构体.