LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
matrix.hpp
浏览该文件的文档.
1#pragma once
3#include <map>
4
5namespace LMCAS {
6
7/**
8 * @brief 矩阵节点,支持稠密和稀疏两种存储方式。
9 *
10 * 当非零元素占比低于 20% 时自动使用稀疏存储,否则使用稠密存储。
11 */
12class MatrixNode : public SymbolicNode {
13public:
14 using DenseStorage = std::vector<std::shared_ptr<const SymbolicNode>>; /**< 稠密存储,按行优先展开。 */
15 using SparseStorage = std::map<size_t, std::shared_ptr<const SymbolicNode>>; /**< 稀疏存储,索引映射到节点。 */
16
17 /**
18 * @brief 验证并返回网格的列数(要求各行列数一致)。
19 * @param grid 二维节点网格
20 * @return 列数
21 * @throw std::invalid_argument 各行列数不一致时抛出
22 */
23 static size_t validate_grid_columns(const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid) {
24 if (grid.empty()) {
25 throw std::invalid_argument("MatrixNode: matrix must have at least one row");
26 }
27 size_t ncols = grid[0].size();
28 if (ncols == 0) {
29 throw std::invalid_argument("MatrixNode: matrix must have at least one column");
30 }
31 for (const auto& item : grid[0]) {
32 if (!item) {
33 throw std::invalid_argument("MatrixNode: matrix elements cannot be null");
34 }
35 }
36 for (size_t i = 1; i < grid.size(); ++i) {
37 if (grid[i].size() != ncols) {
38 throw std::invalid_argument("MatrixNode: all rows must have the same number of columns");
39 }
40 for (const auto& item : grid[i]) {
41 if (!item) {
42 throw std::invalid_argument("MatrixNode: matrix elements cannot be null");
43 }
44 }
45 }
46 return ncols;
47 }
48
49 static DenseStorage validate_dense_storage(size_t r, size_t c, DenseStorage dense) {
50 if (r == 0 || c == 0) {
51 throw std::invalid_argument("MatrixNode: matrix dimensions must be non-zero");
52 }
53 if (r > std::numeric_limits<size_t>::max() / c) {
54 throw std::length_error("MatrixNode: matrix dimensions overflow");
55 }
56 if (dense.size() != r * c) {
57 throw std::invalid_argument("MatrixNode: dense storage size does not match dimensions");
58 }
59 for (const auto& item : dense) {
60 if (!item) {
61 throw std::invalid_argument("MatrixNode: dense storage elements cannot be null");
62 }
63 }
64 return dense;
65 }
66
67 static SparseStorage validate_sparse_storage(size_t r, size_t c, SparseStorage sparse) {
68 if (r == 0 || c == 0) {
69 throw std::invalid_argument("MatrixNode: matrix dimensions must be non-zero");
70 }
71 if (r > std::numeric_limits<size_t>::max() / c) {
72 throw std::length_error("MatrixNode: matrix dimensions overflow");
73 }
74 const size_t total = r * c;
75 for (const auto& [idx, item] : sparse) {
76 if (idx >= total) {
77 throw std::invalid_argument("MatrixNode: sparse storage index is out of bounds");
78 }
79 if (!item) {
80 throw std::invalid_argument("MatrixNode: sparse storage elements cannot be null");
81 }
82 }
83 return sparse;
84 }
85
86 /**
87 * @brief 根据稀疏度选择存储方式,从二维网格创建存储。
88 * @param grid 二维节点网格
89 * @param total_elements 总元素数
90 * @param ncols 列数
91 * @return 稠密或稀疏存储
92 */
93 static std::variant<DenseStorage, SparseStorage> create_storage_from_grid(
94 const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid, size_t total_elements, size_t ncols);
95
96private:
98
99 const size_t rows_;
100 const size_t cols_;
101 const std::variant<DenseStorage, SparseStorage> storage_;
102
103 MatrixNode(const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid)
104 : rows_(grid.size()),
107
108 MatrixNode(size_t r, size_t c, DenseStorage dense)
109 : rows_(r), cols_(c), storage_(validate_dense_storage(r, c, std::move(dense))) {}
110
111 MatrixNode(size_t r, size_t c, SparseStorage sparse)
112 : rows_(r), cols_(c), storage_(validate_sparse_storage(r, c, std::move(sparse))) {}
113
114public:
115 size_t rows() const noexcept { return rows_; }
116 size_t cols() const noexcept { return cols_; }
117 const std::variant<DenseStorage, SparseStorage>& storage() const noexcept {
118 return storage_;
119 }
120
121 int type_priority() const override { return 6; }
122
123protected:
124 std::size_t compute_hash() const override {
125 std::size_t seed = 0;
127 hash_combine(seed, rows_);
128 hash_combine(seed, cols_);
129
130 if (std::holds_alternative<DenseStorage>(storage_)) {
131 const auto& dense = std::get<DenseStorage>(storage_);
132 for (size_t i = 0; i < dense.size(); ++i) {
133 if (dense[i] && !dense[i]->is_zero()) {
134 hash_combine(seed, i);
135 hash_combine(seed, dense[i]->hash());
136 }
137 }
138 } else {
139 const auto& sparse = std::get<SparseStorage>(storage_);
140 for (const auto& [idx, val] : sparse) {
141
142 if (val && !val->is_zero()) {
143 hash_combine(seed, idx);
144 hash_combine(seed, val->hash());
145 }
146 }
147 }
148 return seed;
149 }
150
151 int compare_same_type(const SymbolicNode& other) const override;
152
153public:
154 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override { LMCAS::detail::SymbolicVisitor::DepthGuard guard(visitor); visitor.visit(*this); }
155
156 std::shared_ptr<const SymbolicNode> clone() const override {
157 if (std::holds_alternative<DenseStorage>(storage_)) {
158 const auto& dense = std::get<DenseStorage>(storage_);
159 DenseStorage new_dense;
160 new_dense.reserve(dense.size());
161 for (const auto& e : dense) {
162 new_dense.push_back(e->clone());
163 }
164 return LMCAS::detail::make_node<MatrixNode>(rows_, cols_, std::move(new_dense));
165 } else {
166 const auto& sparse = std::get<SparseStorage>(storage_);
167 SparseStorage new_sparse;
168 for(const auto& [idx, node] : sparse) {
169 new_sparse[idx] = node->clone();
170 }
171 return LMCAS::detail::make_node<MatrixNode>(rows_, cols_, std::move(new_sparse));
172 }
173 }
174
175 /**
176 * @brief 获取指定位置的矩阵元素。
177 * @param r 行索引(从 0 开始)
178 * @param c 列索引(从 0 开始)
179 * @return 对应节点,越界返回 nullptr,稀疏缺失返回零节点
180 */
181 std::shared_ptr<const SymbolicNode> get(size_t r, size_t c) const {
182 if (r >= rows_ || c >= cols_) return nullptr;
183
184 size_t idx = r * cols_ + c;
185 if (std::holds_alternative<DenseStorage>(storage_)) {
186 return std::get<DenseStorage>(storage_)[idx];
187 } else {
188 const auto& sparse = std::get<SparseStorage>(storage_);
189 auto it = sparse.find(idx);
190 if (it != sparse.end()) return it->second;
191 static const std::shared_ptr<const SymbolicNode> zero =
193 return zero;
194 }
195 }
196 bool is_sparse() const { return std::holds_alternative<SparseStorage>(storage_); }
197
198private:
199
200};
201
203 if (dynamic_cast<const MatrixNode*>(&node)) return true;
204 if (const auto* power = dynamic_cast<const PowerNode*>(&node)) {
205 return contains_matrix(*power->base());
206 }
207 const std::vector<std::shared_ptr<const SymbolicNode>>* children = nullptr;
208 if (const auto* sum = dynamic_cast<const AddNode*>(&node)) {
209 children = &sum->operands();
210 } else if (const auto* product = dynamic_cast<const MultiplyNode*>(&node)) {
211 children = &product->operands();
212 } else if (const auto* function = dynamic_cast<const FunctionNode*>(&node)) {
213 children = &function->arguments();
214 } else if (const auto* function = dynamic_cast<const UninterpretedFunctionNode*>(&node)) {
215 children = &function->arguments();
216 }
217 return children && std::any_of(
218 children->begin(), children->end(),
219 [](const auto& child) { return contains_matrix(*child); });
220}
221
222inline std::variant<MatrixNode::DenseStorage, MatrixNode::SparseStorage> MatrixNode::create_storage_from_grid(
223 const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid, size_t total_elements, size_t ncols) {
224
225 size_t non_zeros = 0;
226 for (const auto& row : grid) {
227 for (const auto& item : row) {
228 if (item && !item->is_zero()) non_zeros++;
229 }
230 }
231
232 bool use_sparse = total_elements > 0 && ((double)non_zeros / total_elements < 0.2);
233
234 if (use_sparse) {
236 size_t r = 0;
237 for (const auto& row : grid) {
238 size_t c = 0;
239 for (const auto& item : row) {
240 if (item && !item->is_zero()) {
241 s[r * ncols + c] = item;
242 }
243 c++;
244 }
245 r++;
246 }
247 return s;
248 } else {
249 DenseStorage d;
250 d.reserve(total_elements);
251 for (const auto& row : grid) {
252 d.insert(d.end(), row.begin(), row.end());
253 }
254 return d;
255 }
256}
257
258}
加法节点,表示多个操作数的求和。
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
矩阵节点,支持稠密和稀疏两种存储方式。
static DenseStorage validate_dense_storage(size_t r, size_t c, DenseStorage dense)
const size_t rows_
static std::variant< DenseStorage, SparseStorage > create_storage_from_grid(const std::vector< std::vector< std::shared_ptr< const SymbolicNode > > > &grid, size_t total_elements, size_t ncols)
根据稀疏度选择存储方式,从二维网格创建存储。
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
const std::variant< DenseStorage, SparseStorage > & storage() const noexcept
size_t cols() const noexcept
MatrixNode(size_t r, size_t c, SparseStorage sparse)
std::shared_ptr< const SymbolicNode > clone() const override
MatrixNode(size_t r, size_t c, DenseStorage dense)
bool is_sparse() const
std::size_t compute_hash() const override
size_t rows() const noexcept
MatrixNode(const std::vector< std::vector< std::shared_ptr< const SymbolicNode > > > &grid)
int type_priority() const override
std::map< size_t, std::shared_ptr< const SymbolicNode > > SparseStorage
稀疏存储,索引映射到节点。
std::shared_ptr< const SymbolicNode > get(size_t r, size_t c) const
获取指定位置的矩阵元素。
static size_t validate_grid_columns(const std::vector< std::vector< std::shared_ptr< const SymbolicNode > > > &grid)
验证并返回网格的列数(要求各行列数一致)。
const std::variant< DenseStorage, SparseStorage > storage_
int compare_same_type(const SymbolicNode &other) const override
std::vector< std::shared_ptr< const SymbolicNode > > DenseStorage
稠密存储,按行优先展开。
static SparseStorage validate_sparse_storage(size_t r, size_t c, SparseStorage sparse)
MultiplyNode(std::vector< std::shared_ptr< const SymbolicNode > > ops)
static bool contains_matrix(const SymbolicNode &node)
幂运算节点,表示 base^exponent。
std::size_t hash() const
获取节点哈希值(带缓存).
SymbolicNode()=default
virtual bool is_zero() const
virtual void visit(const NumberNode &node)=0
std::shared_ptr< const Node > make_node(Args &&... args)
ExprResult e()
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
void hash_combine(std::size_t &seed, std::size_t value)
将一个哈希值混合到种子中,用于组合多个字段的哈希.
const VectorField const VectorField & c
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)