matrix: use vector for the row storage

This commit is contained in:
Danny Robson 2017-11-24 13:08:56 +11:00
parent 59240ce83a
commit a8088d03cd
6 changed files with 59 additions and 43 deletions

View File

@ -73,13 +73,20 @@ namespace util::coord {
} }
constexpr base (const base<S,T,SelfT> &rhs) = default; constexpr base (const base<S,T,SelfT> &rhs) = default;
base& operator= (const base<S,T,SelfT> &rhs) = default; base& operator= (const base<S,T,SelfT> &rhs)& = default;
base& operator= (const T t)&
{
for (auto v: *this)
v = t;
return *this;
}
// element accessors // element accessors
T& operator[] (size_t i) { return this->data[i]; } constexpr T& operator[] (size_t i)& noexcept { return this->data[i]; }
constexpr const T& operator[] (size_t i) const { return this->data[i]; } constexpr T& operator[] (int i)& noexcept { return this->data[i]; }
T& operator[] (int i) { return this->data[i]; }
constexpr const T& operator[] (int i) const { return this->data[i]; } constexpr const T& operator[] (size_t i) const& noexcept { return this->data[i]; }
constexpr const T& operator[] (int i) const& noexcept { return this->data[i]; }
auto cbegin (void) const { return std::cbegin (this->data); } auto cbegin (void) const { return std::cbegin (this->data); }
auto cend (void) const { return std::cend (this->data); } auto cend (void) const { return std::cend (this->data); }

View File

@ -609,19 +609,16 @@ namespace util {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template < template <
std::size_t S, typename A,
typename T, typename B,
template <std::size_t,typename> class A,
template <std::size_t,typename> class B,
typename = std::enable_if_t< typename = std::enable_if_t<
is_coord_v<A<S,T>> && is_coord_v<B<S,T>>, void is_coord_v<A> && is_coord_v<B>, void
> >
> >
constexpr constexpr auto
T dot (A a, B b)
dot (A<S,T> a, B<S,T> b)
{ {
return dot<S,T> (a.data, b.data); return dot (a.data, b.data);
} }

View File

@ -352,7 +352,7 @@ util::operator<< (std::ostream &os, const matrix<Rows,Cols,T> &m)
for (std::size_t i = 0; i < Rows; ++i) { for (std::size_t i = 0; i < Rows; ++i) {
os << "{ "; os << "{ ";
std::copy_n (m[i], Cols, util::infix_iterator<float> (os, ", ")); std::copy (std::cbegin (m[i]), std::cend (m[i]), util::infix_iterator<float> (os, ", "));
os << ((i == Rows - 1) ? " }" : " }, "); os << ((i == Rows - 1) ? " }" : " }, ");
} }

View File

@ -34,17 +34,25 @@ namespace util {
static constexpr auto rows = Rows; static constexpr auto rows = Rows;
static constexpr auto cols = Cols; static constexpr auto cols = Cols;
using row_t = util::vector<Cols,T>;
///////////////////////////////////////////////////////////////////////
constexpr matrix () noexcept = default; constexpr matrix () noexcept = default;
//---------------------------------------------------------------------
constexpr matrix (const T(&_data)[Rows][Cols]) noexcept: constexpr matrix (const T(&_data)[Rows][Cols]) noexcept:
values {} values {}
{ {
static_assert (sizeof (*this) == sizeof (T) * Rows * Cols);
for (std::size_t r = 0; r < Rows; ++r) for (std::size_t r = 0; r < Rows; ++r)
for (std::size_t c = 0; c < Cols; ++c) for (std::size_t c = 0; c < Cols; ++c)
values[r][c] = _data[r][c]; values[r][c] = _data[r][c];
} }
//---------------------------------------------------------------------
template <std::size_t S, typename SelfT> template <std::size_t S, typename SelfT>
constexpr matrix (const util::coord::base<S,T,SelfT> (&_data)[Rows]) noexcept constexpr matrix (const util::coord::base<S,T,SelfT> (&_data)[Rows]) noexcept
{ {
@ -53,55 +61,54 @@ namespace util {
values[r][c] = _data[r][c]; values[r][c] = _data[r][c];
} }
T values[Rows][Cols];
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// index operators return a pointer into the data array so that // index operators return a pointer into the data array so that
// multidimensional array syntax can be used transparently on this // multidimensional array syntax can be used transparently on this
// type. // type.
constexpr auto& operator[] (std::size_t idx) { return values[idx]; } constexpr row_t& operator[] (std::size_t idx)& { return values[idx]; }
constexpr const auto& operator[] (std::size_t idx) const { return values[idx]; } constexpr const row_t& operator[] (std::size_t idx) const& { return values[idx]; }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
constexpr auto constexpr row_t*
data (void)& noexcept data (void)& noexcept
{ {
return begin (); return &values[0];
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
constexpr auto constexpr const row_t*
data (void) const& noexcept data (void) const& noexcept
{ {
return begin (); return &values[0];
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
constexpr auto constexpr auto
begin (void) const& noexcept begin (void) const& noexcept
{ {
return &(*this)[0][0]; return data ();
}
//---------------------------------------------------------------------
constexpr auto
end (void) const& noexcept
{
return &(*this)[Rows][0];
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
constexpr auto constexpr auto
begin (void)& noexcept begin (void)& noexcept
{ {
return &(*this)[0][0]; return data ();
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
constexpr auto constexpr row_t*
end (void)& noexcept end (void)& noexcept
{ {
return &(*this)[Rows][0]; return &values[Rows];
}
//---------------------------------------------------------------------
constexpr const row_t*
end (void) const& noexcept
{
return &values[Rows];
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
@ -138,8 +145,8 @@ namespace util {
{ {
VectorT out; VectorT out;
for (std::size_t i = 0; i < Rows; ++i) for (std::size_t r = 0; r < Rows; ++r)
out[i] = dot (rhs, values[i]); out[r] = dot (rhs, values[r]);
return out; return out;
} }
@ -169,9 +176,13 @@ namespace util {
matrix zeroes (void) noexcept matrix zeroes (void) noexcept
{ {
matrix ret {}; matrix ret {};
std::fill (std::begin (ret), std::end (ret), T{0}); std::fill (std::begin (ret), std::end (ret), row_t{0});
return ret; return ret;
} }
private:
row_t values[Rows];
}; };
@ -346,7 +357,8 @@ namespace util {
abs (const matrix<Rows,Cols,T> &src) abs (const matrix<Rows,Cols,T> &src)
{ {
matrix<Rows,Cols,T> dst; matrix<Rows,Cols,T> dst;
std::transform (std::cbegin (src), std::cend (src), std::begin (dst), util::abs<T>); for (size_t r = 0; r < Rows; ++r)
dst[r] = abs (src[r]);
return dst; return dst;
} }
@ -355,7 +367,10 @@ namespace util {
constexpr T constexpr T
sum (const matrix<Rows,Cols,T> &src) sum (const matrix<Rows,Cols,T> &src)
{ {
return sum (std::cbegin (src), std::cend (src)); util::vector<Rows,T> accum {};
for (size_t r = 0; r < Rows; ++r)
accum[r] = sum (src[r]);
return sum (accum);
} }

View File

@ -104,9 +104,6 @@ test_mq_euler (util::TAP::logger &tap)
util::quaternionf::angle_axis (t.z, { 0, 0, 1 }) util::quaternionf::angle_axis (t.z, { 0, 0, 1 })
).as_matrix (); ).as_matrix ();
if (abs (m - q)[0])
exit (0);
auto diff = util::sum (abs (m - q)); auto diff = util::sum (abs (m - q));
tap.expect_le (diff, 1e-6f, "matrix-quaternion xyz euler rotations, %s", t.msg); tap.expect_le (diff, 1e-6f, "matrix-quaternion xyz euler rotations, %s", t.msg);
} }

View File

@ -112,9 +112,9 @@ main (void)
for (size_t r = 0; r < m.rows; ++r) for (size_t r = 0; r < m.rows; ++r)
for (size_t c = 0; c < m.cols; ++c) for (size_t c = 0; c < m.cols; ++c)
if (r == c) if (r == c)
success = success && util::almost_equal (m.values[r][c], 1.f); success = success && util::almost_equal (m[r][c], 1.f);
else else
success = success && util::almost_equal (m.values[r][c], 0.f); success = success && util::almost_equal (m[r][c], 0.f);
tap.expect (success, "identity inversion"); tap.expect (success, "identity inversion");
} }