LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
functions.hpp
浏览该文件的文档.
1/** @file internal/symbolic_ast/functions.hpp */
2#pragma once
4
5namespace LMCAS {
6
7/**
8 * @brief 函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
9 */
10class FunctionNode : public SymbolicNode {
11public:
12 enum class FuncType {
13 Sin, Cos, Tan, Cot, Sec, Csc, /**< 三角函数。 */
14 ArcSin, ArcCos, ArcTan, /**< 反三角函数。 */
15 Sinh, Cosh, Tanh, /**< 双曲函数。 */
16 Ln, Log, Abs, Sqrt, /**< 对数、绝对值、平方根。 */
17 Exp, /**< 指数函数。 */
18 LambertW, /**< Lambert W 函数。 */
19 Atan2, /**< 双参数反正切。 */
20 Infinity, /**< 无穷大。 */
21 Erf, /**< 误差函数 erf(x) = (2/√π)∫₀ˣ e^(-t²) dt。 */
22 Ei, /**< 指数积分 Ei(x)。 */
23 Si, /**< 正弦积分 Si(x) = ∫₀ˣ sin(t)/t dt。 */
24 Ci, /**< 余弦积分 Ci(x)。 */
25 Li, /**< 对数积分 Li(x) = ∫₀ˣ 1/ln(t) dt。 */
26 Max, /**< 最大值 max(a, b)。 */
27 Min, /**< 最小值 min(a, b)。 */
28 Sgn, /**< 符号函数 sgn(x) ∈ {-1, 0, 1}。 */
29 Floor, /**< 下取整 ⌊x⌋。 */
30 Ceil, /**< 上取整 ⌈x⌉。 */
31 Round, /**< 四舍五入 round(x)。 */
32 RealPart, /**< 实部 Re(z)。 */
33 ImagPart, /**< 虚部 Im(z)。 */
34 Conjugate, /**< 共轭 conj(z)。 */
35 ComplexAbs, /**< 复数模 |z|。 */
36 ComplexArg /**< 复数辐角 arg(z)。 */
37 };
38
39private:
41
43 const std::vector<std::shared_ptr<const SymbolicNode>> arguments_;
44
45 FunctionNode(FuncType t, std::vector<std::shared_ptr<const SymbolicNode>> args)
46 : type_(t), arguments_(std::move(args)) {
47 for (const auto& arg : arguments_) {
48 if (!arg) {
49 throw std::invalid_argument("FunctionNode argument cannot be null");
50 }
51 }
52 }
53
54public:
55 FuncType type() const noexcept { return type_; }
56 const std::vector<std::shared_ptr<const SymbolicNode>>& arguments() const noexcept {
57 return arguments_;
58 }
59
60 int type_priority() const override { return 2; }
61
62protected:
63 std::size_t compute_hash() const override {
64 std::size_t seed = 0;
66 hash_combine(seed, static_cast<size_t>(type_));
67 for (const auto& arg : arguments_) {
68 hash_combine(seed, arg->hash());
69 }
70 return seed;
71 }
72
73 int compare_same_type(const SymbolicNode& other) const override {
74 const auto& o = static_cast<const FunctionNode&>(other);
75 if (type_ != o.type_) {
76 return static_cast<int>(type_) < static_cast<int>(o.type_) ? -1 : 1;
77 }
78 if (arguments_.size() != o.arguments_.size()) {
79 return arguments_.size() < o.arguments_.size() ? -1 : 1;
80 }
81 for (size_t i = 0; i < arguments_.size(); ++i) {
82 int cmp = arguments_[i]->compare(*o.arguments_[i]);
83 if (cmp != 0) return cmp;
84 }
85 return 0;
86 }
87
88public:
89 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override { LMCAS::detail::SymbolicVisitor::DepthGuard guard(visitor); visitor.visit(*this); }
90 std::shared_ptr<const SymbolicNode> clone() const override {
91 std::vector<std::shared_ptr<const SymbolicNode>> new_args;
92 for (const auto& arg : arguments_) new_args.push_back(arg->clone());
93 return LMCAS::detail::make_node<FunctionNode>(type_, std::move(new_args));
94 }
95};
97private:
99 const std::string name_;
100 const std::vector<std::shared_ptr<const SymbolicNode>> arguments_;
101
103 std::string name,
104 std::vector<std::shared_ptr<const SymbolicNode>> arguments)
105 : name_(std::move(name)), arguments_(std::move(arguments)) {
106 if (name_.empty()) {
107 throw std::invalid_argument("uninterpreted function name cannot be empty");
108 }
109 for (const auto& argument : arguments_) {
110 if (!argument) {
111 throw std::invalid_argument("uninterpreted function arguments cannot be null");
112 }
113 }
114 }
115
116public:
117 const std::string& name() const noexcept { return name_; }
118 const auto& arguments() const noexcept { return arguments_; }
119 int type_priority() const override { return 111; }
120
121protected:
122 std::size_t compute_hash() const override {
123 std::size_t seed = static_cast<std::size_t>(type_priority());
124 hash_combine(seed, std::hash<std::string>{}(name_));
125 for (const auto& argument : arguments_) hash_combine(seed, argument->hash());
126 return seed;
127 }
128
129 int compare_same_type(const SymbolicNode& other) const override {
130 const auto& function = static_cast<const UninterpretedFunctionNode&>(other);
131 int comparison = name_.compare(function.name_);
132 if (comparison != 0) return comparison;
133 const auto count = std::min(arguments_.size(), function.arguments_.size());
134 for (std::size_t index = 0; index < count; ++index) {
135 comparison = arguments_[index]->compare(*function.arguments_[index]);
136 if (comparison != 0) return comparison;
137 }
138 if (arguments_.size() == function.arguments_.size()) return 0;
139 return arguments_.size() < function.arguments_.size() ? -1 : 1;
140 }
141
142public:
143 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override {
145 visitor.visit(*this);
146 }
147
148 std::shared_ptr<const SymbolicNode> clone() const override {
149 std::vector<std::shared_ptr<const SymbolicNode>> arguments;
150 arguments.reserve(arguments_.size());
151 for (const auto& argument : arguments_) arguments.push_back(argument->clone());
153 name_, std::move(arguments));
154 }
155};
156
157}
std::shared_ptr< const SymbolicNode > clone() const override
const std::vector< std::shared_ptr< const SymbolicNode > > arguments_
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
FunctionNode(FuncType t, std::vector< std::shared_ptr< const SymbolicNode > > args)
int compare_same_type(const SymbolicNode &other) const override
FuncType type() const noexcept
std::size_t compute_hash() const override
int type_priority() const override
const std::vector< std::shared_ptr< const SymbolicNode > > & arguments() const noexcept
SymbolicNode()=default
std::size_t compute_hash() const override
const auto & arguments() const noexcept
std::shared_ptr< const SymbolicNode > clone() const override
const std::string & name() const noexcept
UninterpretedFunctionNode(std::string name, std::vector< std::shared_ptr< const SymbolicNode > > arguments)
int compare_same_type(const SymbolicNode &other) const override
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
const std::vector< std::shared_ptr< const SymbolicNode > > arguments_
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 function(const std::string &name, std::vector< ExprPtr > arguments)
__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