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;
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
T& operator[] (size_t i) { return this->data[i]; }
constexpr const T& operator[] (size_t i) const { return this->data[i]; }
T& operator[] (int i) { return this->data[i]; }
constexpr const T& operator[] (int i) const { return this->data[i]; }
constexpr T& operator[] (size_t i)& noexcept { return this->data[i]; }
constexpr T& operator[] (int i)& noexcept { 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 cend (void) const { return std::cend (this->data); }

View File

@ -609,19 +609,16 @@ namespace util {
//-------------------------------------------------------------------------
template <
std::size_t S,
typename T,
template <std::size_t,typename> class A,
template <std::size_t,typename> class B,
typename A,
typename B,
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
T
dot (A<S,T> a, B<S,T> b)
constexpr auto
dot (A a, B 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) {
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) ? " }" : " }, ");
}

View File

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