6std::optional<std::shared_ptr<const SymbolicNode>> LimitVisitor::exact_ratio_at_point(
7 const std::shared_ptr<const SymbolicNode>&
num,
8 const std::shared_ptr<const SymbolicNode>& den) {
9 auto nl = exact_leading_at_point(
num);
10 auto dl = exact_leading_at_point(den);
11 if (nl && dl && dl->first !=
Rational(0)) {
12 if (nl->first ==
Rational(0) || nl->second > dl->second)
14 Rational coefficient = nl->first / dl->first;
16 if (
direction.empty() && (dl->second - nl->second) % 2) {
return std::shared_ptr<const SymbolicNode>{}; }
19 return signed_infinity(sign);
24std::shared_ptr<const SymbolicNode> LimitVisitor::evaluated_product_ratio(
25 const std::shared_ptr<const SymbolicNode>&
num,
26 const std::shared_ptr<const SymbolicNode>& den,
bool at_infinity) {
27 auto numerator = eval_limit(
num);
29 bool numerator_zero = is_zero_limit(numerator);
31 const bool both_infinite = is_inf(numerator) && is_inf(
denominator);
32 if (both_infinite && at_infinity) {
33 auto growth = limit_by_growth_comparison(
num, den);
38 if ((numerator_zero && denominator_zero) || both_infinite) {
39 auto value = apply_lhopital(
num, den);
44 if (!numerator_zero && denominator_zero) {
45 return singular_ratio_limit(
num, den);
50bool LimitVisitor::positive_tail_product_limit(
const MultiplyNode& node) {
51 std::vector<std::shared_ptr<const SymbolicNode>> rewritten;
53 for (
const auto& operand :
node.operands()) {
54 auto function = std::dynamic_pointer_cast<const FunctionNode>(operand);
57 rewritten.push_back(replacement ? replacement : operand);
66std::shared_ptr<const SymbolicNode> LimitVisitor::resolve_product_factors(
67 const MultiplyNode& node,
const std::vector<std::shared_ptr<const SymbolicNode>>& values) {
68 std::vector<std::shared_ptr<const SymbolicNode>> numerator,
denominator;
69 for (
const auto& operand :
node.operands()) {
70 auto factor = denominator_factor(operand);
72 else { numerator.push_back(operand); }
74 std::shared_ptr<const SymbolicNode> resolved;
76 if (classify_product_form(values) == IndeterminateForm::ZeroTimesInf) {
77 resolved = resolve_zero_times_inf(
node.operands(), values);
80 auto num = make_product_or_one(numerator);
82 resolved = product_ratio_limit(
num, den);
89std::shared_ptr<const SymbolicNode> LimitVisitor::product_ratio_limit(
90 const std::shared_ptr<const SymbolicNode>&
num,
91 const std::shared_ptr<const SymbolicNode>& den) {
92 const bool at_infinity = is_limit_at_infinity() || is_limit_at_neg_infinity();
94 auto exact = exact_ratio_at_point(
num, den);
95 if (exact) {
return std::move(*exact); }
98 auto rational = limit_rational_at_infinity(
num, den);
103 return evaluated_product_ratio(
num, den, at_infinity);
107 if (is_limit_at_neg_infinity()) {
114 if (is_limit_at_infinity()) {
115 if (positive_tail_product_limit(node)) {
return; }
117 if (logarithmic_zero_product(node)) {
121 if (is_limit_at_infinity()) {
122 if (logarithmic_product_limit(node)) {
125 if (decaying_exponential_product(node)) {
130 if (trigonometric_product_limit(node)) {
138 std::vector<std::shared_ptr<const SymbolicNode>> values;
139 for (
const auto& operand :
node.operands()) {
140 operand->accept(*
this);
141 values.push_back(result);
143 std::shared_ptr<const SymbolicNode> substituted;
144 if (std::all_of(values.begin(), values.end(), [](
const auto&
value) { return value != nullptr; })) {
147 substituted = norm.get_result();
149 auto resolved = resolve_product_factors(node, values);
150 result = resolved ? resolved : substituted;
统一规范化数值幂。 精确操作数保留整数和有理数运算;近似求根要求指数精确等于 1/2。 有限浮点幂直接折叠,省去倒数中间值;非有限结果保留幂表达式。
极限访问器,通过代入和 L'Hôpital 法则计算极限。
int sign(const Rational &value)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
const std::string const SymbolicNodePtr & replacement
const FactsQuery & no_facts() noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
std::shared_ptr< SymbolicExpr > num(int value)
@ Rational
Rational numbers
std::size_t std::size_t std::size_t growth
const std::string const LimitExprPtr LimitDirection direction
const std::string const ExprPtr & value
const ExprPtr & denominator
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
ExprResult rational(const Rational &value)