10 return value < Rational(0) ? -1 :
value > Rational(0) ? 1 : 0;
15 if (!number)
return std::nullopt;
26 if (
function->arguments().size() != 1)
return nullptr;
30 }
else if (
const auto* power =
dynamic_cast<const PowerNode*
>(&
node)) {
33 radicand = power->base();
34 }
else return nullptr;
35 const auto* square =
dynamic_cast<const PowerNode*
>(radicand.get());
36 if (!square)
return nullptr;
47 bool infinity =
false;
48 for (
const auto& factor : m->operands()) {
50 if (infinity)
return 0;
59 return infinity ? result : 0;
72 "nonfinite numeric endpoint requires a typed infinity",
operation);
75 root->exact_id().polynomial, root->index(), 1,
context);
84 if (
a.infinity ||
b.infinity)
85 {
return a.infinity <
b.infinity ? -1 :
a.infinity >
b.infinity ? 1 : 0; }
88 right.polynomial.variable_name = left.polynomial.variable_name;
89 if (!(left.upper <
right.lower) && !(
right.upper < left.lower)) {
92 if (equal.value()) {
return 0; }
93 while (!(left.upper <
right.lower) && !(
right.upper < left.lower)) {
105 if (!terms)
return terms;
106 for (
const auto& coefficient : polynomial.
coeffs) {
107 auto checked =
context.require_integer_bits(std::max(
108 coefficient.get_numerator().bit_length(),
109 coefficient.get_denominator().bit_length()),
operation);
110 if (!checked)
return checked;
116 const auto size =
a.coeffs.size() +
b.coeffs.size();
119 if (size >
static_cast<std::size_t
>(std::numeric_limits<int>::max()))
121 "polynomial degree exceeds representation",
operation);
131 while (!
b.is_zero()) {
134 auto remainder =
a.div_mod(
b).second;
138 b = std::move(remainder);
140 return a.make_monic();
146 for (
const auto& operand : operands) {
148 if (!child || !child.value()) {
return child; }
150 sum ? child.value()->denominator : child.value()->numerator,
context);
155 n.value() = n.value() + other.value();
159 result = {std::move(n.value()), std::move(d.value())};
161 return std::optional<RationalFunction>{std::move(result)};
167 if (!
exponent || !
exponent->is_integer()) {
return std::optional<RationalFunction>{}; }
169 if (!base || !base.value()) {
return base; }
170 BigInt count =
exponent->to_bigint();
171 if (count < BigInt(0)) {
172 std::swap(base.value()->numerator, base.value()->denominator);
176 while (count != BigInt(0)) {
177 if (count % BigInt(2) != BigInt(0)) {
182 result = {std::move(n.value()), std::move(d.value())};
184 count = count / BigInt(2);
185 if (count == BigInt(0)) {
break; }
190 base.value() =
RationalFunction{std::move(n.value()), std::move(d.value())};
192 return std::optional<RationalFunction>{std::move(result)};
201 if (polynomial.value()) {
return std::optional<RationalFunction>{
203 const auto* sum =
dynamic_cast<const AddNode*
>(
node.get());
205 if (sum || product) {
207 sum ? sum->operands() : product->operands(), sum !=
nullptr, var,
context);
209 if (
const auto* power =
dynamic_cast<const PowerNode*
>(
node.get())) {
212 return std::optional<RationalFunction>{};
218 auto bits =
context.require_integer_bits(2 * denominator_bound.bit_length() + 2,
operation);
219 if (!bits) {
return bits; }
220 const Rational separation(BigInt(1), BigInt(2) * denominator_bound * denominator_bound);
221 while (root.
upper - root.
lower >= separation) {
223 if (!refined) {
return refined; }
230 const Rational midpoint = (root.
lower + root.
upper) / Rational(2);
231 BigInt numerator = midpoint.get_numerator(),
denominator = midpoint.get_denominator();
232 BigInt old_p(0), p(1), old_q(1), q(0);
235 if (!step) {
return step; }
238 if (remainder < BigInt(0)) { quotient = quotient - BigInt(1); remainder = remainder +
denominator; }
239 BigInt next_p = quotient * p + old_p;
240 BigInt next_q = quotient * q + old_q;
241 if (next_q > denominator_bound) {
break; }
242 Rational candidate(next_p, next_q);
243 if (candidate >= root.
lower && candidate <= root.
upper &&
248 old_p = std::move(p); p = std::move(next_p);
249 old_q = std::move(q); q = std::move(next_q);
256 if (polynomial.
degree() <= 0)
return std::vector<Algebraic>{};
259 auto square_free = polynomial.
div_mod(repeated.value()).first.make_monic();
260 BigInt denominator_bound(1);
261 for (
const auto& coefficient : square_free.coeffs) {
262 const auto&
denominator = coefficient.get_denominator();
264 auto checked =
context.require_integer_bits(denominator_bound.bit_length(),
operation);
269 std::vector<Algebraic>
roots;
270 for (std::size_t i = 0; i < isolated.value().size(); ++i) {
271 Algebraic root{square_free, isolated.value()[i].first, isolated.value()[i].second, i, 1};
274 roots.push_back(std::move(root));
281 if (polynomial.
is_zero())
return std::optional<int>{0};
290 if (left.value() < 0 &&
right.value() < 0)
return std::optional<int>{};
294 (polynomial.
degree() % 2 ? -1 : 1)};
295 if (
b.infinity > 0)
return std::optional<int>{
sign(polynomial.
lead_coeff())};
296 auto left =
a.finite;
298 while (!(left.upper <
right.lower)) {
304 return std::optional<int>{
sign(polynomial.
eval((left.upper +
right.lower) / Rational(2)))};
309 if (polynomial.
is_zero()) {
return 0; }
313 if (common.value().degree() > 0) {
316 if (zeros.value()) {
return 0; }
321 if (!zeros.value()) {
return sign(polynomial.
eval(root.
lower)); }
343 int denominator_sign = 0;
349 denominator_sign =
value.value();
350 }
while (!denominator_sign);
353 int coefficient_sign = numerator_sign.value() * denominator_sign;
355 "reduced rational pole has a zero numerator",
operation); }
369 if (
rational.numerator.is_zero()) {
return 0; }
377 const int degree =
rational.numerator.degree() -
rational.denominator.degree();
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
CoeffType eval(const CoeffType &val) const
对多项式求值(Horner 法)
Polynomial differentiate() const
求导
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={})
static Result success(T value)
static Result< void > polynomial_budget(const Poly &polynomial, ComputationContext &context)
Result< int > rational_divergence_checked(RationalFunction &rational, const Boundary &a, const Boundary &b, ComputationContext &context)
Result< std::optional< RationalFunction > > RationalResult
Result< Poly > product_checked(const Poly &a, const Poly &b, ComputationContext &context)
static int sign(const Rational &value)
std::optional< Rational > exact_number(const Node &node)
static bool include_divergence(int &divergence, int contribution)
Result< int > compare_boundaries(const Boundary &a, const Boundary &b, ComputationContext &context)
static Result< void > recover_rational_cut(Algebraic &root, const BigInt &denominator_bound, ComputationContext &context)
static Result< void > rational_pole_divergence(const RationalFunction &rational, const Algebraic &root, const Boundary &a, const Boundary &b, int &divergence, ComputationContext &context)
std::shared_ptr< const SymbolicNode > Node
Polynomial< Rational > Poly
ExactRealAlgebraic Algebraic
static RationalResult rational_operands_checked(const std::vector< Node > &operands, bool sum, const std::string &var, ComputationContext &context)
static RationalResult rational_power_checked(const PowerNode &power, const std::string &var, ComputationContext &context)
Result< std::optional< int > > polynomial_sign_checked(const Poly &polynomial, const Boundary &a, const Boundary &b, ComputationContext &context)
int infinity_sign(const Node &node)
Result< Boundary > boundary_checked(const SymbolicExpr &expression, ComputationContext &context)
RationalResult rational_checked(const Node &node, const std::string &var, ComputationContext &context)
Node absolute_argument(const SymbolicNode &node)
识别绝对值节点及公共接口的平方开根表示。
static Result< Poly > gcd_checked(Poly a, Poly b, ComputationContext &context)
Result< std::vector< Algebraic > > roots_checked(const Poly &polynomial, ComputationContext &context)
static Result< int > polynomial_at_root_sign(Poly polynomial, Algebraic root, ComputationContext &context)
constexpr const char * operation
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
Result< std::vector< RationalInterval > > isolate_real_roots_exact(const Polynomial< Rational > &polynomial, ComputationContext &context, const std::string &operation)
Result< std::size_t > count_real_roots_exact(const Polynomial< Rational > &polynomial, const Rational &lower, const Rational &upper, ComputationContext &context, const std::string &operation)
Result< int > compare_exact_real_algebraic(ExactRealAlgebraic lhs, ExactRealAlgebraic rhs, ComputationContext &context)
std::size_t std::size_t multiplicity
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
Result< void > refine_exact_real_algebraic(ExactRealAlgebraic &value, ComputationContext &context, const std::string &operation)
ExactRealAlgebraicResult make_exact_real_algebraic(Polynomial< Rational > polynomial, std::size_t root_index, std::size_t multiplicity, ComputationContext &context)
std::size_t std::size_t ComputationContext & context
Result< bool > equal_exact_real_algebraic(ExactRealAlgebraic lhs, ExactRealAlgebraic rhs, ComputationContext &context)
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
__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 > divergence(const VectorField &F, const std::vector< std::string > &vars)
Result< OptionalRationalPolynomial > recognize_rational_polynomial(const SymbolicExpr &expression, const std::string &variable, ComputationContext &context)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
const std::string const ExprPtr & value
Rational exact_number_as_rational(const NumberNode &node)
const ExprPtr & denominator
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
ExprResult rational(const Rational &value)
Polynomial< Rational > polynomial
bool is_rational() const noexcept