#ifndef FESA_MATH_SPARSE_MATRIX_H_ #define FESA_MATH_SPARSE_MATRIX_H_ #include #include #include "fesa/core/status.h" #include "fesa/math/vector.h" namespace fesa { struct SparsePattern; /// @brief Carries one deterministic element-local COO contribution. struct CooContribution { std::size_t row; std::size_t column; double value; std::size_t element_order; std::size_t local_order; }; /// @brief Owns canonical 0-based CSR independently of the dense Matrix type. class SparseMatrix { public: /// @brief Reduces ordered COO contributions into an expected CSR pattern. /// @return A validated matrix or a structured model failure. /// @note Duplicate sums use stable element and local contribution order. static Result FromCoo( std::size_t rows, std::size_t columns, std::vector contributions, const SparsePattern& expected_pattern); /// @brief Returns the row count. std::size_t Rows() const noexcept; /// @brief Returns the column count. std::size_t Columns() const noexcept; /// @brief Returns the canonical 0-based CSR row offsets. const std::vector& RowOffsets() const noexcept; /// @brief Returns sorted unique 0-based CSR column indices. const std::vector& ColumnIndices() const noexcept; /// @brief Returns CSR values including preserved structural zeros. const std::vector& Values() const noexcept; /// @brief Multiplies this matrix by a dense vector in stable CSR order. /// @throws std::invalid_argument if the dimensions are incompatible. Vector Multiply(const Vector& rhs) const; /// @brief Validates shape, indices, ordering, and finite CSR values. /// @return Success or a structured model failure. Status Validate() const; private: /// @brief Constructs CSR storage after boundary validation. SparseMatrix(std::size_t rows, std::size_t columns, std::vector row_offsets, std::vector column_indices, std::vector values); std::size_t rows_; std::size_t columns_; std::vector row_offsets_; std::vector column_indices_; std::vector values_; }; } // namespace fesa #endif // FESA_MATH_SPARSE_MATRIX_H_