Skip to content
Snippets Groups Projects
Commit acdb69a9 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

Implement axy using sparseRangeFor()

This way it works for multi-type matrices again.
This helps to fix the dune-tnnmg test which currently
breaks.

Notice that this may be slightly less efficient, because
we use a new temporary for each loop instance. This is
necessary because we may need a different type each time.
This may be fixed by adding a specialization for the
case that the corresponding vector is a classic dynamic
container.
parent 056bcfa4
Branches
No related tags found
No related merge requests found
Pipeline #
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "axpy.hh" #include "axpy.hh"
#include "matrixtraits.hh" #include "matrixtraits.hh"
#include "algorithm.hh"
namespace Dune { namespace Dune {
namespace MatrixVector { namespace MatrixVector {
...@@ -40,22 +41,23 @@ namespace MatrixVector { ...@@ -40,22 +41,23 @@ namespace MatrixVector {
static typename VectorType::field_type Axy(const MatrixType &A, static typename VectorType::field_type Axy(const MatrixType &A,
const VectorType &x, const VectorType &x,
const VectorType2 &y) { const VectorType2 &y) {
assert(x.N() == A.M()); assert(x.size() == A.M());
assert(y.N() == A.N()); assert(y.size() == A.N());
typename VectorType::field_type outer = 0.0; using Result = std::decay_t<decltype(y*y)>;
typename VectorType2::block_type inner;
typename MatrixType::ConstIterator endi = A.end(); Result result = 0;
for (typename MatrixType::ConstIterator i = A.begin(); i != endi; ++i) { sparseRangeFor(A, [&](auto&& Ai, auto i) {
inner = 0.0; // ToDo: Provide a specialization using a single temporary
const size_t iindex = i.index(); // for the case that each y[i] has the same type.
typename MatrixType::row_type::ConstIterator endj = i->end(); auto Aix = y[i];
for (typename MatrixType::row_type::ConstIterator j = i->begin(); Aix = 0;
j != endj; ++j) sparseRangeFor(Ai, [&](auto&& Aij, auto j) {
addProduct(inner, *j, x[j.index()]); addProduct(Aix, Aij, x[j]);
outer += inner * y[iindex]; });
} result += Aix * y[i];
return outer; });
return result;
} }
template <class VectorType, class VectorType2> template <class VectorType, class VectorType2>
...@@ -63,23 +65,23 @@ namespace MatrixVector { ...@@ -63,23 +65,23 @@ namespace MatrixVector {
const VectorType2 &b, const VectorType2 &b,
const VectorType &x, const VectorType &x,
const VectorType2 &y) { const VectorType2 &y) {
assert(x.N() == A.M()); assert(x.size() == A.M());
assert(y.N() == A.N()); assert(y.size() == A.N());
assert(y.N() == b.N()); assert(y.size() == b.size());
using Result = std::decay_t<decltype(y*y)>;
typename VectorType::field_type outer = 0.0; Result result = 0;
typename VectorType2::block_type inner; sparseRangeFor(A, [&](auto&& Ai, auto i) {
typename MatrixType::ConstIterator endi = A.end(); // ToDo: Provide a specialization using a single temporary
for (typename MatrixType::ConstIterator i = A.begin(); i != endi; ++i) { // for the case that each b[i] has the same type.
const size_t iindex = i.index(); auto Aix = b[i];
inner = b[iindex]; sparseRangeFor(Ai, [&](auto&& Aij, auto j) {
typename MatrixType::row_type::ConstIterator endj = i->end(); subtractProduct(Aix, Aij, x[j]);
for (typename MatrixType::row_type::ConstIterator j = i->begin(); });
j != endj; ++j) result += Aix * y[i];
subtractProduct(inner, *j, x[j.index()]); });
outer += inner * y[iindex]; return result;
}
return outer;
} }
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment