12 const std::shared_ptr<SymbolicExpr>& f,
13 const std::shared_ptr<SymbolicExpr>& g,
14 const std::string& var,
16 const std::string& operation) {
17 auto step =
context.consume_steps(1, operation);
18 if (!step)
return step;
21 "convolution expressions cannot be null",
26 "convolution variable name cannot be empty",
33 const std::shared_ptr<SymbolicExpr>& f,
const std::shared_ptr<SymbolicExpr>& g,
37 const AddNode& addition,
const std::shared_ptr<SymbolicExpr>& other,
40 (
context).limits().max_ast_nodes,
"transform");
41 std::shared_ptr<SymbolicExpr> accumulated;
42 for (
const auto& operand : addition.
operands()) {
44 auto transformed = sum_is_left
47 if (!transformed)
return transformed;
48 auto expression = transformed.value().value.expression;
49 accumulated = accumulated ? SymbolicExpr::add(accumulated, expression) : expression;
53}
catch (
const CasError& error) {
55}
catch (
const std::bad_alloc&) {
57}
catch (
const std::length_error& error) {
59}
catch (
const std::exception& error) {
64 const std::shared_ptr<SymbolicExpr>& f,
65 const std::shared_ptr<SymbolicExpr>& g,
70 (
context).limits().max_ast_nodes,
"transform");
71 constexpr const char* operation =
"convolve";
72 auto step =
context.consume_steps(1, operation);
79 auto left_sum = std::dynamic_pointer_cast<const AddNode>(
detail::node(f));
83 auto right_sum = std::dynamic_pointer_cast<const AddNode>(
detail::node(g));
90 left_parts.second->to_string() != f->to_string()) {
93 if (!inner)
return inner;
95 left_parts.first, inner.value().value.expression)), transform_budget));
100 right_parts.second->to_string() != g->to_string()) {
103 if (!inner)
return inner;
105 right_parts.first, inner.value().value.expression)), transform_budget));
111 if (!left || !
right) {
114 "当前双边卷积规则不支持该表达式对", operation);
117 const Rational rate_sum = left->rate +
right->rate;
118 const Rational output_rate = left->rate *
right->rate / rate_sum;
119 auto scale = SymbolicExpr::multiply(
120 SymbolicExpr::multiply(left->coefficient,
right->coefficient),
121 SymbolicExpr::sqrt(SymbolicExpr::divide(
124 SymbolicExpr::number(rate_sum))));
125 auto square = SymbolicExpr::power(
126 SymbolicExpr::variable(
variable), SymbolicExpr::number(2));
127 auto exponent = SymbolicExpr::multiply(
128 SymbolicExpr::number(-output_rate), square);
129 auto gaussian = SymbolicExpr::exp(
exponent);
132}
catch (
const CasError& error) {
134}
catch (
const std::bad_alloc&) {
136}
catch (
const std::length_error& error) {
138}
catch (
const std::exception& error) {
143 const std::shared_ptr<SymbolicExpr>& f,
144 const std::shared_ptr<SymbolicExpr>& g,
145 const std::string& var,
147 const std::string operation =
"convolve";
153 }
catch (
const std::bad_alloc&) {
156 }
catch (
const std::exception& error) {
163 const std::shared_ptr<SymbolicExpr>& f,
164 const std::shared_ptr<SymbolicExpr>& g,
165 const std::string& var) {
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
const std::string & variable
static Result< void > te_validate_convolution_inputs(const std::shared_ptr< SymbolicExpr > &f, const std::shared_ptr< SymbolicExpr > &g, const std::string &var, ComputationContext &context, const std::string &operation)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
static TransformEngineResult te_convolve_sum(const AddNode &addition, const std::shared_ptr< SymbolicExpr > &other, bool sum_is_left, const std::string &variable, ComputationContext &context)
static TransformEngineResult te_convolve_core(const std::shared_ptr< SymbolicExpr > &f, const std::shared_ptr< SymbolicExpr > &g, const std::string &variable, ComputationContext &context)
TransformEngineResult convolve_checked(const std::shared_ptr< SymbolicExpr > &f, const std::shared_ptr< SymbolicExpr > &g, const std::string &var, ComputationContext &context)
Result< Verified< EvaluatedTransform > > TransformEngineResult