18 const std::shared_ptr<const SymbolicNode>& node,
20 std::shared_ptr<const SymbolicNode>& argument) {
22 auto pow = std::dynamic_pointer_cast<const PowerNode>(node);
27 auto exp_num = std::dynamic_pointer_cast<const NumberNode>(
pow->exponent());
32 const bool is_two = std::holds_alternative<BigInt>(exp_num->value())
33 ? std::get<BigInt>(exp_num->value()) == BigInt(2)
34 : std::get<Rational>(exp_num->value()) == Rational(2);
39 auto func = std::dynamic_pointer_cast<const FunctionNode>(
pow->base());
40 if (!func || func->arguments().size() != 1) {
49 func_type = func->type();
50 argument = func->arguments()[0];
66 const std::shared_ptr<const SymbolicNode>& node,
67 std::shared_ptr<const SymbolicNode>& coeff,
69 std::shared_ptr<const SymbolicNode>& argument) {
76 auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node);
77 if (!
mul ||
mul->operands().size() < 2) {
81 for (
size_t i = 0; i <
mul->operands().size(); ++i) {
83 std::vector<std::shared_ptr<const SymbolicNode>> coeff_ops;
84 for (
size_t j = 0; j <
mul->operands().size(); ++j) {
86 coeff_ops.push_back(
mul->operands()[j]);
90 if (coeff_ops.size() == 1) {
103 const std::shared_ptr<const SymbolicNode>& node,
const std::string& var);
112 const std::shared_ptr<const SymbolicNode>& node,
const TrigSquare& square) {
131 const std::vector<std::shared_ptr<const SymbolicNode>>& operands,
132 const std::vector<bool>& consumed, std::size_t start,
const TrigSquare& square) {
133 for (std::size_t i = start; i < operands.size(); ++i) {
138 return operands.size();
142 const AddNode& sum,
const std::string& var) {
143 std::vector<std::shared_ptr<const SymbolicNode>> operands;
144 operands.reserve(sum.
operands().size());
145 for (
const auto& operand : sum.
operands()) {
148 std::vector<bool> consumed(operands.size(),
false);
149 std::vector<std::shared_ptr<const SymbolicNode>> result;
150 for (std::size_t i = 0; i < operands.size(); ++i) {
157 result.push_back(operands[i]);
161 if (partner == operands.size()) {
162 result.push_back(operands[i]);
166 consumed[partner] =
true;
173 if (result.empty()) {
176 if (result.size() == 1) {
192 const std::shared_ptr<const SymbolicNode>& node,
193 const std::string& var) {
199 if (
auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
203 if (
auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
204 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
205 new_ops.reserve(
mul->operands().size());
206 for (
const auto&
op :
mul->operands()) {
212 if (
auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
218 if (
auto func = std::dynamic_pointer_cast<const FunctionNode>(node)) {
219 std::vector<std::shared_ptr<const SymbolicNode>> new_args;
220 new_args.reserve(func->arguments().size());
221 for (
const auto& arg : func->arguments()) {
239 const std::shared_ptr<SymbolicExpr>& expr,
240 const std::string& var) {
248 if (!simplified_root) {
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
bool equals(const SymbolicNode &other) const
判断两个节点是否结构相等.
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)
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
std::shared_ptr< SymbolicExpr > tf_simplify_pythagorean(const std::shared_ptr< SymbolicExpr > &expression, const std::string &variable)
在因式分解前用 sin^2(f) + cos^2(f) = 1 化简表达式。
FunctionNode::FuncType type
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
static std::shared_ptr< const SymbolicNode > simplify_pythagorean_sum(const AddNode &sum, const std::string &var)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
static std::size_t find_complementary_square(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, const std::vector< bool > &consumed, std::size_t start, const TrigSquare &square)
const ExprPtr RelationOp op
static std::shared_ptr< const SymbolicNode > tf_simplify_pythagorean_node(const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
递归化简 a*sin^2(f) + a*cos^2(f) 为 a,系数为 1 时结果为 1。
std::shared_ptr< const SymbolicNode > argument
static bool complementary_square(const std::shared_ptr< const SymbolicNode > &node, const TrigSquare &square)
static bool tf_extract_coeff_trig_squared(const std::shared_ptr< const SymbolicNode > &node, std::shared_ptr< const SymbolicNode > &coeff, FunctionNode::FuncType &func_type, std::shared_ptr< const SymbolicNode > &argument)
从 a*sin^2(f) 或 a*cos^2(f) 提取系数和三角平方项。
static bool tf_is_trig_squared(const std::shared_ptr< const SymbolicNode > &node, FunctionNode::FuncType &func_type, std::shared_ptr< const SymbolicNode > &argument)
匹配 sin^2(f) 或 cos^2(f),提取函数类型和参数。
std::shared_ptr< const SymbolicNode > coefficient