I'm trying to modify my linear algebra module to avoid the virtual vtable things.. Trying to use CRTP and expression template. I went with something basic that should test the whole thing, and I can't get it work.
I have 4 classes, say: The base CRTP class, here Mathbase
template <typename Derived>
class Mathbase
{
public:
using T = typename dense_traits<Derived>::T;
Derived& derived() { return static_cast<Derived&>(*this); }
const Derived& derived() const { return static_cast<const Derived&>(*this); }
T& coeff(std::size_t row, std::size_t col) { return derived().coeff(row, col); }
const T& coeff(std::size_t row, std::size_t col) const { return derived().coeff(row, col); }
T& coeff(std::size_t index) { return derived().coeff(index); }
const T& coeff(std::size_t index) const { return derived().coeff(index); }
};
Then, a Densebase in which I implements functions like transpose, determinant, etc:
template <typename Derived>
class Densebase : public Mathbase<Derived>
{
public:
using Submat = Subview<Derived, dense_traits<Derived>::M-1, dense_traits<Derived>::N-1>;
using ConstSubmat = const Subview<const Derived, dense_traits<Derived>::M-1, dense_traits<Derived>::N-1>;
Submat sub(std::size_t row, std::size_t col) { return Submat(derived(), row, col); }
ConstSubmat sub(std::size_t row, std::size_t col) const { return ConstSubmat(derived(), row, col); }
};
Note that it declares two types that makes a references on a parent matrix (co-matrix) Then I have the Matrix class, that implements coeff functions by accessing its storage:
template <typename T, std::size_t M, std::size_t N>
class Matrix : public Densebase<Matrix<T,M,N>>
{
// nothing fancy
};
Now, two things aren't working:
-
I implemented a determinant helper which uses laplace expansion (calculating co-matrix determinants and summing them up, sadly it failed to compile
template <typename Derived, std::size_t N> struct det_helper { static inline typename dense_traits<Derived>::T run(const Densebase<Derived>& dense) { typename dense_traits<Derived>::T det = 0; // Laplace expansion for (std::size_t i = 0; i < N; ++i) det += ((i & 1) ? -1 : 1)*dense.coeff(0,i)*det_helper::run(dense.sub(0,i)); return det; } }; template <typename Derived> struct det_helper<Derived, 2> { static inline typename dense_traits<Derived>::T run(const Densebase<Derived>& dense) { return dense.coeff(0,0)*dense.coeff(1,1) - dense.coeff(0,1)*dense.coeff(1,0); } };
And called like this:
T determinant() const
{
return det_helper<Derived, dense_traits<Derived>::M>::run(derived());
}
- The 2nd problem is when I implemented an overload on
<< stream operatorwhich works fine on Matrix but crash onstream << matrix.sub(0,0);without even entering in the function.
Aucun commentaire:
Enregistrer un commentaire