14 using DenseStorage = std::vector<std::shared_ptr<const SymbolicNode>>;
15 using SparseStorage = std::map<size_t, std::shared_ptr<const SymbolicNode>>;
23 static size_t validate_grid_columns(
const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid) {
25 throw std::invalid_argument(
"MatrixNode: matrix must have at least one row");
27 size_t ncols = grid[0].size();
29 throw std::invalid_argument(
"MatrixNode: matrix must have at least one column");
31 for (
const auto& item : grid[0]) {
33 throw std::invalid_argument(
"MatrixNode: matrix elements cannot be null");
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");
40 for (
const auto& item : grid[i]) {
42 throw std::invalid_argument(
"MatrixNode: matrix elements cannot be null");
50 if (
r == 0 ||
c == 0) {
51 throw std::invalid_argument(
"MatrixNode: matrix dimensions must be non-zero");
53 if (
r > std::numeric_limits<size_t>::max() /
c) {
54 throw std::length_error(
"MatrixNode: matrix dimensions overflow");
56 if (dense.size() !=
r *
c) {
57 throw std::invalid_argument(
"MatrixNode: dense storage size does not match dimensions");
59 for (
const auto& item : dense) {
61 throw std::invalid_argument(
"MatrixNode: dense storage elements cannot be null");
68 if (
r == 0 ||
c == 0) {
69 throw std::invalid_argument(
"MatrixNode: matrix dimensions must be non-zero");
71 if (
r > std::numeric_limits<size_t>::max() /
c) {
72 throw std::length_error(
"MatrixNode: matrix dimensions overflow");
74 const size_t total =
r *
c;
75 for (
const auto& [idx, item] : sparse) {
77 throw std::invalid_argument(
"MatrixNode: sparse storage index is out of bounds");
80 throw std::invalid_argument(
"MatrixNode: sparse storage elements cannot be null");
94 const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid,
size_t total_elements,
size_t ncols);
101 const std::variant<DenseStorage, SparseStorage>
storage_;
103 MatrixNode(
const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid)
104 :
rows_(grid.size()),
117 const std::variant<DenseStorage, SparseStorage>&
storage() const noexcept {
125 std::size_t seed = 0;
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()) {
139 const auto& sparse = std::get<SparseStorage>(
storage_);
140 for (
const auto& [idx, val] : sparse) {
142 if (val && !val->is_zero()) {
156 std::shared_ptr<const SymbolicNode>
clone()
const override {
157 if (std::holds_alternative<DenseStorage>(
storage_)) {
158 const auto& dense = std::get<DenseStorage>(
storage_);
160 new_dense.reserve(dense.size());
161 for (
const auto&
e : dense) {
162 new_dense.push_back(
e->clone());
166 const auto& sparse = std::get<SparseStorage>(
storage_);
168 for(
const auto& [idx, node] : sparse) {
169 new_sparse[idx] = node->clone();
181 std::shared_ptr<const SymbolicNode>
get(
size_t r,
size_t c)
const {
185 if (std::holds_alternative<DenseStorage>(
storage_)) {
186 return std::get<DenseStorage>(
storage_)[idx];
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 =
203 if (
dynamic_cast<const MatrixNode*
>(&node))
return true;
204 if (
const auto* power =
dynamic_cast<const PowerNode*
>(&node)) {
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();
217 return children && std::any_of(
218 children->begin(), children->end(),
219 [](
const auto& child) { return contains_matrix(*child); });
223 const std::vector<std::vector<std::shared_ptr<const SymbolicNode>>>& grid,
size_t total_elements,
size_t ncols) {
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++;
232 bool use_sparse = total_elements > 0 && ((double)non_zeros / total_elements < 0.2);
237 for (
const auto& row : grid) {
239 for (
const auto& item : row) {
240 if (item && !item->is_zero()) {
241 s[
r * ncols +
c] = item;
250 d.reserve(total_elements);
251 for (
const auto& row : grid) {
252 d.insert(d.end(), row.begin(), row.end());
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
static DenseStorage validate_dense_storage(size_t r, size_t c, DenseStorage dense)
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)
根据稀疏度选择存储方式,从二维网格创建存储。
LMCAS_AST_NODE_FACTORY_FRIEND
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)
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)
std::size_t hash() const
获取节点哈希值(带缓存).
virtual bool is_zero() const
virtual void visit(const NumberNode &node)=0
std::shared_ptr< const Node > make_node(Args &&... args)
__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)