LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
solve_polynomial_quartic_symbolic.cpp
浏览该文件的文档.
3#include <algorithm>
4#include <cmath>
5#include <limits>
6#include <stdexcept>
7
9
11 const std::shared_ptr<SymbolicExpr>& a, const std::shared_ptr<SymbolicExpr>& b,
12 const std::shared_ptr<SymbolicExpr>& c, const std::shared_ptr<SymbolicExpr>& d,
13 const std::shared_ptr<SymbolicExpr>& e, ComputationContext& context) {
14
15 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
16 (context).limits().max_ast_nodes, "transform");
17 auto a2 = SymbolicExpr::power(a, num(2));
18 auto a3 = SymbolicExpr::power(a, num(3));
19 auto a4 = SymbolicExpr::power(a, num(4));
20 auto b2 = SymbolicExpr::power(b, num(2));
21 auto b3 = SymbolicExpr::power(b, num(3));
22 auto b4 = SymbolicExpr::power(b, num(4));
23
24 auto eight_ac = SymbolicExpr::multiply(num(8), SymbolicExpr::multiply(a, c));
25 auto three_b2 = SymbolicExpr::multiply(num(3), b2);
26 auto p = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(sub(eight_ac, three_b2), SymbolicExpr::multiply(num(8), a2))), transform_budget));
27
28 auto four_abc = SymbolicExpr::multiply(num(4), SymbolicExpr::multiply(a, SymbolicExpr::multiply(b, c)));
29 auto eight_a2d = SymbolicExpr::multiply(num(8), SymbolicExpr::multiply(a2, d));
30 auto q_num = SymbolicExpr::add(sub(b3, four_abc), eight_a2d);
31 auto q = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(q_num, SymbolicExpr::multiply(num(8), a3))), transform_budget));
32
33 auto neg3_b4 = SymbolicExpr::multiply(num(-3), b4);
34 auto t256_a3e = SymbolicExpr::multiply(num(256), SymbolicExpr::multiply(a3, e));
35 auto neg64_a2bd = SymbolicExpr::multiply(num(-64), SymbolicExpr::multiply(a2, SymbolicExpr::multiply(b, d)));
36 auto t16_ab2c = SymbolicExpr::multiply(num(16), SymbolicExpr::multiply(a, SymbolicExpr::multiply(b2, c)));
37 auto r_num = SymbolicExpr::add(SymbolicExpr::add(SymbolicExpr::add(neg3_b4, t256_a3e), neg64_a2bd), t16_ab2c);
38 auto r = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(r_num, SymbolicExpr::multiply(num(256), a4))), transform_budget));
39
40 auto shift = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(b, SymbolicExpr::multiply(num(4), a))), transform_budget));
41 return {p, q, r, shift};
42}
43
44std::vector<std::shared_ptr<SymbolicExpr>> symbolic_quartic_roots(
45 const SymbolicQuarticDepression& depression, const std::string& var,
47 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
48 (context).limits().max_ast_nodes, "transform");
49 const auto& [p, q, r, shift] = depression;
50 auto q_simp = detail::make_expression_ptr(detail::normalize_node(detail::node(q), transform_budget));
51 if (q_simp->get_number_value_is_zero()) {
52
53 auto u_roots = solve_quadratic_internal(num(1), p, r, context);
54 std::vector<std::shared_ptr<SymbolicExpr>> results;
55 for (const auto& u : u_roots) {
56
57 auto pos_y = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::sqrt(u)), transform_budget));
58 auto neg_y = detail::make_expression_ptr(detail::normalize_node(detail::node(negate(SymbolicExpr::sqrt(u))), transform_budget));
59 results.push_back(detail::make_expression_ptr(detail::normalize_node(detail::node(sub(pos_y, shift)), transform_budget)));
60 results.push_back(detail::make_expression_ptr(detail::normalize_node(detail::node(sub(neg_y, shift)), transform_budget)));
61 }
62 return results;
63 }
64
65 auto p2 = SymbolicExpr::power(p, num(2));
66 auto q2 = SymbolicExpr::power(q, num(2));
67 auto eight_p = SymbolicExpr::multiply(num(8), p);
68 auto two_p2_minus_8r = detail::make_expression_ptr(detail::normalize_node(detail::node(sub(SymbolicExpr::multiply(num(2), p2), SymbolicExpr::multiply(num(8), r))), transform_budget));
69 auto neg_q2 = detail::make_expression_ptr(detail::normalize_node(detail::node(negate(q2)), transform_budget));
70
71 auto cubic_roots = solve_cubic_impl(num(8), eight_p, two_p2_minus_8r, neg_q2, var, context);
72
73 std::shared_ptr<SymbolicExpr> m = nullptr;
74 if (!cubic_roots.empty()) {
75 m = cubic_roots[0];
76 }
77
78 if (!m) return {};
79
80 auto two_m = SymbolicExpr::multiply(num(2), m);
81 auto s = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::sqrt(two_m)), transform_budget));
82
83 auto p_half = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(p, num(2))), transform_budget));
84
85 auto m_plus_p_half = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::add(m, p_half)), transform_budget));
86
87 auto q_over_2s = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(q, SymbolicExpr::multiply(num(2), s))), transform_budget));
88
89 auto quad1_c = detail::make_expression_ptr(detail::normalize_node(detail::node(sub(m_plus_p_half, q_over_2s)), transform_budget));
90
91 auto neg_s = detail::make_expression_ptr(detail::normalize_node(detail::node(negate(s)), transform_budget));
92 auto quad2_c = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::add(m_plus_p_half, q_over_2s)), transform_budget));
93
94 auto y_roots1 = solve_quadratic_internal(num(1), s, quad1_c, context);
95 auto y_roots2 = solve_quadratic_internal(num(1), neg_s, quad2_c, context);
96
97 std::vector<std::shared_ptr<SymbolicExpr>> results;
98 for (const auto& y : y_roots1) {
99 results.push_back(detail::make_expression_ptr(detail::normalize_node(detail::node(sub(y, shift)), transform_budget)));
100 }
101 for (const auto& y : y_roots2) {
102 results.push_back(detail::make_expression_ptr(detail::normalize_node(detail::node(sub(y, shift)), transform_budget)));
103 }
104
105 return results;
106}
107
108}
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::shared_ptr< SymbolicExpr > num(int value)
std::vector< std::shared_ptr< SymbolicExpr > > solve_cubic_impl(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, const std::string &variable, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > symbolic_quartic_roots(const SymbolicQuarticDepression &depression, const std::string &variable, ComputationContext &context)
std::shared_ptr< SymbolicExpr > sub(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b)
std::shared_ptr< SymbolicExpr > negate(const std::shared_ptr< SymbolicExpr > &expr)
SymbolicQuarticDepression symbolic_quartic_depression(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, const std::shared_ptr< SymbolicExpr > &e, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > solve_quadratic_internal(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, ComputationContext &context)
ExprResult e()
__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
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
const VectorField const VectorField & c
const MultiPoly & b
__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
__attribute__((visibility("default"))) LineSymbolicResult line_from_two_points_checked(const std __attribute__((visibility("default"))) LineSymbolicResult line_from_two_points_checked(const std __attribute__((visibility("default"))) PlaneSymbolicResult plane_from_three_points_checked(const std __attribute__((visibility("default"))) PlaneSymbolicResult plane_from_three_points_checked(const std const PlaneSymbolic & p2
__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 & u