Skip to content
Snippets Groups Projects
Select Git revision
  • 70bfde9a7de7fa3495d9e2bd7142cb1bc656484e
  • esp32_c3_bringup default
  • master
3 results

cryptodev-vhost-user.c

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    triangularsolve.hh 4.74 KiB
    #ifndef DUNE_MATRIX_VECTOR_TRIANGULARSOLVE_HH
    #define DUNE_MATRIX_VECTOR_TRIANGULARSOLVE_HH
    
    namespace Dune {
    namespace MatrixVector {
    
      /**
       * \brief Solves L*x=b where L is a lower triangular matrix.
       * \param x Solution vector. Make sure the ignored nodes are set
       *        correctly because their respective values for x as passed to
       *        this method may affect other lines.
       * \param ignore Tags the lines of the system where x shall not be
       *        computed. Note that ignored nodes might still influence the
       *        solution of other lines if not set to zero.
       * \param transpose Set true if L is passed as an upper triangular matrix.
       */
      // Note: The current assert makes sure we actually deal with triangular
      //       matrices. It might be favorable to support matrices as well
      //       where other entries are not required to be non-existent, e.g.
      //       if one has a in-place decomposition and does not want to
      //       reimplement the iterators.
      template <class Matrix, class Vector, class BitVector>
      static void lowerTriangularSolve(Matrix const& L, Vector b, Vector& x,
                                       BitVector const* ignore,
                                       bool transpose = false) {
        if (transpose) {
          for (auto it = L.begin(); it != L.end(); ++it) {
            const size_t i = it.index();
            auto cIt = it->begin();
            assert(cIt.index() == i);
            if (ignore == nullptr or (*ignore)[cIt.index()].none())
              x[i] = b[i] / *cIt;
            cIt++;
            for (; cIt != it->end(); ++cIt) {
              const size_t j = cIt.index();
              assert(j > i);
              // Note: We could drop the check for ignore nodes here bcs. b[j] will
              // be ignored anyway due to the check above.
              if (ignore == nullptr or (*ignore)[j].none())
                b[j] -= x[i] * *cIt;
            }
          }
        } else {
          for (auto it = L.begin(); it != L.end(); ++it) {
            const size_t i = it.index();
            if (ignore != nullptr and (*ignore)[i].all())
              continue;
            for (auto cIt = it->begin(); cIt != it->end(); ++cIt) {
              const size_t j = cIt.index();
              assert(j <= i);
              if (j < i) {
                b[i] -= *cIt * x[j];
                continue;
              }
              assert(j == i);
              x[i] = b[i] / *cIt;
            }
          }
        }
      }
    
      /**
       * \brief Same as lowerTriangularSolve. Ignored nodes are set to 0.
       */
      template <class Matrix, class Vector, class BitVector>
      static Vector lowerTriangularSolve(Matrix const& L, Vector b,
                                         BitVector const* ignore,
                                         bool transpose = false) {
        Vector x = b;
        x = 0;
        lowerTriangularSolve(L, std::move(b), x, ignore, transpose);
        return x;
      }
    
      /**
       * \brief Solves U*x=b where U is an upper triangular matrix.
       *        See @lowerTriangularSolve for details.
       */
      template <class Matrix, class Vector, class BitVector>
      static void upperTriangularSolve(Matrix const& U, Vector b, Vector& x,
                                       BitVector const* ignore,
                                       bool transpose = false) {
        if (transpose) {
          for (auto it = U.beforeEnd(); it != U.beforeBegin(); --it) {
            const size_t i = it.index();
            auto cIt = it->beforeEnd();
            assert(cIt.index() == i);
            if (ignore == nullptr or (*ignore)[cIt.index()].none())
              x[i] = b[i] / *cIt;
            cIt--;
            for (; cIt != it->beforeBegin(); --cIt) {
              const size_t j = cIt.index();
              assert(j < i);
              // Note: We could drop the check for ignore nodes here bcs. b[j] will
              // be ignored anyway due to the check above.
              if (ignore == nullptr or (*ignore)[j].none())
                b[j] -= *cIt * x[i];
            }
          }
        } else {
          for (auto it = U.beforeEnd(); it != U.beforeBegin(); --it) {
            const size_t i = it.index();
            if (ignore != nullptr and (*ignore)[i].all())
              continue;
            auto cIt = it->beforeEnd();
            for (; cIt != it->begin(); --cIt) {
              const size_t j = cIt.index();
              assert(j > i);
              b[i] -= *cIt * x[j];
            }
            assert(cIt.index() == i);
            x[i] = b[i] / *cIt;
          }
        }
      }
    
      /**
       * \brief Same as upperTriangularSolve. Ignored nodes are set to 0.
       */
      template <class Matrix, class Vector, class BitVector>
      static Vector upperTriangularSolve(Matrix const& U, Vector b,
                                         BitVector const* ignore,
                                         bool transpose = false) {
        Vector x = b;
        x = 0;
        upperTriangularSolve(U, std::move(b), x, ignore, transpose);
        return x;
      }
    
    } // end namespace MatrixVector
    } // end namespace Dune
    
    #endif // DUNE_MATRIX_VECTOR_TRIANGULARSOLVE_HH