21 throw std::invalid_argument(
"unknown mathematical constant");
26 const std::string&
name() const noexcept {
return name_; }
33 std::size_t
hash = std::hash<std::string>{}(
name_);
40 const int cmp =
name_.compare(o.name_);
41 if (cmp != 0)
return cmp;
60 std::vector<std::shared_ptr<const SymbolicNode>> ops) {
62 throw std::invalid_argument(
"AddNode requires at least one operand");
64 std::vector<std::shared_ptr<const SymbolicNode>> flattened;
65 for (
const auto&
op : ops) {
67 throw std::invalid_argument(
"AddNode operand cannot be null");
69 if (
auto add = std::dynamic_pointer_cast<const AddNode>(
op)) {
70 flattened.insert(flattened.end(),
add->operands_.begin(),
add->operands_.end());
72 flattened.push_back(
op);
75 std::sort(flattened.begin(), flattened.end(), [](
const auto&
a,
const auto&
b) {
76 bool a_num = a->is_number();
77 bool b_num = b->is_number();
78 if (a_num != b_num) return !a_num;
79 return a->compare(*b) < 0;
84 const std::vector<std::shared_ptr<const SymbolicNode>>
operands_;
86 explicit AddNode(std::vector<std::shared_ptr<const SymbolicNode>> ops)
90 const std::vector<std::shared_ptr<const SymbolicNode>>&
operands() const noexcept {
107 const auto& o =
static_cast<const AddNode&
>(other);
108 if (
operands_.size() != o.operands_.size()) {
109 return operands_.size() < o.operands_.size() ? -1 : 1;
111 for (
size_t i = 0; i <
operands_.size(); ++i) {
112 int cmp =
operands_[i]->compare(*o.operands_[i]);
113 if (cmp != 0)
return cmp;
120 std::shared_ptr<const SymbolicNode>
clone()
const override {
121 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
123 for (
const auto&
op :
operands_) new_ops.push_back(
op->clone());
140 const std::shared_ptr<const SymbolicNode>& lhs,
141 const std::shared_ptr<const SymbolicNode>&
rhs) {
142 return lhs->compare(*
rhs) < 0;
146 std::vector<std::shared_ptr<const SymbolicNode>> ops) {
148 throw std::invalid_argument(
"MultiplyNode requires at least one operand");
150 std::vector<std::shared_ptr<const SymbolicNode>> flattened;
151 for (
const auto&
op : ops) {
153 throw std::invalid_argument(
"MultiplyNode operand cannot be null");
155 if (
auto mul = std::dynamic_pointer_cast<const MultiplyNode>(
op)) {
156 flattened.insert(flattened.end(),
mul->operands_.begin(),
mul->operands_.end());
158 flattened.push_back(
op);
161 const bool scalar_product = std::none_of(
162 flattened.begin(), flattened.end(),
163 [](
const auto& factor) { return contains_matrix(*factor); });
164 if (scalar_product) {
171 const std::vector<std::shared_ptr<const SymbolicNode>>
operands_;
173 explicit MultiplyNode(std::vector<std::shared_ptr<const SymbolicNode>> ops)
177 const std::vector<std::shared_ptr<const SymbolicNode>>&
operands() const noexcept {
185 std::size_t seed = 0;
194 const auto& o =
static_cast<const MultiplyNode&
>(other);
195 if (
operands_.size() != o.operands_.size()) {
196 return operands_.size() < o.operands_.size() ? -1 : 1;
198 for (
size_t i = 0; i <
operands_.size(); ++i) {
199 int cmp =
operands_[i]->compare(*o.operands_[i]);
200 if (cmp != 0)
return cmp;
207 std::shared_ptr<const SymbolicNode>
clone()
const override {
208 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
210 for (
const auto&
op :
operands_) new_ops.push_back(
op->clone());
222 const std::shared_ptr<const SymbolicNode>
base_;
225 PowerNode(std::shared_ptr<const SymbolicNode>
b, std::shared_ptr<const SymbolicNode>
e)
228 throw std::invalid_argument(
"PowerNode base and exponent cannot be null");
233 const std::shared_ptr<const SymbolicNode>&
base() const noexcept {
return base_; }
234 const std::shared_ptr<const SymbolicNode>&
exponent() const noexcept {
242 std::size_t seed = 0;
250 const auto& o =
static_cast<const PowerNode&
>(other);
252 int cmp_exp =
exponent_->compare(*o.exponent_);
253 if (cmp_exp != 0)
return cmp_exp > 0 ? -1 : 1;
255 return base_->compare(*o.base_);
260 std::shared_ptr<const SymbolicNode>
clone()
const override {
std::shared_ptr< const SymbolicNode > clone() const override
const std::vector< std::shared_ptr< const SymbolicNode > > operands_
int type_priority() const override
std::size_t compute_hash() const override
LMCAS_AST_NODE_FACTORY_FRIEND
static std::vector< std::shared_ptr< const SymbolicNode > > normalize_operands(std::vector< std::shared_ptr< const SymbolicNode > > ops)
int compare_same_type(const SymbolicNode &other) const override
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
AddNode(std::vector< std::shared_ptr< const SymbolicNode > > ops)
static std::vector< std::shared_ptr< const SymbolicNode > > normalize_operands(std::vector< std::shared_ptr< const SymbolicNode > > ops)
std::size_t compute_hash() const override
MultiplyNode(std::vector< std::shared_ptr< const SymbolicNode > > ops)
std::shared_ptr< const SymbolicNode > clone() const override
int type_priority() const override
int compare_same_type(const SymbolicNode &other) const override
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
LMCAS_AST_NODE_FACTORY_FRIEND
static bool compare_operands(const std::shared_ptr< const SymbolicNode > &lhs, const std::shared_ptr< const SymbolicNode > &rhs)
static bool contains_matrix(const SymbolicNode &node)
const std::vector< std::shared_ptr< const SymbolicNode > > operands_
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
const std::shared_ptr< const SymbolicNode > exponent_
int type_priority() const override
std::size_t compute_hash() const override
std::shared_ptr< const SymbolicNode > clone() const override
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
LMCAS_AST_NODE_FACTORY_FRIEND
PowerNode(std::shared_ptr< const SymbolicNode > b, std::shared_ptr< const SymbolicNode > e)
const std::shared_ptr< const SymbolicNode > base_
int compare_same_type(const SymbolicNode &other) const override
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
std::size_t hash() const
获取节点哈希值(带缓存).
bool is_constant() const noexcept
LMCAS_AST_NODE_FACTORY_FRIEND
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
int type_priority() const override
VariableNode(std::string n, bool constant=false)
std::shared_ptr< const SymbolicNode > clone() const override
int compare_same_type(const SymbolicNode &other) const override
const std::string & name() const noexcept
std::size_t compute_hash() const override
virtual void visit(const NumberNode &node)=0
std::shared_ptr< const Node > make_node(Args &&... args)
void hash_combine(std::size_t &seed, std::size_t value)
将一个哈希值混合到种子中,用于组合多个字段的哈希.
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const ExprPtr RelationOp op
__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