.. _program_listing_file__tmp_ws_src_proxsuite_include_proxsuite_linalg_sparse_core.hpp: Program Listing for File core.hpp ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/proxsuite/include/proxsuite/linalg/sparse/core.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // // Copyright (c) 2022 INRIA // #ifndef PROXSUITE_LINALG_SPARSE_LDLT_CORE_HPP #define PROXSUITE_LINALG_SPARSE_LDLT_CORE_HPP #include #include #include #include #define SPARSE_LDLT_CONCEPT(...) \ VEG_CONCEPT_MACRO(::proxsuite::linalg::sparse::concepts, __VA_ARGS__) #define SPARSE_LDLT_CHECK_CONCEPT(...) \ VEG_CONCEPT_MACRO(::proxsuite::linalg::sparse::concepts, __VA_ARGS__) namespace proxsuite { namespace linalg { namespace sparse { using proxsuite::linalg::veg::dynstack::DynStackMut; using namespace proxsuite::linalg::veg::literals; using proxsuite::linalg::veg::isize; using proxsuite::linalg::veg::usize; using proxsuite::linalg::veg::Slice; using proxsuite::linalg::veg::SliceMut; using proxsuite::linalg::veg::mut; using proxsuite::linalg::veg::Ref; using proxsuite::linalg::veg::ref; using proxsuite::linalg::veg::RefMut; inline namespace tags { using proxsuite::linalg::veg::Unsafe; using proxsuite::linalg::veg::unsafe; using proxsuite::linalg::veg::from_raw_parts; using proxsuite::linalg::veg::FromRawParts; VEG_TAG(from_eigen, FromEigen); } // namespace tags namespace concepts { } // namespace concepts namespace _detail { template struct WrappingPlusType; template struct WrappingPlusType { using Promoted = unsigned; }; template struct WrappingPlusType { using Promoted = typename std::make_unsigned::type; }; } // namespace _detail namespace util { namespace nb { struct wrapping_plus { template auto operator()(I a, I b) const noexcept -> I { using U = typename _detail::WrappingPlusType::Promoted; return I(U(a) + U(b)); } }; struct checked_non_negative_plus { template auto operator()(I a, I b) const noexcept -> I { return (VEG_ASSERT(wrapping_plus{}(a, b) >= a), // wrapping_plus{}(a, b)); } }; struct wrapping_inc { template auto operator()(RefMut a) const noexcept -> I { return a.get() = wrapping_plus{}(a.get(), I(1)); } }; struct wrapping_dec { template auto operator()(RefMut a) const noexcept -> I { return a.get() = wrapping_plus{}(a.get(), I(-1)); } }; struct sign_extend { template auto operator()(I a) const noexcept -> usize { return usize(isize(typename std::make_signed::type(a))); } }; struct zero_extend { template auto operator()(I a) const noexcept -> usize { return usize(typename std::make_unsigned::type(a)); } }; } // namespace nb VEG_NIEBLOID(wrapping_plus); VEG_NIEBLOID(checked_non_negative_plus); VEG_NIEBLOID(wrapping_inc); VEG_NIEBLOID(wrapping_dec); VEG_NIEBLOID(sign_extend); VEG_NIEBLOID(zero_extend); } // namespace util template struct DenseVecRef { DenseVecRef() = default; DenseVecRef(FromRawParts /*from_raw_parts*/, T const* data, isize len) noexcept : _{ data, len } { } template DenseVecRef(FromEigen /*from_eigen*/, V const& v) noexcept : _{ v.data(), v.rows() } { static_assert(V::InnerStrideAtCompileTime == 1, "."); static_assert(V::ColsAtCompileTime == 1, "."); } auto as_slice() const noexcept -> Slice { return { unsafe, from_raw_parts, _.ptr, _.size, }; } auto nrows() const noexcept -> isize { return _.size; } auto ncols() const noexcept -> isize { return 1; } auto to_eigen() const noexcept -> Eigen::Map const> { return { _.ptr, _.size }; } private: struct { T const* ptr; isize size; } _ = {}; }; template struct DenseVecMut { DenseVecMut() = default; DenseVecMut(FromRawParts /*from_raw_parts*/, T* data, isize len) noexcept : _{ data, len } { } template DenseVecMut(FromEigen /*from_eigen*/, V&& v) noexcept : _{ v.data(), v.rows() } { static_assert( proxsuite::linalg::veg::uncvref_t::InnerStrideAtCompileTime == 1, "."); static_assert(proxsuite::linalg::veg::uncvref_t::ColsAtCompileTime == 1, "."); } auto as_slice() const noexcept -> Slice { return { unsafe, from_raw_parts, _.ptr, _.size, }; } auto as_slice_mut() noexcept -> SliceMut { return { unsafe, from_raw_parts, _.ptr, _.size, }; } auto as_const() const noexcept -> DenseVecRef { return { from_raw_parts, _.ptr, _.size }; } auto nrows() const noexcept -> isize { return _.size; } auto ncols() const noexcept -> isize { return 1; } auto to_eigen() const noexcept -> Eigen::Map> { return { _.ptr, _.size }; } private: struct { T* ptr; isize size; } _ = {}; }; template struct VecRef { VecRef( // FromRawParts /*from_raw_parts*/, isize nrows, isize nnz, I const* row_indices, T const* values) : _{ nrows, nnz, row_indices, values } { } auto nrows() const noexcept -> isize { return _.nrows; } auto ncols() const noexcept -> isize { return 1; } auto nnz() const noexcept -> isize { return _.nnz; } auto row_indices() const noexcept -> I const* { return _.row; } auto values() const noexcept -> T const* { return _.val; } private: struct { isize nrows; isize nnz; I const* row; T const* val; } _; }; namespace _detail { template struct SymbolicMatRefInterface { private: template auto _() const noexcept -> decltype((VEG_DECLVAL(U const&)._)) { return static_cast(this)->_; } public: auto nrows() const noexcept -> isize { return _().nrows; } auto ncols() const noexcept -> isize { return _().ncols; } auto nnz() const noexcept -> isize { return _().nnz; } auto col_ptrs() const noexcept -> I const* { return _().col; } auto nnz_per_col() const noexcept -> I const* { return _().nnz_per_col; } auto is_compressed() const noexcept -> bool { return nnz_per_col() == nullptr; } auto row_indices() const noexcept -> I const* { return _().row; } auto col_start(usize j) const noexcept -> usize { return VEG_ASSERT(j < usize(ncols())), util::zero_extend(_().col[j]); } auto col_start_unchecked(Unsafe /*unsafe*/, usize j) const noexcept -> usize { return VEG_DEBUG_ASSERT(j < usize(ncols())), util::zero_extend(_().col[j]); } auto col_end(usize j) const noexcept -> usize { return VEG_ASSERT(j < usize(ncols())), col_end_unchecked(unsafe, j); } auto col_end_unchecked(Unsafe /*unsafe*/, usize j) const noexcept -> usize { return VEG_DEBUG_ASSERT(j < usize(ncols())), util::zero_extend(is_compressed() ? _().col[j + 1] : I(_().col[j] + _().nnz_per_col[j])); } }; template struct SymbolicMatMutInterface : SymbolicMatRefInterface { private: template auto _() noexcept -> decltype((VEG_DECLVAL(U&)._)) { return static_cast(this)->_; } public: auto col_ptrs_mut() noexcept -> I* { return _().col; } auto nnz_per_col_mut() noexcept -> I* { return _().nnz_per_col; } auto row_indices_mut() noexcept -> I* { return _().row; } }; } // namespace _detail template struct SymbolicMatRef : _detail::SymbolicMatRefInterface, I> { friend struct _detail::SymbolicMatRefInterface; SymbolicMatRef(FromRawParts /*from_raw_parts*/, isize nrows, isize ncols, isize nnz, I const* col_ptrs, I const* nnz_per_col, I const* row_indices) : _{ nrows, ncols, nnz, col_ptrs, nnz_per_col, row_indices, } { } private: struct { isize nrows; isize ncols; isize nnz; I const* col; I const* nnz_per_col; I const* row; } _; }; template struct SymbolicMatMut : _detail::SymbolicMatMutInterface, I> { friend struct _detail::SymbolicMatRefInterface; friend struct _detail::SymbolicMatMutInterface; SymbolicMatMut(FromRawParts /*from_raw_parts*/, isize nrows, isize ncols, isize nnz, I* col_ptrs, I* nnz_per_col, I* row_indices) : _{ nrows, ncols, nnz, col_ptrs, nnz_per_col, row_indices, } { } auto as_const() const noexcept -> SymbolicMatRef { return { from_raw_parts, this->nrows(), this->ncols(), this->nnz(), this->col_ptrs(), this->nnz_per_col(), this->row_indices(), }; } private: struct { isize nrows; isize ncols; isize nnz; I* col; I* nnz_per_col; I* row; } _; }; template struct MatRef : _detail::SymbolicMatRefInterface, I> { friend struct _detail::SymbolicMatRefInterface; MatRef(FromRawParts /*from_raw_parts*/, isize nrows, isize ncols, isize nnz, I const* col_ptrs, I const* nnz_per_col, I const* row_indices, T const* values) : _{ nrows, ncols, nnz, col_ptrs, nnz_per_col, row_indices, values, } { } template MatRef(FromEigen /*from_eigen*/, M const& m) : _{ m.rows(), m.cols(), m.nonZeros(), m.outerIndexPtr(), m.innerNonZeroPtr(), m.innerIndexPtr(), m.valuePtr(), } { static_assert(!bool(M::IsRowMajor), "."); } auto values() const noexcept -> T const* { return _.val; } auto symbolic() const noexcept -> SymbolicMatRef { return { from_raw_parts, this->nrows(), this->ncols(), this->nnz(), this->col_ptrs(), this->nnz_per_col(), this->row_indices(), }; } auto to_eigen() const noexcept -> Eigen::Map const> { return { _.nrows, _.ncols, _.nnz, _.col, _.row, _.val, _.nnz_per_col }; } private: struct { isize nrows; isize ncols; isize nnz; I const* col; I const* nnz_per_col; I const* row; T const* val; } _; }; template struct MatMut : _detail::SymbolicMatMutInterface, I> { friend struct _detail::SymbolicMatRefInterface; friend struct _detail::SymbolicMatMutInterface; MatMut(FromRawParts /*from_raw_parts*/, isize nrows, isize ncols, isize nnz, I* col_ptrs, I* nnz_per_col, I* row_indices, T* values) : _{ nrows, ncols, nnz, col_ptrs, nnz_per_col, row_indices, values, } { } template MatMut(FromEigen /*from_eigen*/, M&& m) : _{ m.rows(), m.cols(), m.nonZeros(), m.outerIndexPtr(), m.innerNonZeroPtr(), m.innerIndexPtr(), m.valuePtr(), } { static_assert(!bool(proxsuite::linalg::veg::uncvref_t::IsRowMajor), "."); } auto values() const noexcept -> T const* { return _.val; } auto values_mut() const noexcept -> T* { return _.val; } auto is_compressed() const noexcept -> bool { return _.nnz_per_col == nullptr; } auto as_const() const noexcept -> MatRef { return { from_raw_parts, this->nrows(), this->ncols(), this->nnz(), this->col_ptrs(), this->nnz_per_col(), this->row_indices(), this->values(), }; } auto symbolic() const noexcept -> SymbolicMatRef { return { from_raw_parts, this->nrows(), this->ncols(), this->nnz(), this->col_ptrs(), this->nnz_per_col(), this->row_indices(), }; } auto symbolic_mut() const noexcept -> SymbolicMatRef { return { from_raw_parts, this->nrows(), this->ncols(), this->nnz(), this->col_ptrs_mut(), this->nnz_per_col_mut(), this->row_indices_mut(), }; } auto to_eigen() const noexcept -> Eigen::Map> { return { _.nrows, _.ncols, _.nnz, _.col, _.row, _.val, _.nnz_per_col }; } void _set_nnz(isize new_nnz) noexcept { _.nnz = new_nnz; } private: struct { isize nrows; isize ncols; isize nnz; I* col; I* nnz_per_col; I* row; T* val; } _; }; } // namespace sparse } // namespace linalg } // namespace proxsuite #endif /* end of include guard PROXSUITE_LINALG_SPARSE_LDLT_CORE_HPP */