Browse Source

Math: C++14 constexpr in RectangularMatrix.

pull/276/head
Vladimír Vondruš 12 years ago
parent
commit
7eb62cd30f
  1. 86
      src/Magnum/Math/RectangularMatrix.h
  2. 217
      src/Magnum/Math/Test/RectangularMatrixTest.cpp

86
src/Magnum/Math/RectangularMatrix.h

@ -139,7 +139,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
constexpr RectangularMatrix(const RectangularMatrix<cols, rows, T>&) = default; constexpr RectangularMatrix(const RectangularMatrix<cols, rows, T>&) = default;
/** @brief Assignment operator */ /** @brief Assignment operator */
RectangularMatrix<cols, rows, T>& operator=(const RectangularMatrix<cols, rows, T>&) = default; constexpr RectangularMatrix<cols, rows, T>& operator=(const RectangularMatrix<cols, rows, T>&) = default;
/** @brief Convert matrix to external representation */ /** @brief Convert matrix to external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<cols, rows, T, U>::to(std::declval<RectangularMatrix<cols, rows, T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::RectangularMatrixConverter<cols, rows, T, U>::to(std::declval<RectangularMatrix<cols, rows, T>>()))> constexpr explicit operator U() const {
@ -153,7 +153,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see @ref operator[]() * @see @ref operator[]()
*/ */
T* data() { return _data[0].data(); } constexpr T* data() { return _data[0].data(); }
constexpr const T* data() const { return _data[0].data(); } /**< @overload */ constexpr const T* data() const { return _data[0].data(); } /**< @overload */
/** /**
@ -168,7 +168,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see @ref row(), @ref data() * @see @ref row(), @ref data()
*/ */
Vector<rows, T>& operator[](std::size_t col) { return _data[col]; } constexpr Vector<rows, T>& operator[](std::size_t col) { return _data[col]; }
constexpr const Vector<rows, T>& operator[](std::size_t col) const { return _data[col]; } /**< @overload */ constexpr const Vector<rows, T>& operator[](std::size_t col) const { return _data[col]; } /**< @overload */
/** /**
@ -179,7 +179,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* stored. * stored.
* @see @ref operator[]() * @see @ref operator[]()
*/ */
Vector<cols, T> row(std::size_t row) const; constexpr Vector<cols, T> row(std::size_t row) const;
/** @brief Equality comparison */ /** @brief Equality comparison */
bool operator==(const RectangularMatrix<cols, rows, T>& other) const { bool operator==(const RectangularMatrix<cols, rows, T>& other) const {
@ -206,7 +206,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* \boldsymbol B_j = -\boldsymbol A_j * \boldsymbol B_j = -\boldsymbol A_j
* @f] * @f]
*/ */
RectangularMatrix<cols, rows, T> operator-() const; constexpr RectangularMatrix<cols, rows, T> operator-() const;
/** /**
* @brief Add and assign matrix * @brief Add and assign matrix
@ -215,7 +215,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* \boldsymbol A_j = \boldsymbol A_j + \boldsymbol B_j * \boldsymbol A_j = \boldsymbol A_j + \boldsymbol B_j
* @f] * @f]
*/ */
RectangularMatrix<cols, rows, T>& operator+=(const RectangularMatrix<cols, rows, T>& other) { constexpr RectangularMatrix<cols, rows, T>& operator+=(const RectangularMatrix<cols, rows, T>& other) {
for(std::size_t i = 0; i != cols; ++i) for(std::size_t i = 0; i != cols; ++i)
_data[i] += other._data[i]; _data[i] += other._data[i];
@ -227,7 +227,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see @ref operator+=() * @see @ref operator+=()
*/ */
RectangularMatrix<cols, rows, T> operator+(const RectangularMatrix<cols, rows, T>& other) const { constexpr RectangularMatrix<cols, rows, T> operator+(const RectangularMatrix<cols, rows, T>& other) const {
return RectangularMatrix<cols, rows, T>(*this)+=other; return RectangularMatrix<cols, rows, T>(*this)+=other;
} }
@ -238,7 +238,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* \boldsymbol A_j = \boldsymbol A_j - \boldsymbol B_j * \boldsymbol A_j = \boldsymbol A_j - \boldsymbol B_j
* @f] * @f]
*/ */
RectangularMatrix<cols, rows, T>& operator-=(const RectangularMatrix<cols, rows, T>& other) { constexpr RectangularMatrix<cols, rows, T>& operator-=(const RectangularMatrix<cols, rows, T>& other) {
for(std::size_t i = 0; i != cols; ++i) for(std::size_t i = 0; i != cols; ++i)
_data[i] -= other._data[i]; _data[i] -= other._data[i];
@ -250,7 +250,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see @ref operator-=() * @see @ref operator-=()
*/ */
RectangularMatrix<cols, rows, T> operator-(const RectangularMatrix<cols, rows, T>& other) const { constexpr RectangularMatrix<cols, rows, T> operator-(const RectangularMatrix<cols, rows, T>& other) const {
return RectangularMatrix<cols, rows, T>(*this)-=other; return RectangularMatrix<cols, rows, T>(*this)-=other;
} }
@ -261,7 +261,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* \boldsymbol A_j = a \boldsymbol A_j * \boldsymbol A_j = a \boldsymbol A_j
* @f] * @f]
*/ */
RectangularMatrix<cols, rows, T>& operator*=(T number) { constexpr RectangularMatrix<cols, rows, T>& operator*=(T number) {
for(std::size_t i = 0; i != cols; ++i) for(std::size_t i = 0; i != cols; ++i)
_data[i] *= number; _data[i] *= number;
@ -273,7 +273,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see @ref operator*=(T), @ref operator*(T, const RectangularMatrix<cols, rows, T>&) * @see @ref operator*=(T), @ref operator*(T, const RectangularMatrix<cols, rows, T>&)
*/ */
RectangularMatrix<cols, rows, T> operator*(T number) const { constexpr RectangularMatrix<cols, rows, T> operator*(T number) const {
return RectangularMatrix<cols, rows, T>(*this) *= number; return RectangularMatrix<cols, rows, T>(*this) *= number;
} }
@ -284,7 +284,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* \boldsymbol A_j = \frac{\boldsymbol A_j} a * \boldsymbol A_j = \frac{\boldsymbol A_j} a
* @f] * @f]
*/ */
RectangularMatrix<cols, rows, T>& operator/=(T number) { constexpr RectangularMatrix<cols, rows, T>& operator/=(T number) {
for(std::size_t i = 0; i != cols; ++i) for(std::size_t i = 0; i != cols; ++i)
_data[i] /= number; _data[i] /= number;
@ -297,7 +297,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* @see @ref operator/=(T), * @see @ref operator/=(T),
* @ref operator/(T, const RectangularMatrix<cols, rows, T>&) * @ref operator/(T, const RectangularMatrix<cols, rows, T>&)
*/ */
RectangularMatrix<cols, rows, T> operator/(T number) const { constexpr RectangularMatrix<cols, rows, T> operator/(T number) const {
return RectangularMatrix<cols, rows, T>(*this) /= number; return RectangularMatrix<cols, rows, T>(*this) /= number;
} }
@ -308,7 +308,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* (\boldsymbol {AB})_{ji} = \sum_{k=0}^{m-1} \boldsymbol A_{ki} \boldsymbol B_{jk} * (\boldsymbol {AB})_{ji} = \sum_{k=0}^{m-1} \boldsymbol A_{ki} \boldsymbol B_{jk}
* @f] * @f]
*/ */
template<std::size_t size> RectangularMatrix<size, rows, T> operator*(const RectangularMatrix<size, cols, T>& other) const; template<std::size_t size> constexpr RectangularMatrix<size, rows, T> operator*(const RectangularMatrix<size, cols, T>& other) const;
/** /**
* @brief Multiply vector * @brief Multiply vector
@ -318,7 +318,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* (\boldsymbol {Aa})_i = \sum_{k=0}^{m-1} \boldsymbol A_{ki} \boldsymbol a_k * (\boldsymbol {Aa})_i = \sum_{k=0}^{m-1} \boldsymbol A_{ki} \boldsymbol a_k
* @f] * @f]
*/ */
Vector<rows, T> operator*(const Vector<cols, T>& other) const { constexpr Vector<rows, T> operator*(const Vector<cols, T>& other) const {
return operator*(RectangularMatrix<1, cols, T>(other))[0]; return operator*(RectangularMatrix<1, cols, T>(other))[0];
} }
@ -327,7 +327,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see @ref row() * @see @ref row()
*/ */
RectangularMatrix<rows, cols, T> transposed() const; constexpr RectangularMatrix<rows, cols, T> transposed() const;
/** /**
* @brief Values on diagonal * @brief Values on diagonal
@ -425,7 +425,7 @@ template<class T> using Matrix4x3 = RectangularMatrix<4, 3, T>;
Same as @ref RectangularMatrix::operator*(T) const. Same as @ref RectangularMatrix::operator*(T) const.
*/ */
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator*( template<std::size_t cols, std::size_t rows, class T> inline constexpr RectangularMatrix<cols, rows, T> operator*(
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
T T
#else #else
@ -444,7 +444,7 @@ The computation is done column-wise. @f[
@f] @f]
@see @ref RectangularMatrix::operator/(T) const @see @ref RectangularMatrix::operator/(T) const
*/ */
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator/( template<std::size_t cols, std::size_t rows, class T> inline constexpr RectangularMatrix<cols, rows, T> operator/(
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
T T
#else #else
@ -452,7 +452,7 @@ template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<c
#endif #endif
number, const RectangularMatrix<cols, rows, T>& matrix) number, const RectangularMatrix<cols, rows, T>& matrix)
{ {
RectangularMatrix<cols, rows, T> out; RectangularMatrix<cols, rows, T> out{};
for(std::size_t i = 0; i != cols; ++i) for(std::size_t i = 0; i != cols; ++i)
out[i] = number/matrix[i]; out[i] = number/matrix[i];
@ -468,7 +468,7 @@ Internally the same as multiplying one-column matrix with one-row matrix. @f[
@f] @f]
@see @ref RectangularMatrix::operator*(const RectangularMatrix<size, cols, T>&) const @see @ref RectangularMatrix::operator*(const RectangularMatrix<size, cols, T>&) const
*/ */
template<std::size_t size, std::size_t cols, class T> inline RectangularMatrix<cols, size, T> operator*(const Vector<size, T>& vector, const RectangularMatrix<cols, 1, T>& matrix) { template<std::size_t size, std::size_t cols, class T> inline constexpr RectangularMatrix<cols, size, T> operator*(const Vector<size, T>& vector, const RectangularMatrix<cols, 1, T>& matrix) {
return RectangularMatrix<1, size, T>(vector)*matrix; return RectangularMatrix<1, size, T>(vector)*matrix;
} }
@ -527,57 +527,57 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit
return Math::RectangularMatrix<cols, rows, T>::fromDiagonal(diagonal); \ return Math::RectangularMatrix<cols, rows, T>::fromDiagonal(diagonal); \
} \ } \
\ \
__VA_ARGS__ operator-() const { \ constexpr __VA_ARGS__ operator-() const { \
return Math::RectangularMatrix<cols, rows, T>::operator-(); \ return Math::RectangularMatrix<cols, rows, T>::operator-(); \
} \ } \
__VA_ARGS__& operator+=(const Math::RectangularMatrix<cols, rows, T>& other) { \ constexpr __VA_ARGS__& operator+=(const Math::RectangularMatrix<cols, rows, T>& other) { \
Math::RectangularMatrix<cols, rows, T>::operator+=(other); \ Math::RectangularMatrix<cols, rows, T>::operator+=(other); \
return *this; \ return *this; \
} \ } \
__VA_ARGS__ operator+(const Math::RectangularMatrix<cols, rows, T>& other) const { \ constexpr __VA_ARGS__ operator+(const Math::RectangularMatrix<cols, rows, T>& other) const { \
return Math::RectangularMatrix<cols, rows, T>::operator+(other); \ return Math::RectangularMatrix<cols, rows, T>::operator+(other); \
} \ } \
__VA_ARGS__& operator-=(const Math::RectangularMatrix<cols, rows, T>& other) { \ constexpr __VA_ARGS__& operator-=(const Math::RectangularMatrix<cols, rows, T>& other) { \
Math::RectangularMatrix<cols, rows, T>::operator-=(other); \ Math::RectangularMatrix<cols, rows, T>::operator-=(other); \
return *this; \ return *this; \
} \ } \
__VA_ARGS__ operator-(const Math::RectangularMatrix<cols, rows, T>& other) const { \ constexpr __VA_ARGS__ operator-(const Math::RectangularMatrix<cols, rows, T>& other) const { \
return Math::RectangularMatrix<cols, rows, T>::operator-(other); \ return Math::RectangularMatrix<cols, rows, T>::operator-(other); \
} \ } \
__VA_ARGS__& operator*=(T number) { \ constexpr __VA_ARGS__& operator*=(T number) { \
Math::RectangularMatrix<cols, rows, T>::operator*=(number); \ Math::RectangularMatrix<cols, rows, T>::operator*=(number); \
return *this; \ return *this; \
} \ } \
__VA_ARGS__ operator*(T number) const { \ constexpr __VA_ARGS__ operator*(T number) const { \
return Math::RectangularMatrix<cols, rows, T>::operator*(number); \ return Math::RectangularMatrix<cols, rows, T>::operator*(number); \
} \ } \
__VA_ARGS__& operator/=(T number) { \ constexpr __VA_ARGS__& operator/=(T number) { \
Math::RectangularMatrix<cols, rows, T>::operator/=(number); \ Math::RectangularMatrix<cols, rows, T>::operator/=(number); \
return *this; \ return *this; \
} \ } \
__VA_ARGS__ operator/(T number) const { \ constexpr __VA_ARGS__ operator/(T number) const { \
return Math::RectangularMatrix<cols, rows, T>::operator/(number); \ return Math::RectangularMatrix<cols, rows, T>::operator/(number); \
} }
#define MAGNUM_MATRIX_OPERATOR_IMPLEMENTATION(...) \ #define MAGNUM_MATRIX_OPERATOR_IMPLEMENTATION(...) \
template<std::size_t size, class T> inline __VA_ARGS__ operator*(typename std::common_type<T>::type number, const __VA_ARGS__& matrix) { \ template<std::size_t size, class T> inline constexpr __VA_ARGS__ operator*(typename std::common_type<T>::type number, const __VA_ARGS__& matrix) { \
return number*static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \ return number*static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \
} \ } \
template<std::size_t size, class T> inline __VA_ARGS__ operator/(typename std::common_type<T>::type number, const __VA_ARGS__& matrix) { \ template<std::size_t size, class T> inline constexpr __VA_ARGS__ operator/(typename std::common_type<T>::type number, const __VA_ARGS__& matrix) { \
return number/static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \ return number/static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \
} \ } \
template<std::size_t size, class T> inline __VA_ARGS__ operator*(const Vector<size, T>& vector, const RectangularMatrix<size, 1, T>& matrix) { \ template<std::size_t size, class T> inline constexpr __VA_ARGS__ operator*(const Vector<size, T>& vector, const RectangularMatrix<size, 1, T>& matrix) { \
return Math::RectangularMatrix<1, size, T>(vector)*matrix; \ return Math::RectangularMatrix<1, size, T>(vector)*matrix; \
} }
#define MAGNUM_MATRIXn_OPERATOR_IMPLEMENTATION(size, Type) \ #define MAGNUM_MATRIXn_OPERATOR_IMPLEMENTATION(size, Type) \
template<class T> inline Type<T> operator*(typename std::common_type<T>::type number, const Type<T>& matrix) { \ template<class T> inline constexpr Type<T> operator*(typename std::common_type<T>::type number, const Type<T>& matrix) { \
return number*static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \ return number*static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \
} \ } \
template<class T> inline Type<T> operator/(typename std::common_type<T>::type number, const Type<T>& matrix) { \ template<class T> inline constexpr Type<T> operator/(typename std::common_type<T>::type number, const Type<T>& matrix) { \
return number/static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \ return number/static_cast<const Math::RectangularMatrix<size, size, T>&>(matrix); \
} \ } \
template<class T> inline Type<T> operator*(const Vector<size, T>& vector, const RectangularMatrix<size, 1, T>& matrix) { \ template<class T> inline constexpr Type<T> operator*(const Vector<size, T>& vector, const RectangularMatrix<size, 1, T>& matrix) { \
return Math::RectangularMatrix<1, size, T>(vector)*matrix; \ return Math::RectangularMatrix<1, size, T>(vector)*matrix; \
} }
#endif #endif
@ -593,8 +593,8 @@ namespace Implementation {
template<std::size_t cols, std::size_t rows, class T> template<std::size_t ...sequence> inline constexpr RectangularMatrix<cols, rows, T>::RectangularMatrix(Implementation::Sequence<sequence...>, const Vector<DiagonalSize, T>& diagonal): _data{Implementation::diagonalMatrixColumn<rows, sequence>(sequence < DiagonalSize ? diagonal[sequence] : T{})...} {} template<std::size_t cols, std::size_t rows, class T> template<std::size_t ...sequence> inline constexpr RectangularMatrix<cols, rows, T>::RectangularMatrix(Implementation::Sequence<sequence...>, const Vector<DiagonalSize, T>& diagonal): _data{Implementation::diagonalMatrixColumn<rows, sequence>(sequence < DiagonalSize ? diagonal[sequence] : T{})...} {}
template<std::size_t cols, std::size_t rows, class T> inline Vector<cols, T> RectangularMatrix<cols, rows, T>::row(std::size_t row) const { template<std::size_t cols, std::size_t rows, class T> inline constexpr Vector<cols, T> RectangularMatrix<cols, rows, T>::row(std::size_t row) const {
Vector<cols, T> out; Vector<cols, T> out{};
for(std::size_t i = 0; i != cols; ++i) for(std::size_t i = 0; i != cols; ++i)
out[i] = _data[i][row]; out[i] = _data[i][row];
@ -602,8 +602,8 @@ template<std::size_t cols, std::size_t rows, class T> inline Vector<cols, T> Rec
return out; return out;
} }
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> RectangularMatrix<cols, rows, T>::operator-() const { template<std::size_t cols, std::size_t rows, class T> inline constexpr RectangularMatrix<cols, rows, T> RectangularMatrix<cols, rows, T>::operator-() const {
RectangularMatrix<cols, rows, T> out; RectangularMatrix<cols, rows, T> out{};
for(std::size_t i = 0; i != cols; ++i) for(std::size_t i = 0; i != cols; ++i)
out._data[i] = -_data[i]; out._data[i] = -_data[i];
@ -611,8 +611,8 @@ template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<c
return out; return out;
} }
template<std::size_t cols, std::size_t rows, class T> template<std::size_t size> inline RectangularMatrix<size, rows, T> RectangularMatrix<cols, rows, T>::operator*(const RectangularMatrix<size, cols, T>& other) const { template<std::size_t cols, std::size_t rows, class T> template<std::size_t size> inline constexpr RectangularMatrix<size, rows, T> RectangularMatrix<cols, rows, T>::operator*(const RectangularMatrix<size, cols, T>& other) const {
RectangularMatrix<size, rows, T> out; RectangularMatrix<size, rows, T> out{};
for(std::size_t col = 0; col != size; ++col) for(std::size_t col = 0; col != size; ++col)
for(std::size_t row = 0; row != rows; ++row) for(std::size_t row = 0; row != rows; ++row)
@ -622,8 +622,8 @@ template<std::size_t cols, std::size_t rows, class T> template<std::size_t size>
return out; return out;
} }
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<rows, cols, T> RectangularMatrix<cols, rows, T>::transposed() const { template<std::size_t cols, std::size_t rows, class T> inline constexpr RectangularMatrix<rows, cols, T> RectangularMatrix<cols, rows, T>::transposed() const {
RectangularMatrix<rows, cols, T> out; RectangularMatrix<rows, cols, T> out{};
for(std::size_t col = 0; col != cols; ++col) for(std::size_t col = 0; col != cols; ++col)
for(std::size_t row = 0; row != rows; ++row) for(std::size_t row = 0; row != rows; ++row)

217
src/Magnum/Math/Test/RectangularMatrixTest.cpp

@ -241,23 +241,24 @@ void RectangularMatrixTest::data() {
Vector4(4.0f, 5.0f, 6.0f, 7.0f))); Vector4(4.0f, 5.0f, 6.0f, 7.0f)));
/* Pointer chasings, i.e. *(b.data()[1]), are not possible */ /* Pointer chasings, i.e. *(b.data()[1]), are not possible */
constexpr Matrix3x4 a(Vector4(3.0f, 5.0f, 8.0f, 4.0f), constexpr const Matrix3x4 a(Vector4(3.0f, 5.0f, 8.0f, 4.0f),
Vector4(4.5f, 4.0f, 7.0f, 3.0f), Vector4(4.5f, 4.0f, 7.0f, 3.0f),
Vector4(7.0f, -1.7f, 8.0f, 0.0f)); Vector4(7.0f, -1.7f, 8.0f, 0.0f));
constexpr Vector4 b = a[2]; constexpr auto b = a[2];
constexpr Float c = a[1][2]; constexpr auto c = a[1][2];
constexpr Float d = *a.data(); constexpr auto d = *a.data();
CORRADE_COMPARE(b, Vector4(7.0f, -1.7f, 8.0f, 0.0f)); CORRADE_COMPARE(b, Vector4(7.0f, -1.7f, 8.0f, 0.0f));
CORRADE_COMPARE(c, 7.0f); CORRADE_COMPARE(c, 7.0f);
CORRADE_COMPARE(d, 3.0f); CORRADE_COMPARE(d, 3.0f);
} }
void RectangularMatrixTest::row() { void RectangularMatrixTest::row() {
const Matrix3x4 a(Vector4(1.0f, 2.0f, 3.0f, 4.0f), constexpr Matrix3x4 a(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f), Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f)); Vector4(9.0f, 10.0f, 11.0f, 12.0f));
CORRADE_COMPARE(a.row(1), Vector3(2.0f, 6.0f, 10.0f)); constexpr auto b = a.row(1);
CORRADE_COMPARE(b, Vector3(2.0f, 6.0f, 10.0f));
} }
void RectangularMatrixTest::compare() { void RectangularMatrixTest::compare() {
@ -279,58 +280,67 @@ void RectangularMatrixTest::compare() {
} }
void RectangularMatrixTest::negative() { void RectangularMatrixTest::negative() {
Matrix2x2 matrix(Vector2(1.0f, -3.0f), constexpr Matrix2x2 matrix(Vector2(1.0f, -3.0f),
Vector2(5.0f, -10.0f)); Vector2(5.0f, -10.0f));
Matrix2x2 negated(Vector2(-1.0f, 3.0f), constexpr Matrix2x2 negated(Vector2(-1.0f, 3.0f),
Vector2(-5.0f, 10.0f)); Vector2(-5.0f, 10.0f));
CORRADE_COMPARE(-matrix, negated);
constexpr auto a = -matrix;
CORRADE_COMPARE(a, negated);
} }
void RectangularMatrixTest::addSubtract() { void RectangularMatrixTest::addSubtract() {
Matrix4x3 a(Vector3(0.0f, 1.0f, 3.0f), constexpr Matrix4x3 a(Vector3(0.0f, 1.0f, 3.0f),
Vector3(4.0f, 5.0f, 7.0f), Vector3(4.0f, 5.0f, 7.0f),
Vector3(8.0f, 9.0f, 11.0f), Vector3(8.0f, 9.0f, 11.0f),
Vector3(12.0f, 13.0f, 15.0f)); Vector3(12.0f, 13.0f, 15.0f));
Matrix4x3 b(Vector3(-4.0f, 0.5f, 9.0f), constexpr Matrix4x3 b(Vector3(-4.0f, 0.5f, 9.0f),
Vector3(-9.0f, 11.0f, 0.25f), Vector3(-9.0f, 11.0f, 0.25f),
Vector3( 0.0f, -8.0f, 19.0f), Vector3( 0.0f, -8.0f, 19.0f),
Vector3(-3.0f, -5.0f, 2.0f)); Vector3(-3.0f, -5.0f, 2.0f));
Matrix4x3 c(Vector3(-4.0f, 1.5f, 12.0f), constexpr Matrix4x3 c(Vector3(-4.0f, 1.5f, 12.0f),
Vector3(-5.0f, 16.0f, 7.25f), Vector3(-5.0f, 16.0f, 7.25f),
Vector3( 8.0f, 1.0f, 30.0f), Vector3( 8.0f, 1.0f, 30.0f),
Vector3( 9.0f, 8.0f, 17.0f)); Vector3( 9.0f, 8.0f, 17.0f));
CORRADE_COMPARE(a + b, c); constexpr auto d = a + b;
CORRADE_COMPARE(c - b, a); constexpr auto e = c - b;
CORRADE_COMPARE(d, c);
CORRADE_COMPARE(e, a);
} }
void RectangularMatrixTest::multiplyDivide() { void RectangularMatrixTest::multiplyDivide() {
Matrix2x2 matrix(Vector2(1.0f, 2.0f), constexpr Matrix2x2 matrix(Vector2(1.0f, 2.0f),
Vector2(3.0f, 4.0f)); Vector2(3.0f, 4.0f));
Matrix2x2 multiplied(Vector2(-1.5f, -3.0f), constexpr Matrix2x2 multiplied(Vector2(-1.5f, -3.0f),
Vector2(-4.5f, -6.0f)); Vector2(-4.5f, -6.0f));
CORRADE_COMPARE(matrix*-1.5f, multiplied); constexpr auto a = matrix*-1.5f;
CORRADE_COMPARE(-1.5f*matrix, multiplied); constexpr auto b = -1.5f*matrix;
CORRADE_COMPARE(multiplied/-1.5f, matrix); constexpr auto c = multiplied/-1.5f;
CORRADE_COMPARE(a, multiplied);
CORRADE_COMPARE(b, multiplied);
CORRADE_COMPARE(c, matrix);
/* Divide vector with number and inverse */ /* Divide vector with number and inverse */
Matrix2x2 divisor(Vector2( 1.0f, 2.0f), constexpr Matrix2x2 divisor(Vector2( 1.0f, 2.0f),
Vector2(-4.0f, 8.0f)); Vector2(-4.0f, 8.0f));
Matrix2x2 result(Vector2( 1.0f, 0.5f), constexpr Matrix2x2 result(Vector2( 1.0f, 0.5f),
Vector2(-0.25f, 0.125f)); Vector2(-0.25f, 0.125f));
CORRADE_COMPARE(1.0f/divisor, result);
constexpr auto d = 1.0f/divisor;
CORRADE_COMPARE(d, result);
} }
void RectangularMatrixTest::multiply() { void RectangularMatrixTest::multiply() {
RectangularMatrix<4, 6, Int> left( constexpr RectangularMatrix<4, 6, Int> left(
Vector<6, Int>(-5, 27, 10, 33, 0, -15), Vector<6, Int>(-5, 27, 10, 33, 0, -15),
Vector<6, Int>( 7, 56, 66, 1, 0, -24), Vector<6, Int>( 7, 56, 66, 1, 0, -24),
Vector<6, Int>( 4, 41, 4, 0, 1, -4), Vector<6, Int>( 4, 41, 4, 0, 1, -4),
Vector<6, Int>( 9, -100, 19, -49, 1, 9) Vector<6, Int>( 9, -100, 19, -49, 1, 9)
); );
RectangularMatrix<5, 4, Int> right( constexpr RectangularMatrix<5, 4, Int> right(
Vector<4, Int>(1, -7, 0, 158), Vector<4, Int>(1, -7, 0, 158),
Vector<4, Int>(2, 24, -3, 40), Vector<4, Int>(2, 24, -3, 40),
Vector<4, Int>(3, -15, -2, -50), Vector<4, Int>(3, -15, -2, -50),
@ -338,7 +348,7 @@ void RectangularMatrixTest::multiply() {
Vector<4, Int>(5, 30, 4, 18) Vector<4, Int>(5, 30, 4, 18)
); );
RectangularMatrix<5, 6, Int> expected( constexpr RectangularMatrix<5, 6, Int> expected(
Vector<6, Int>( 1368, -16165, 2550, -7716, 158, 1575), Vector<6, Int>( 1368, -16165, 2550, -7716, 158, 1575),
Vector<6, Int>( 506, -2725, 2352, -1870, 37, -234), Vector<6, Int>( 506, -2725, 2352, -1870, 37, -234),
Vector<6, Int>( -578, 4159, -1918, 2534, -52, -127), Vector<6, Int>( -578, 4159, -1918, 2534, -52, -127),
@ -346,36 +356,42 @@ void RectangularMatrixTest::multiply() {
Vector<6, Int>( 363, 179, 2388, -687, 22, -649) Vector<6, Int>( 363, 179, 2388, -687, 22, -649)
); );
CORRADE_COMPARE(left*right, expected); constexpr auto a = left*right;
CORRADE_COMPARE(a, expected);
} }
void RectangularMatrixTest::multiplyVector() { void RectangularMatrixTest::multiplyVector() {
Vector4i a(-5, 27, 10, 33); constexpr Vector4i a(-5, 27, 10, 33);
RectangularMatrix<3, 1, Int> b(1, 2, 3); constexpr RectangularMatrix<3, 1, Int> b(1, 2, 3);
CORRADE_COMPARE(a*b, Matrix3x4i(
constexpr auto c = a*b;
CORRADE_COMPARE(c, Matrix3x4i(
Vector4i( -5, 27, 10, 33), Vector4i( -5, 27, 10, 33),
Vector4i(-10, 54, 20, 66), Vector4i(-10, 54, 20, 66),
Vector4i(-15, 81, 30, 99) Vector4i(-15, 81, 30, 99)
)); ));
Matrix3x4i c(Vector4i(0, 4, 8, 12), constexpr Matrix3x4i d(Vector4i(0, 4, 8, 12),
Vector4i(1, 5, 9, 13), Vector4i(1, 5, 9, 13),
Vector4i(3, 7, 11, 15)); Vector4i(3, 7, 11, 15));
Vector3i d(2, -2, 3); constexpr Vector3i e(2, -2, 3);
CORRADE_COMPARE(c*d, Vector4i(7, 19, 31, 43));
constexpr auto f = d*e;
CORRADE_COMPARE(f, Vector4i(7, 19, 31, 43));
} }
void RectangularMatrixTest::transposed() { void RectangularMatrixTest::transposed() {
Matrix4x3 original(Vector3( 0.0f, 1.0f, 3.0f), constexpr Matrix4x3 original(Vector3( 0.0f, 1.0f, 3.0f),
Vector3( 4.0f, 5.0f, 7.0f), Vector3( 4.0f, 5.0f, 7.0f),
Vector3( 8.0f, 9.0f, 11.0f), Vector3( 8.0f, 9.0f, 11.0f),
Vector3(12.0f, 13.0f, 15.0f)); Vector3(12.0f, 13.0f, 15.0f));
Matrix3x4 transposed(Vector4(0.0f, 4.0f, 8.0f, 12.0f), constexpr Matrix3x4 transposed(Vector4(0.0f, 4.0f, 8.0f, 12.0f),
Vector4(1.0f, 5.0f, 9.0f, 13.0f), Vector4(1.0f, 5.0f, 9.0f, 13.0f),
Vector4(3.0f, 7.0f, 11.0f, 15.0f)); Vector4(3.0f, 7.0f, 11.0f, 15.0f));
CORRADE_COMPARE(original.transposed(), transposed); constexpr auto a = original.transposed();
CORRADE_COMPARE(a, transposed);
} }
void RectangularMatrixTest::diagonal() { void RectangularMatrixTest::diagonal() {
@ -475,48 +491,59 @@ void RectangularMatrixTest::subclass() {
CORRADE_COMPARE(Mat2x2::fromDiagonal({1.0f, -2.0f}), Mat2x2(Vector2(1.0f, 0.0f), CORRADE_COMPARE(Mat2x2::fromDiagonal({1.0f, -2.0f}), Mat2x2(Vector2(1.0f, 0.0f),
Vector2(0.0f, -2.0f))); Vector2(0.0f, -2.0f)));
const Mat2x2 a(Vector2(1.0f, -3.0f), constexpr const Mat2x2 a(Vector2(1.0f, -3.0f),
Vector2(-3.0f, 1.0f)); Vector2(-3.0f, 1.0f));
CORRADE_COMPARE(-a, Mat2x2(Vector2(-1.0f, 3.0f), constexpr auto a0 = -a;
CORRADE_COMPARE(a0, Mat2x2(Vector2(-1.0f, 3.0f),
Vector2(3.0f, -1.0f))); Vector2(3.0f, -1.0f)));
Mat2x2 b(Vector2(-2.0f, 5.0f), constexpr const Mat2x2 b(Vector2(-2.0f, 5.0f),
Vector2(5.0f, -2.0f)); Vector2(5.0f, -2.0f));
const Mat2x2 bExpected(Vector2(-1.0f, 2.0f), constexpr Mat2x2 bExpected(Vector2(-1.0f, 2.0f),
Vector2(2.0f, -1.0f)); Vector2(2.0f, -1.0f));
CORRADE_COMPARE(b + a, bExpected); constexpr auto b0 = b + a;
CORRADE_COMPARE(b0, bExpected);
Mat2x2 c(Vector2(-2.0f, 5.0f), constexpr Mat2x2 c(Vector2(-2.0f, 5.0f),
Vector2(5.0f, -2.0f)); Vector2(5.0f, -2.0f));
const Mat2x2 cExpected(Vector2(-3.0f, 8.0f), const Mat2x2 cExpected(Vector2(-3.0f, 8.0f),
Vector2(8.0f, -3.0f)); Vector2(8.0f, -3.0f));
CORRADE_COMPARE(c - a, cExpected); constexpr auto c0 = c - a;
CORRADE_COMPARE(c0, cExpected);
Mat2x2 d(Vector2(-2.0f, 5.0f), constexpr Mat2x2 d(Vector2(-2.0f, 5.0f),
Vector2(5.0f, -2.0f)); Vector2(5.0f, -2.0f));
const Mat2x2 dExpected(Vector2(-4.0f, 10.0f), const Mat2x2 dExpected(Vector2(-4.0f, 10.0f),
Vector2(10.0f, -4.0f)); Vector2(10.0f, -4.0f));
CORRADE_COMPARE(d*2.0f, dExpected); constexpr auto d0 = d*2.0f;
CORRADE_COMPARE(2.0f*d, dExpected); constexpr auto d1 = 2.0f*d;
CORRADE_COMPARE(d0, dExpected);
Mat2x2 e(Vector2(-2.0f, 5.0f), CORRADE_COMPARE(d1, dExpected);
Vector2(5.0f, -2.0f));
CORRADE_COMPARE(e/0.5f, dExpected); constexpr Mat2x2 e(Vector2(-2.0f, 5.0f),
CORRADE_COMPARE(2.0f/e, Mat2x2(Vector2(-1.0f, 0.4f), Vector2(5.0f, -2.0f));
Vector2(0.4f, -1.0f))); constexpr auto e0 = e/0.5f;
const Vector2 f(2.0f, 5.0f); constexpr auto e1 = 2.0f/e;
const Math::RectangularMatrix<2, 1, Float> g(3.0f, -1.0f); CORRADE_COMPARE(e0, dExpected);
CORRADE_COMPARE(f*g, Mat2x2(Vector2(6.0f, 15.0f), CORRADE_COMPARE(e1, Mat2x2(Vector2(-1.0f, 0.4f),
Vector2(-2.0f, -5.0f))); Vector2(0.4f, -1.0f)));
constexpr const Vector2 f(2.0f, 5.0f);
constexpr const Math::RectangularMatrix<2, 1, Float> g(3.0f, -1.0f);
constexpr auto f0 = f*g;
CORRADE_COMPARE(f0, Mat2x2(Vector2(6.0f, 15.0f),
Vector2(-2.0f, -5.0f)));
/* Operators on variable-sized matrix */ /* Operators on variable-sized matrix */
const BasicMat<1, Float> h(-2.0f); constexpr const BasicMat<1, Float> h(-2.0f);
CORRADE_COMPARE(2.0f*h, (BasicMat<1, Float>(-4.0f))); constexpr auto h0 = 2.0f*h;
CORRADE_COMPARE(2.0f/h, (BasicMat<1, Float>(-1.0f))); constexpr auto h1 = 2.0f/h;
CORRADE_COMPARE(h0, (BasicMat<1, Float>(-4.0f)));
const Math::Vector<1, Float> i(2.0f); CORRADE_COMPARE(h1, (BasicMat<1, Float>(-1.0f)));
const Math::RectangularMatrix<1, 1, Float> j(3.0f);
CORRADE_COMPARE(i*j, (BasicMat<1, Float>(6.0f))); constexpr const Math::Vector<1, Float> i(2.0f);
constexpr const Math::RectangularMatrix<1, 1, Float> j(3.0f);
constexpr auto i0 = i*j;
CORRADE_COMPARE(i0, (BasicMat<1, Float>(6.0f)));
} }
void RectangularMatrixTest::debug() { void RectangularMatrixTest::debug() {

Loading…
Cancel
Save