7 std::shared_ptr<const SymbolicNode>
value;
8 if (
const auto* dense = std::get_if<MatrixNode::DenseStorage>(&matrix.
storage())) {
9 if (index < dense->size()) {
10 value = (*dense)[index];
13 const auto& sparse = std::get<MatrixNode::SparseStorage>(matrix.
storage());
14 const auto found = sparse.find(index);
15 if (found != sparse.end()) {
16 value = found->second;
23 std::size_t rows, std::size_t cols) {
24 for (
const auto& operand : operands) {
25 const auto matrix = std::dynamic_pointer_cast<const MatrixNode>(operand);
26 if (!matrix || matrix->rows() != rows || matrix->cols() != cols) {
35 const std::vector<std::shared_ptr<const SymbolicNode>>& operands) {
36 if (operands.empty()) {
39 const auto first = std::dynamic_pointer_cast<const MatrixNode>(operands.front());
43 const auto rows = first->rows();
44 const auto cols = first->cols();
45 if (!matching_matrix_shapes(operands, rows, cols)) {
50 std::size_t nodes = 1;
51 elements.reserve(count);
52 for (std::size_t i = 0; i < count; ++i) {
53 std::vector<std::shared_ptr<const SymbolicNode>> terms;
54 std::size_t term_nodes = 0;
56 for (
const auto& operand : operands) {
57 const auto matrix = std::dynamic_pointer_cast<const MatrixNode>(operand);
70 const auto*
a = std::get_if<MatrixNode::DenseStorage>(&left.
storage());
71 const auto*
b = std::get_if<MatrixNode::DenseStorage>(&
right.storage());
72 std::vector<std::shared_ptr<const SymbolicNode>> terms;
73 std::size_t nodes = 0;
75 terms.reserve(left.
cols());
76 for (std::size_t k = 0; k < left.
cols(); ++k) {
77 auto first =
a ? (*a)[row * left.
cols() + k] : matrix_element(left, row * left.
cols() + k);
78 auto second =
b ? (*b)[k *
right.cols() + col] : matrix_element(
right, k *
right.cols() + col);
89 const std::shared_ptr<const SymbolicNode>& left,
90 const std::shared_ptr<const SymbolicNode>&
right) {
91 const auto a = std::dynamic_pointer_cast<const MatrixNode>(left);
92 const auto b = std::dynamic_pointer_cast<const MatrixNode>(
right);
96 if (
a->cols() !=
b->rows()) {
101 std::size_t nodes = 1;
102 elements.reserve(count);
103 for (std::size_t row = 0; row <
a->rows(); ++row) {
104 for (std::size_t col = 0; col <
b->cols(); ++col) {
113 const MatrixNode& matrix,
const std::shared_ptr<const NumberNode>& scalar) {
116 std::size_t nodes = 1;
117 elements.reserve(count);
118 for (std::size_t i = 0; i < count; ++i) {
119 auto element = matrix_element(matrix, i);
122 std::vector<std::shared_ptr<const SymbolicNode>>{scalar,
element})->accept(*
this);
129 const std::vector<std::shared_ptr<const SymbolicNode>>& operands) {
130 std::vector<std::shared_ptr<const SymbolicNode>> nonscalar;
131 std::size_t nonscalar_nodes = 0;
133 for (
const auto& operand : operands) {
134 if (
const auto number = std::dynamic_pointer_cast<const NumberNode>(operand)) {
140 std::vector<std::shared_ptr<const SymbolicNode>> fused;
141 std::size_t fused_nodes = 0;
142 std::size_t last_nodes = 0;
143 if (!nonscalar.empty()) {
145 last_nodes = fused_nodes;
147 for (std::size_t i = 1; i < nonscalar.size(); ++i) {
152 last_nodes = replacement_nodes;
154 fused.back() = std::move(product);
156 const auto previous_nodes = fused_nodes;
158 last_nodes = fused_nodes - previous_nodes;
161 if (fused.size() == 1 && !scalar->is_one()) {
162 if (
const auto matrix = std::dynamic_pointer_cast<const MatrixNode>(fused.front())) {
166 if (!scalar->is_one()) {
168 fused.insert(fused.begin(), scalar);
const std::variant< DenseStorage, SparseStorage > & storage() const noexcept
size_t cols() const noexcept
size_t rows() const noexcept
std::vector< std::shared_ptr< const SymbolicNode > > DenseStorage
稠密存储,按行优先展开。
std::shared_ptr< const SymbolicNode > scale_matrix(const MatrixNode &matrix, const std::shared_ptr< const NumberNode > &scalar)
NormalizationVisitor(detail::RewriteBudget &budget, const FactsQuery &facts, Domain domain)
void set_result(std::shared_ptr< const SymbolicNode > candidate)
const FactsQuery & facts_
std::shared_ptr< const SymbolicNode > result
bool normalize_matrix_sum(const std::vector< std::shared_ptr< const SymbolicNode > > &operands)
std::shared_ptr< const SymbolicNode > normalize_matrix_product(const std::vector< std::shared_ptr< const SymbolicNode > > &operands)
std::shared_ptr< const SymbolicNode > matrix_product_element(const MatrixNode &left, const MatrixNode &right, std::size_t row, std::size_t col)
std::shared_ptr< const SymbolicNode > fuse_matrix_product(const std::shared_ptr< const SymbolicNode > &left, const std::shared_ptr< const SymbolicNode > &right)
std::shared_ptr< const SymbolicNode > get_result() const
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
std::size_t append_size(std::size_t current, std::size_t child)
RewriteBudget * rewrite_budget() const noexcept
std::shared_ptr< const SymbolicNode > matrix_element(const MatrixNode &matrix, std::size_t index)
bool matching_matrix_shapes(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, std::size_t rows, std::size_t cols)
std::shared_ptr< const Node > make_node(Args &&... args)
std::size_t normalization_check_arithmetic(detail::RewriteBudget *budget, std::size_t extra_nodes, const std::shared_ptr< const Nodes > &... children)
std::size_t normalization_check_count(detail::RewriteBudget *budget, std::size_t rows, std::size_t cols=1, bool wrapped=true)
std::shared_ptr< const NumberNode > multiply_numbers(const std::shared_ptr< const NumberNode > &left, const std::shared_ptr< const NumberNode > &right)
两个数值节点相乘
__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
const std::string const ExprPtr & value
std::shared_ptr< const SymbolicNode > make_normalized_multiply_node(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, detail::RewriteBudget *budget=nullptr)
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)