13#include <Eigen/Sparse>
15namespace smooth::feedback {
33template<
typename Source,
int Options>
34 requires(std::is_base_of_v<Eigen::EigenBase<Source>, Source>)
36 Eigen::SparseMatrix<double, Options> & dest,
39 const Source & source,
41 bool upper_only =
false)
43 for (
auto c = 0; c < source.outerSize(); ++c) {
44 for (Eigen::InnerIterator it(source, c); it; ++it) {
45 if (!upper_only || row0 + it.row() <= col0 + it.col()) {
46 dest.coeffRef(row0 + it.row(), col0 + it.col()) += scale * it.value();
68template<
typename Source,
int Options>
69 requires(std::is_base_of_v<Eigen::EigenBase<Source>, Source>)
71 Eigen::SparseMatrix<double, Options> & dest,
74 const Source & source,
76 bool upper_only =
false)
78 for (
auto c = 0; c < source.outerSize(); ++c) {
79 for (Eigen::InnerIterator it(source, c); it; ++it) {
80 if (!upper_only || row0 + it.row() <= col0 + it.col()) {
81 dest.coeffRef(row0 + it.row(), col0 + it.col()) = scale * it.value();
104 Eigen::SparseMatrix<double, Options> & dest, Eigen::Index row0, Eigen::Index col0, Eigen::Index n,
double scale = 1)
106 for (
auto k = 0u; k < n; ++k) { dest.coeffRef(row0 + k, col0 + k) += scale; }
126 Eigen::SparseMatrix<double, Options> & dest, Eigen::Index row0, Eigen::Index col0, Eigen::Index n,
double scale = 1)
128 for (
auto k = 0u; k < n; ++k) { dest.coeffRef(row0 + k, col0 + k) = scale; }
138template<
typename SparseMat>
139 requires(std::is_base_of_v<Eigen::SparseCompressedBase<std::decay_t<SparseMat>>, std::decay_t<SparseMat>>)
142 if (mat.isCompressed()) {
143 mat.coeffs().setZero();
145 for (
auto i = 0; i < mat.outerSize(); ++i) {
146 for (
typename std::decay_t<
decltype(mat)>::InnerIterator it(mat, i); it; ++it) { it.valueRef() = 0; }
156template<
typename Mat>
157 requires(std::is_base_of_v<Eigen::EigenBase<Mat>, Mat>)
161 for (
auto c = 0; c < mat.outerSize(); ++c) {
162 for (Eigen::InnerIterator it(mat, c); it; ++it) {
163 if (it.value() == 0) { ++ret; }
179template<
typename Mat>
180 requires(std::is_base_of_v<Eigen::EigenBase<Mat>, Mat>)
183 Eigen::MatrixX<typename Mat::Scalar> ret;
184 ret.setConstant(mat.rows(), mat.cols(), 0);
185 for (
auto c = 0; c < mat.outerSize(); ++c) {
186 for (Eigen::InnerIterator it(mat, c); it; ++it) {
187 if (it.value() == 0) {
188 ret(it.row(), it.col()) = 9;
190 ret(it.row(), it.col()) = 1;
210template<
typename S1,
typename S2,
typename S3,
typename S4>
211 requires(std::is_base_of_v<Eigen::EigenBase<S1>, S1> && std::is_base_of_v<Eigen::EigenBase<S2>, S2> &&
212 std::is_base_of_v<Eigen::EigenBase<S3>, S3> && std::is_base_of_v<Eigen::EigenBase<S4>, S4>)
214 Eigen::SparseMatrix<double> & out,
222 const auto No = Jf.rows();
223 const auto Ny = Jf.cols();
225 [[maybe_unused]]
const auto Ni = Jg.rows();
226 const auto Nx = Jg.cols();
230 assert(Hf.rows() == Ny);
231 assert(Hf.cols() == No * Ny);
232 assert(Hg.rows() == Nx);
233 assert(Hg.cols() == Ni * Nx);
235 for (
auto no = 0u; no < No; ++no) {
237 block_add(out, r0, c0 + no * Nx, Jg.transpose() * Hf.middleCols(no * Ny, Ny) * Jg);
240 for (
auto i = 0u; i < Jf.outerSize(); ++i) {
241 for (Eigen::InnerIterator it(Jf, i); it; ++it) {
242 block_add(out, r0, c0 + it.row() * Nx, Hg.middleCols(it.col() * Nx, Nx), it.value());
void set_zero(MeshValue< Deriv > &mv)
Reset MeshValue to zeros.
void d2r_fog(Eigen::SparseMatrix< double > &out, const S1 &Jf, const S2 &Hf, const S3 &Jg, const S4 &Hg, Eigen::Index r0=0, Eigen::Index c0=0)
(Right) Hessian of composed function .
void block_write(Eigen::SparseMatrix< double, Options > &dest, Eigen::Index row0, Eigen::Index col0, const Source &source, double scale=1, bool upper_only=false)
Write block into a sparse matrix.
void block_add_identity(Eigen::SparseMatrix< double, Options > &dest, Eigen::Index row0, Eigen::Index col0, Eigen::Index n, double scale=1)
Add identity matrix block into sparse matrix.
void block_add(Eigen::SparseMatrix< double, Options > &dest, Eigen::Index row0, Eigen::Index col0, const Source &source, double scale=1, bool upper_only=false)
Add block into a sparse matrix.
void block_write_identity(Eigen::SparseMatrix< double, Options > &dest, Eigen::Index row0, Eigen::Index col0, Eigen::Index n, double scale=1)
Write identity matrix block into sparse matrix.
Eigen::MatrixX< typename Mat::Scalar > mark_explicit_zeros(const Mat &mat)
Mark explicit zeros in sparse matrix.
uint64_t count_explicit_zeros(const Mat &mat)
Count number of explicit zeros in sparse matrix.