Commits

committed 8383d9a

Add in-place operators to Matrix, and restructure code to use them as the primary operators.

Matrix/Matrix/Matrix.h

` #pragma once`
` `
` #include <cmath>`
`+#include <utility>`
` `
` namespace Math`
` {`
`     template<class T, int Rows, int Cols>`
`-    struct __declspec(align(16)) Matrix`
`+    struct Matrix;`
`+`
`+    namespace Matrix_detail`
`+    {`
`+        template<class T, int Rows, int Cols>`
`+        Matrix<T, Rows, Cols>& iadd(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r);`
`+`
`+        template<class T, int Rows, int Cols>`
`+        Matrix<T, Rows, Cols>& isub(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r);`
`+`
`+        template<class T, int Rows, int Cols>`
`+        Matrix<T, Rows, Cols>& imul_s(Matrix<T, Rows, Cols> &m, T s);`
`+`
`+        template<class T, int Rows, int Cols>`
`+        Matrix<T, Rows, Cols>& idiv_s(Matrix<T, Rows, Cols> &m, T s);`
`+`
`+        template<class T, int Rows, int Cols>`
`+        Matrix<T, Rows, Cols>& imul(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r);`
`+    }`
`+`
`+#define MATRIX_IOPS(Rows, Cols)                                                                                 \`
`+    Matrix<T, Rows, Cols>& operator+=(const Matrix<T, Rows, Cols> &m) { return Matrix_detail::iadd(*this, m); } \`
`+    Matrix<T, Rows, Cols>& operator-=(const Matrix<T, Rows, Cols> &m) { return Matrix_detail::isub(*this, m); } \`
`+    Matrix<T, Rows, Cols>& operator*=(const Matrix<T, Rows, Cols> &m) { return Matrix_detail::imul(*this, m); } \`
`+    Matrix<T, Rows, Cols>& operator*=(T s) { return Matrix_detail::imul_s(*this, s); }                          \`
`+    Matrix<T, Rows, Cols>& operator/=(T s) { return Matrix_detail::idiv_s(*this, s); }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    struct Matrix`
`     {`
`         T operator()(int row, int col) const`
`         {`
`             return raw_data[row][col];`
`         }`
` `
`+        MATRIX_IOPS(Rows, Cols)`
`+`
`         T raw_data[Rows][Cols];`
`     };`
` `
`     template<class T, int Rows>`
`-    struct __declspec(align(16)) Matrix<T, Rows, 1>`
`+    struct Matrix<T, Rows, 1>`
`     {`
`         T operator()(int row, int /*col*/) const`
`         {`
`             return raw_data[index];`
`         }`
` `
`+        MATRIX_IOPS(Rows, 1)`
`+`
`         T raw_data[Rows];`
`     };`
` `
`     template<class T>`
`-    struct __declspec(align(16)) Matrix<T, 3, 1>`
`+    struct Matrix<T, 3, 1>`
`     {`
`         T operator()(int row, int /*col*/) const`
`         {`
`             }`
`         }`
` `
`+        MATRIX_IOPS(3, 1)`
`+`
`         T x, y, z;`
`     };`
` `
`     template<class T>`
`-    struct __declspec(align(16)) Matrix<T, 4, 1>`
`+    struct Matrix<T, 4, 1>`
`     {`
`         T operator()(int row, int /*col*/) const`
`         {`
`             }`
`         }`
` `
`+        MATRIX_IOPS(4, 1)`
`+`
`         T x, y, z, w;`
`     };`
` `
`     template<class T, int Cols>`
`-    struct __declspec(align(16)) Matrix<T, 1, Cols>`
`+    struct Matrix<T, 1, Cols>`
`     {`
`         T operator()(int /*row*/, int col) const`
`         {`
`             return raw_data[index];`
`         }`
` `
`+        MATRIX_IOPS(1, Cols)`
`+`
`         T raw_data[Cols];`
`     };`
` `
`     template<class T>`
`-    struct __declspec(align(16)) Matrix<T, 1, 3>`
`+    struct Matrix<T, 1, 3>`
`     {`
`         T operator()(int /*row*/, int col) const`
`         {`
`             }`
`         }`
` `
`+        MATRIX_IOPS(1, 3)`
`+`
`         T x, y, z;`
`     };`
` `
`     template<class T>`
`-    struct __declspec(align(16)) Matrix<T, 1, 4>`
`+    struct Matrix<T, 1, 4>`
`     {`
`         T operator()(int /*row*/, int col) const`
`         {`
`             }`
`         }`
` `
`+        MATRIX_IOPS(1, 4)`
`+`
`         T x, y, z, w;`
`     };`
` `
`     template<class T>`
`-    struct __declspec(align(16)) Matrix<T, 1, 1>`
`+    struct Matrix<T, 1, 1>`
`     {`
`         T operator()(int row, int col) const`
`         {`
`             return value;`
`         }`
` `
`+        MATRIX_IOPS(1, 1)`
`+`
`         T value;`
`     };`
` `
`     namespace Matrix_detail`
`     {`
`         template<class T, int Rows, int Cols>`
`-        Matrix<T, Rows, Cols> add(const Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)`
`+        Matrix<T, Rows, Cols>& iadd(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)`
`         {`
`-            Matrix<T, Rows, Cols> result;`
`-`
`             for(int i = 0; i < Rows; ++i)`
`                 for(int j = 0; j < Cols; ++j)`
`-                    result(i, j) = l(i, j) + r(i, j);`
`+                    l(i, j) += r(i, j);`
` `
`-            return result;`
`+            return l;`
`         }`
` `
`         template<class T, int Rows, int Cols>`
`-        Matrix<T, Rows, Cols> scalar_multiply(const Matrix<T, Rows, Cols> &m, T s)`
`+        Matrix<T, Rows, Cols>& isub(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)`
`         {`
`-            Matrix<T, Rows, Cols> result;`
`-            `
`             for(int i = 0; i < Rows; ++i)`
`                 for(int j = 0; j < Cols; ++j)`
`-                    result(i, j) = m(i, j) * s;`
`+                    l(i, j) -= r(i, j);`
` `
`-            return result;`
`+            return l;`
`         }`
` `
`         template<class T, int Rows, int Cols>`
`-        Matrix<T, Rows, Cols> scalar_divide(const Matrix<T, Rows, Cols> &m, T s)`
`+        Matrix<T, Rows, Cols>& imul_s(Matrix<T, Rows, Cols> &m, T s)`
`         {`
`-            Matrix<T, Rows, Cols> result;`
`-            `
`             for(int i = 0; i < Rows; ++i)`
`                 for(int j = 0; j < Cols; ++j)`
`-                    result(i, j) = m(i, j) / s;`
`-`
`-            return result;`
`+                    m(i, j) *= s;`
`+            `
`+            return m;`
`         }`
` `
`         template<class T, int Rows, int Cols>`
`-        Matrix<T, Rows, Cols> negate(const Matrix<T, Rows, Cols> &m)`
`+        Matrix<T, Rows, Cols>& idiv_s(Matrix<T, Rows, Cols> &m, T s)`
`         {`
`-            return m * -1;`
`+            for(int i = 0; i < Rows; ++i)`
`+                for(int j = 0; j < Cols; ++j)`
`+                    m(i, j) /= s;`
`+`
`+            return m;`
`         }`
` `
`         template<class T, int Rows, int Cols>`
`-        Matrix<T, Rows, Cols> subtract(const Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)`
`+        Matrix<T, Rows, Cols>& imul(Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)`
`         {`
`-            return l + negate(r);`
`+            using namespace std;`
`+`
`+            Matrix<T, Rows, Cols> result = {};`
`+`
`+            for(int i = 0; i < Rows; i++) `
`+               for(int j = 0; j < Cols; j++)`
`+                   for(int k = 0; k < Cols; k++) `
`+                       result(i, j) += l(i, k) * r(k, j);`
`+            `
`+            swap(result, l);`
`+            return l;`
`+        }`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    Matrix<T, Cols, Rows> transpose(const Matrix<T, Rows, Cols> &m)`
`+    {`
`+        Matrix<T, Cols, Rows> result;`
`+`
`+        for(int i = 0; i < Rows; ++i)`
`+            for(int j = 0; j < Cols; ++j)`
`+                result(j, i) = m(i, j);`
`+`
`+        return result;`
`+    }`
`+`
`+    template<class T, int Rows>`
`+    T inner_product(const Matrix<T, Rows, 1> &l, const Matrix<T, Rows, 1> &r)`
`+    {`
`+        T result = 0;`
`+`
`+        for(int i = 0; i < Rows; ++i)`
`+            result += l(i) * r(i);`
`+`
`+        return result;`
`+    }`
`+`
`+    template<class T, int Cols>`
`+    T inner_product(const Matrix<T, 1, Cols> &l, const Matrix<T, 1, Cols> &r)`
`+    {`
`+        T result = 0;`
`+`
`+        for(int j = 0; j < Cols; ++j)`
`+            result += l(j) * r(j);`
`+`
`+        return result;`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    T magnitude(const Matrix<T, Rows, Cols> &m)`
`+    {`
`+        return std::sqrt(inner_product(m, m));`
`+    }`
`+`
`+    template<int Rows, int Cols>`
`+    int magnitude(const Matrix<int, Rows, Cols> &m)`
`+    {`
`+        return (int)std::sqrt((double)inner_product(m, m));`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    Matrix<T, Rows, Cols> normalize(const Matrix<T, Rows, Cols> &m)`
`+    {`
`+        return m / magnitude(m);`
`+    }`
`+`
`+    template<class T>`
`+    Matrix<T, 3, 1> cross_product(const Matrix<T, 3, 1> &l, const Matrix<T, 3, 1> &r)`
`+    {`
`+        Matrix<T, 3, 1> result = {`
`+            l(1) * r(2) - l(2) * r(1),`
`+            l(2) * r(0) - l(0) * r(2),`
`+            l(0) * r(1) - l(1) * r(0)`
`+        };`
`+        return result;`
`+    }`
`+`
`+    template<class T>`
`+    Matrix<T, 1, 3> cross_product(const Matrix<T, 1, 3> &l, const Matrix<T, 1, 3> &r)`
`+    {`
`+        Matrix<T, 1, 3> result = {`
`+            l(1) * r(2) - l(2) * r(1),`
`+            l(2) * r(0) - l(0) * r(2),`
`+            l(0) * r(1) - l(1) * r(0)`
`+        };`
`+        return result;`
`+    }`
`+`
`+    template<class T>`
`+    T determinant(const Matrix<T, 2, 2> &m)`
`+    {`
`+        return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0);`
`+    }`
`+    `
`+    template<class T, int N>`
`+    Matrix<T, N - 1, N - 1> minor_matrix(const Matrix<T, N, N> &m, int i, int j)`
`+    {`
`+        Matrix<T, N - 1, N - 1> result;`
`+`
`+        for(int a = 0, b = 0; a < N; ++a)`
`+        {`
`+            if(a != i)`
`+            {`
`+                for(int c = 0, d = 0; c < N; ++c)`
`+                {`
`+                    if(c != j)`
`+                    {`
`+                        result(b, d) = m(a, c);`
`+                        ++d;`
`+                    }`
`+                }`
`+                ++b;`
`+            }`
`         }`
` `
`-        template<class T, int RowsL, int ColsL, int ColsR>`
`-        Matrix<T, RowsL, ColsR> multiply(const Matrix<T, RowsL, ColsL> &l, const Matrix<T, ColsL, ColsR> &r)`
`-        {`
`-            Matrix<T, RowsL, ColsR> result = {};`
`+        return result;`
`+    }`
` `
`-            for(int i = 0; i < RowsL; i++) `
`-               for(int j = 0; j < ColsR; j++)`
`-                   for(int k = 0; k < ColsL; k++) `
`-                       result(i, j) +=  l(i, k) * r(k, j);`
`+    template<class T, int N>`
`+    T cofactor(const Matrix<T, N, N> &m, int row, int col)`
`+    {`
`+        return determinant(minor_matrix(m, row, col)) * (T)std::pow((T)-1, row + col);`
`+    }`
` `
`-            return result;`
`-        }`
`+    template<int N>`
`+    int cofactor(const Matrix<int, N, N> &m, int row, int col)`
`+    {`
`+        return determinant(minor_matrix(m, row, col)) * (int)std::pow(-1.0, row + col);`
`+    }`
` `
`-        template<class T, int Rows, int Cols>`
`-        Matrix<T, Cols, Rows> transpose(const Matrix<T, Rows, Cols> &m)`
`-        {`
`-            Matrix<T, Cols, Rows> result;`
`+    template<class T, int N>`
`+    Matrix<T, N, N> cofactor_matrix(const Matrix<T, N, N> &m)`
`+    {`
`+        Matrix<T, N, N> result;`
` `
`-            for(int i = 0; i < Rows; ++i)`
`-                for(int j = 0; j < Cols; ++j)`
`-                    result(j, i) = m(i, j);`
`+        for(int i = 0; i < N; ++i)`
`+            for(int j = 0; j < N; ++j)`
`+                result(i, j) = cofactor(m, i, j);`
` `
`-            return result;`
`-        }`
`+        return result;`
`+    }`
` `
`-        template<class T, int Rows, int Cols>`
`-        bool equals(const Matrix<T, Rows, Cols> &l, const Matrix<T, Rows, Cols> &r)`
`-        {`
`-            for(int i = 0; i < Rows; ++i)`
`+    template<class T, int N>`
`+    Matrix<T, N, N> adjoint(const Matrix<T, N, N> &m)`
`+    {`
`+        return transpose(cofactor_matrix(m));`
`+    }`
`+`
`+    template<class T, int N>`
`+    T determinant(const Matrix<T, N, N> &m)`
`+    {`
`+        T result = 0;`
`+`
`+        // Laplace expansion of first row`
`+        for(int i = 0; i < N; ++i)`
`+            result += m(i, 0) * cofactor(m, i, 0);`
`+`
`+        return result;`
`+    }`
`+`
`+    template<class T>`
`+    Matrix<T, 2, 2> inverse(const Matrix<T, 2, 2> &m)`
`+    {`
`+        Matrix<T, 2, 2> result = {m(1, 1), -m(0, 1), -m(1, 0), m(0, 0)};`
`+        return result / determinant(m);`
`+    }`
`+`
`+    template<class T, int N>`
`+    Matrix<T, N, N> inverse(const Matrix<T, N, N> &m)`
`+    {`
`+        return adjoint(m) / determinant(m);`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    Matrix<T, Rows, Cols> operator+(Matrix<T, Rows, Cols> m)`
`+    {`
`+        return m;`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    Matrix<T, Rows, Cols> operator-(Matrix<T, Rows, Cols> m)`
`+    {`
`+        return m *= -1;`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    Matrix<T, Rows, Cols> operator~(const Matrix<T, Rows, Cols> &m)`
`+    {`
`+        return inverse(m);`
`+    }`
`+`
`+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`+    Matrix<T, RowsL, ColsL> operator+(Matrix<T, RowsL, ColsL> l, const Matrix<U, RowsR, ColsR> &r)`
`+    {`
`+        return l += r;`
`+    }`
`+`
`+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`+    Matrix<T, RowsL, ColsL> operator-(Matrix<T, RowsL, ColsL> l, const Matrix<U, RowsR, ColsR> &r)`
`+    {`
`+        return l -= r;`
`+    }`
`+`
`+    template<class T, class U, int Rows, int Cols>`
`+    Matrix<T, Rows, Cols> operator*(Matrix<T, Rows, Cols> l, const Matrix<U, Rows, Cols> &r)`
`+    {`
`+        return l *= r;`
`+    }`
`+`
`+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`+    Matrix<T, RowsL, ColsR> operator*(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)`
`+    {`
`+        Matrix<T, RowsL, ColsR> result = {};`
`+`
`+        for(int i = 0; i < RowsL; i++) `
`+           for(int j = 0; j < ColsR; j++)`
`+               for(int k = 0; k < ColsL; k++) `
`+                   result(i, j) += l(i, k) * r(k, j);`
`+`
`+        return result;`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    Matrix<T, Rows, Cols> operator*(Matrix<T, Rows, Cols> m, T s)`
`+    {`
`+        return m *= s;`
`+    }`
`+`
`+    template<class T, int Rows, int Cols>`
`+    Matrix<T, Rows, Cols> operator/(Matrix<T, Rows, Cols> m, T s)`
`+    {`
`+        return m /= s;`
`+    }`
`+`
`+    template<class T, class U, int Rows>`
`+    T operator*(const Matrix<T, Rows, 1> &l, const Matrix<U, Rows, 1> &r)`
`+    {`
`+        return inner_product(l, r);`
`+    }`
`+`
`+    template<class T, class U, int Cols>`
`+    T operator*(const Matrix<T, 1, Cols> &l, const Matrix<U, 1, Cols> &r)`
`+    {`
`+        return inner_product(l, r);`
`+    }`
`+`
`+    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`+    Matrix<T, RowsL, ColsL> operator^(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)`
`+    {`
`+        return cross_product(l, r);`
`+    }`
`+`
`+    template<class T, class U, int Rows, int Cols>`
`+    bool operator==(const Matrix<T, Rows, Cols> &l, const Matrix<U, Rows, Cols> &r)`
`+    {`
`+        for(int i = 0; i < Rows; ++i)`
`                 for(int j = 0; j < Cols; ++j)`
`                     if(l(i, j) != r(i, j))`
`                         return false;`
` `
`             return true;`
`-        }`
`-`
`-        template<class T, int Rows>`
`-        T inner_product(const Matrix<T, Rows, 1> &l, const Matrix<T, Rows, 1> &r)`
`-        {`
`-            T result = 0;`
`-`
`-            for(int i = 0; i < Rows; ++i)`
`-                result += l(i) * r(i);`
`-`
`-            return result;`
`-        }`
`-`
`-        template<class T, int Cols>`
`-        T inner_product(const Matrix<T, 1, Cols> &l, const Matrix<T, 1, Cols> &r)`
`-        {`
`-            T result = 0;`
`-`
`-            for(int j = 0; j < Cols; ++j)`
`-                result += l(j) * r(j);`
`-`
`-            return result;`
`-        }`
`-`
`-        template<class T, int Rows, int Cols>`
`-        T magnitude(const Matrix<T, Rows, Cols> &m)`
`-        {`
`-            return std::sqrt(inner_product(m, m));`
`-        }`
`-`
`-        template<int Rows, int Cols>`
`-        int magnitude(const Matrix<int, Rows, Cols> &m)`
`-        {`
`-            return (int)std::sqrt((double)inner_product(m, m));`
`-        }`
`-`
`-        template<class T, int Rows, int Cols>`
`-        Matrix<T, Rows, Cols> normalize(const Matrix<T, Rows, Cols> &m)`
`-        {`
`-            return m / magnitude(m);`
`-        }`
`-`
`-        template<class T>`
`-        Matrix<T, 3, 1> cross_product(const Matrix<T, 3, 1> &l, const Matrix<T, 3, 1> &r)`
`-        {`
`-            Matrix<T, 3, 1> result = {`
`-                l(1) * r(2) - l(2) * r(1),`
`-                l(2) * r(0) - l(0) * r(2),`
`-                l(0) * r(1) - l(1) * r(0)`
`-            };`
`-            return result;`
`-        }`
`-`
`-        template<class T>`
`-        Matrix<T, 1, 3> cross_product(const Matrix<T, 1, 3> &l, const Matrix<T, 1, 3> &r)`
`-        {`
`-            Matrix<T, 1, 3> result = {`
`-                l(1) * r(2) - l(2) * r(1),`
`-                l(2) * r(0) - l(0) * r(2),`
`-                l(0) * r(1) - l(1) * r(0)`
`-            };`
`-            return result;`
`-        }`
`-`
`-        template<class T>`
`-        T determinant(const Matrix<T, 2, 2> &m)`
`-        {`
`-            return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0);`
`-        }`
`-        `
`-        template<class T, int N>`
`-        Matrix<T, N - 1, N - 1> minor_matrix(const Matrix<T, N, N> &m, int i, int j)`
`-        {`
`-            Matrix<T, N - 1, N - 1> result;`
`-`
`-            for(int a = 0, b = 0; a < N; ++a)`
`-            {`
`-                if(a != i)`
`-                {`
`-                    for(int c = 0, d = 0; c < N; ++c)`
`-                    {`
`-                        if(c != j)`
`-                        {`
`-                            result(b, d) = m(a, c);`
`-                            ++d;`
`-                        }`
`-                    }`
`-                    ++b;`
`-                }`
`-            }`
`-`
`-            return result;`
`-        }`
`-`
`-        template<class T, int N>`
`-        T cofactor(const Matrix<T, N, N> &m, int row, int col)`
`-        {`
`-            return determinant(minor_matrix(m, row, col)) * (T)std::pow((T)-1, row + col);`
`-        }`
`-`
`-        template<int N>`
`-        int cofactor(const Matrix<int, N, N> &m, int row, int col)`
`-        {`
`-            return determinant(minor_matrix(m, row, col)) * (int)std::pow(-1.0, row + col);`
`-        }`
`-`
`-        template<class T, int N>`
`-        Matrix<T, N, N> cofactor_matrix(const Matrix<T, N, N> &m)`
`-        {`
`-            Matrix<T, N, N> result;`
`-`
`-            for(int i = 0; i < N; ++i)`
`-                for(int j = 0; j < N; ++j)`
`-                    result(i, j) = cofactor(m, i, j);`
`-`
`-            return result;`
`-        }`
`-`
`-        template<class T, int N>`
`-        Matrix<T, N, N> adjoint(const Matrix<T, N, N> &m)`
`-        {`
`-            return transpose(cofactor_matrix(m));`
`-        }`
`-`
`-        template<class T, int N>`
`-        T determinant(const Matrix<T, N, N> &m)`
`-        {`
`-            T result = 0;`
`-`
`-            // Laplace expansion of first row`
`-            for(int i = 0; i < N; ++i)`
`-                result += m(i, 0) * cofactor(m, i, 0);`
`-`
`-            return result;`
`-        }`
`-`
`-        template<class T>`
`-        Matrix<T, 2, 2> inverse(const Matrix<T, 2, 2> &m)`
`-        {`
`-            Matrix<T, 2, 2> result = {m(1, 1), -m(0, 1), -m(1, 0), m(0, 0)};`
`-            return result / determinant(m);`
`-        }`
`-`
`-        template<class T, int N>`
`-        Matrix<T, N, N> inverse(const Matrix<T, N, N> &m)`
`-        {`
`-            return adjoint(m) / determinant(m);`
`-        }`
`     }`
`-`
`-    template<class T, int Rows, int Cols>`
`-    Matrix<T, Rows, Cols> operator+(const Matrix<T, Rows, Cols> &m)`
`-    {`
`-        return m;`
`-    }`
`-`
`-    template<class T, int Rows, int Cols>`
`-    Matrix<T, Rows, Cols> operator-(const Matrix<T, Rows, Cols> &m)`
`-    {`
`-        return Matrix_detail::negate(m);`
`-    }`
`-`
`-    template<class T, int Rows, int Cols>`
`-    Matrix<T, Rows, Cols> operator~(const Matrix<T, Rows, Cols> &m)`
`-    {`
`-        return Matrix_detail::inverse(m);`
`-    }`
`-`
`-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`-    Matrix<T, RowsL, ColsL> operator+(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)`
`-    {`
`-        return Matrix_detail::add(l, r);`
`-    }`
`-`
`-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`-    Matrix<T, RowsL, ColsL> operator-(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)`
`-    {`
`-        return Matrix_detail::subtract(l, r);`
`-    }`
`-`
`-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`-    Matrix<T, RowsL, ColsR> operator*(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)`
`-    {`
`-        return Matrix_detail::multiply(l, r);`
`-    }`
`-`
`-    template<class T, int Rows, int Cols>`
`-    Matrix<T, Rows, Cols> operator*(const Matrix<T, Rows, Cols> &m, T s)`
`-    {`
`-        return Matrix_detail::scalar_multiply(m, s);`
`-    }`
`-`
`-    template<class T, int Rows, int Cols>`
`-    Matrix<T, Rows, Cols> operator/(const Matrix<T, Rows, Cols> &m, T s)`
`-    {`
`-        return Matrix_detail::scalar_divide(m, s);`
`-    }`
`-`
`-    template<class T, class U, int RowsL, int RowsR>`
`-    T operator*(const Matrix<T, RowsL, 1> &l, const Matrix<U, RowsR, 1> &r)`
`-    {`
`-        return Matrix_detail::inner_product(l, r);`
`-    }`
`-`
`-    template<class T, class U, int ColsL, int ColsR>`
`-    T operator*(const Matrix<T, 1, ColsL> &l, const Matrix<U, 1, ColsR> &r)`
`-    {`
`-        return Matrix_detail::inner_product(l, r);`
`-    }`
`-`
`-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`-    Matrix<T, RowsL, ColsL> operator^(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)`
`-    {`
`-        return Matrix_detail::cross_product(l, r);`
`-    }`
`-`
`-    template<class T, class U, int RowsL, int ColsL, int RowsR, int ColsR>`
`-    bool operator==(const Matrix<T, RowsL, ColsL> &l, const Matrix<U, RowsR, ColsR> &r)`
`-    {`
`-        return Matrix_detail::equals(l, r);`
`-    }`
`-`
`-    using Matrix_detail::magnitude;`
`-    using Matrix_detail::determinant;`
`-    using Matrix_detail::transpose;`
`-    using Matrix_detail::normalize;`
` }`

Matrix/Matrix/Matrix.vcproj

` 			<File`
` 				RelativePath=".\Matrix.cpp"`
` 				>`
`+				<FileConfiguration`
`+					Name="Debug|Win32"`
`+					>`
`+					<Tool`
`+						Name="VCCLCompilerTool"`
`+						GeneratePreprocessedFile="0"`
`+					/>`
`+				</FileConfiguration>`
` 			</File>`
` 		</Filter>`
` 		<Filter`

Matrix/MatrixTests/MatrixTests.cpp

` `
` BOOST_AUTO_TEST_CASE( test_add )`
` {`
`-    Matrix<int, 3, 3> zero = zero_matrix<int, 3, 3>();`
`+    const Matrix<int, 3, 3> zero = zero_matrix<int, 3, 3>();`
` `
`     Matrix<int, 3, 3> a = {0, 1, 2, `
`                            3, 4, 5, `
`     BOOST_CHECK_EQUAL(b + a, expected);`
` }`
` `
`+BOOST_AUTO_TEST_CASE( test_iadd )`
`+{`
`+    const Matrix<int, 3, 3> zero = zero_matrix<int, 3, 3>();`
`+`
`+    Matrix<int, 3, 3> a = {0, 1, 2, `
`+                           3, 4, 5, `
`+                           6, 7, 8};`
`+`
`+    const Matrix<int, 3, 3> a0 = a;`
`+`
`+    a += zero;`
`+    BOOST_CHECK_EQUAL(a, a0);`
`+    `
`+    Matrix<int, 3, 3> b = {9, 8, 7, `
`+                           6, 5, 4, `
`+                           3, 2, 1};`
`+    const Matrix<int, 3, 3> b0 = b;`
`+    `
`+    Matrix<int, 3, 3> expected = {9, 9, 9, `
`+                                  9, 9, 9, `
`+                                  9, 9, 9};`
`+`
`+    b += a;`
`+    BOOST_CHECK_EQUAL(b, expected);`
`+    `
`+    b = b0;`
`+    a += b;`
`+    BOOST_CHECK_EQUAL(a, expected);`
`+}`
`+`
` BOOST_AUTO_TEST_CASE( test_multiply )`
` {`
`-    Matrix<int, 3, 3> I = identity_matrix<int, 3>();`
`+    const Matrix<int, 3, 3> I = identity_matrix<int, 3>();`
`     `
`     Matrix<int, 3, 3> a = {0, 1, 2, `
`                            3, 4, 5, `
`                                   -6,  3, -0,`
`                                    2, -1,  3};`
` `
`-    BOOST_CHECK_EQUAL(Matrix_detail::cofactor_matrix(m), expected);`
`+    BOOST_CHECK_EQUAL(cofactor_matrix(m), expected);`
` }`
` `
` BOOST_AUTO_TEST_CASE( test_adjoint )`
`                                    4,  3, -1,`
`                                   -3, -0,  3};`
` `
`-    BOOST_CHECK_EQUAL(Matrix_detail::adjoint(m), expected);`
`+    BOOST_CHECK_EQUAL(adjoint(m), expected);`
` }`
` `
` BOOST_AUTO_TEST_CASE( test_inverse )`