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.