19 const std::string& var) {
20 auto fn = std::dynamic_pointer_cast<const FunctionNode>(node);
21 if (!fn || fn->type() !=
t) {
return false; }
22 if (fn->arguments().size() != 1) {
return false; }
23 auto v = std::dynamic_pointer_cast<const VariableNode>(fn->arguments()[0]);
24 return v && !
v->is_constant() &&
v->name() == var;
30 const std::string& var) {
31 auto pw = std::dynamic_pointer_cast<const PowerNode>(node);
32 if (!pw) {
return false; }
33 auto b = std::dynamic_pointer_cast<const VariableNode>(pw->base());
34 if (!
b ||
b->is_constant() ||
b->name() != var) {
return false; }
41 const std::string& var) {
42 auto pw = std::dynamic_pointer_cast<const PowerNode>(node);
43 if (!pw) {
return false; }
53 const std::string& var,
54 std::vector<std::shared_ptr<const SymbolicNode>>& other_factors,
56 other_factors.clear();
58 std::vector<std::shared_ptr<const SymbolicNode>> factors;
59 if (
auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
60 factors =
mul->operands();
62 factors.push_back(node);
64 for (
const auto& f : factors) {
66 if (has_inv_var) {
return false; }
69 other_factors.push_back(f);
82 const std::string& var,
84 auto fn = std::dynamic_pointer_cast<const FunctionNode>(node);
86 if (fn->arguments().size() != 1) {
return false; }
90 if (!converted.value()) {
return false; }
91 const auto& poly = *converted.value();
92 if (poly.degree() != 2) {
return false; }
93 if (poly.coeffs.size() < 3) {
return false; }
95 if (!(poly.coeffs[0] == Rational(0))) {
return false; }
96 if (!(poly.coeffs[1] == Rational(0))) {
return false; }
97 Rational a2 = poly.coeffs[2];
99 if (!(a2 < Rational(0))) {
return false; }
100 c_out = Rational(0) - a2;
106Result<std::optional<detail::IntegralParts>> Integrator::try_special_function(
107 const SymbolicExpr& expr,
const std::string& var,
108 ComputationContext&
context,
int)
try {
110 detail::RewriteBudget transform_budget(
context, (
context).limits().max_recursion_depth,
111 (
context).limits().max_ast_nodes,
"transform");
115 auto v = SymbolicExpr::variable(var);
120 return std::optional<detail::IntegralParts>{{*(simp ? simp : li), zero_}};
129 if (matched.value()) {
132 auto sqrt_c = SymbolicExpr::sqrt(SymbolicExpr::number(c_rat));
133 auto scaled_x = SymbolicExpr::multiply(sqrt_c,
v);
136 auto two = SymbolicExpr::number(2);
137 auto two_sqrt_c = SymbolicExpr::multiply(two, sqrt_c);
138 auto coeff = SymbolicExpr::multiply(
140 SymbolicExpr::power(two_sqrt_c, SymbolicExpr::number(-1)));
141 auto result = SymbolicExpr::multiply(coeff, erf_node);
143 return std::optional<detail::IntegralParts>{{*(simp ? simp : result), zero_}};
151 std::vector<std::shared_ptr<const SymbolicNode>> others;
152 bool has_inv =
false;
154 const auto& other = others[0];
158 return std::optional<detail::IntegralParts>{{*(simp ? simp : ei), zero_}};
163 return std::optional<detail::IntegralParts>{{*(simp ? simp : si), zero_}};
168 return std::optional<detail::IntegralParts>{{*(simp ? simp : ci), zero_}};
173 return std::optional<detail::IntegralParts>{};
static Result failure(CasErrc code, std::string message, std::string operation={})
bool sf_is_fn_of_var(const std::shared_ptr< const SymbolicNode > &node, FunctionNode::FuncType t, const std::string &var)
std::shared_ptr< SymbolicExpr > sf_sqrt_pi()
Result< bool > sf_match_exp_neg_quad(const std::shared_ptr< const SymbolicNode > &node, const std::string &var, Rational &c_out, ComputationContext &context)
bool sf_is_inv_ln_var(const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
bool sf_is_inv_var(const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
bool sf_split_inv_var(const std::shared_ptr< const SymbolicNode > &node, const std::string &var, std::vector< std::shared_ptr< const SymbolicNode > > &other_factors, bool &has_inv_var)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)
std::optional< Rational > exact_rational_value(const NumberNode &number)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
__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
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
@ Rational
Rational numbers
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
Result< OptionalRationalPolynomial > recognize_rational_polynomial(const SymbolicExpr &expression, const std::string &variable, ComputationContext &context)
std::shared_ptr< SymbolicExpr > make_unary_function(FunctionNode::FuncType type, const std::shared_ptr< SymbolicExpr > &operand)
__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 & t