Commits

Anonymous committed 74f6c48

Added in-place matrix multiplication, fixed a bug, made default matrix
constructor leave the matrix uninitialized.

  • Participants
  • Parent commits bc8b30e

Comments (0)

Files changed (3)

neglect/cpplib/include/neglect/matrix.hpp

         static const size_t columns = N;
         static const size_t dimensions = M * N;
 
+        /* default constructor, warning: does not initialize the matrix */
         matrix()
         {
-            set_zero();
         }
 
         template <class Sequence>
 
         static neglect::matrix<T, M, N> zero()
         {
-            return neglect::matrix<T, M, N>();
+            neglect::matrix<T, M, N> rv;
+            rv.set_zero();
+            return rv;
         }
 
         static neglect::matrix<T, M, N> identity()
             return m_cols[column][row];
         }
 
-        const T &operator()(size_t row, size_t column) const
+        T operator()(size_t row, size_t column) const
         {
             return m_cols[column][row];
         }
 
     // matrix factory functions
 
+    /* multiply two matrices */
+    template <typename T, size_t M, size_t N, size_t P>
+    matrix<T, M, P> operator*(const matrix<T, M, N> &lhs,
+                              const matrix<T, N, P> &rhs)
+    {
+        matrix<T, M, P> rv;
+        for (size_t i = 0; i < M; i++)
+            for (size_t j = 0; j < P; j++) {
+                for (size_t k = 0; k < N; k++)
+                    rv(i, j) += lhs(i, k) * rhs(k, j);
+            }
+        return rv;
+    }
+
+    /* in-place multiplication is possible if the dimension of
+       lhs is the dimension of the resulting matrix. */
+    template <typename T, size_t M, size_t N>
+    matrix<T, M, N> &operator*=(matrix<T, M, N> &lhs,
+                                const matrix<T, N, N> &rhs)
+    {
+        for (size_t i = 0; i < M; i++)
+            for (size_t j = 0; j < N; j++) {
+                T sum = T();
+                for (size_t k = 0; k < N; k++)
+                    sum += lhs(i, k) * rhs(k, j);
+                lhs(i, j) = sum;
+            }
+        return lhs;
+    }
+
     /* creates a scale matrix */
     template <typename T>
     matrix<T, 4, 4> scale_matrix(T sx, T zy, T sz)
     {
-        matrix<T, 4, 4> m;
+        matrix<T, 4, 4> m::zero();
         m[0][0] = sx;
         m[1][1] = sy;
         m[2][2] = sz;
     template <typename T>
     matrix<T, 4, 4> translation_matrix(T tx, T ty, T tz)
     {
-        matrix<T, 4, 4> m;
-        m.set_identity();
+        matrix<T, 4, 4> m::identity();
         vector<T, 4> &last = m[3];
         last[0] = tx;
         last[1] = ty;
                             ic * y * z - sz,
                             ic * z * z + c,
                             T());
-        m[3][3] = T(1);
+        m[3] = vector<T, 4>(T(), T(), T(), T(1));
         return m;
     }
 }

neglect/cpplib/include/neglect/matrix_io.hpp

 
 namespace neglect {
 
-    template <typename T, size_t Width, size_t Height>
+    template <typename T, size_t M, size_t N>
     std::ostream &operator<<(std::ostream &lhs,
-        const neglect::matrix<T, Width, Height> &rhs)
+        const neglect::matrix<T, M, N> &rhs)
     {
         lhs << "[";
-        for (size_t row = 0; row < Height; row++) {
+        for (size_t row = 0; row < M; row++) {
             if (row)
                 lhs << "," << std::endl << " ";
-            for (size_t column = 0; column < Width; column++) {
+            for (size_t column = 0; column < N; column++) {
                 if (column)
                     lhs << ", ";
                 lhs << rhs[column][row];

neglect/tests/src/test_matrix.cpp

     NUT_TESTCASE(matrix_functions)
     {
         matrix<float, 2, 3> mat;
+        mat.set_zero();
         mat[0][1] = 1.0f;
         mat[2][0] = 3.0f;
         matrix<float, 3, 2> mat_t = transpose(mat);
         NUT_CHECK_EQUAL(mat_t[0][2], 3.0f);
         NUT_CHECK_EQUAL(mat_t[0][0], 0.0f);
     }
+
+    NUT_TESTCASE(matrix_multiplication)
+    {
+        mat3 m1;
+        m1[0] = vec3(1, 4, 7);
+        m1[1] = vec3(2, 5, 8);
+        m1[2] = vec3(3, 6, 9);
+        matrix<float, 3, 2> m2;
+        m2[0] = vec3(1, 3, 5);
+        m2[1] = vec3(2, 4, 6);
+
+        matrix<float, 3, 2> expected;
+        expected[0] = vec3(22, 49, 76);
+        expected[1] = vec3(28, 64, 100);
+
+        matrix<float, 3, 2> m3 = m1 * m2;
+        NUT_CHECK_EQUAL(m3, expected);
+    }
+
+    NUT_TESTCASE(matrix_inplace_multiply)
+    {
+        mat2 m1, m2, m3, expected;
+        m1[0] = vec2(1, 0);
+        m1[1] = vec2(1, 1);
+        m2[0] = vec2(1, 1);
+        m2[1] = vec2(0, 1);
+        expected[0] = vec2(2, 1);
+        expected[1] = vec2(1, 1);
+        m3 = m1 * m2;
+        m1 *= m2;
+        NUT_CHECK_EQUAL(m1, expected);
+        NUT_CHECK_EQUAL(m1, m3);
+    }
 }