You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
631 lines
17 KiB
631 lines
17 KiB
#ifndef _TCUMATRIX_HPP
|
|
#define _TCUMATRIX_HPP
|
|
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program Tester Core
|
|
* ----------------------------------------
|
|
*
|
|
* Copyright 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief Templatized matrix class.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "tcuDefs.hpp"
|
|
#include "tcuVector.hpp"
|
|
#include "tcuArray.hpp"
|
|
|
|
namespace tcu
|
|
{
|
|
|
|
// Templated matrix class.
|
|
template <typename T, int Rows, int Cols>
|
|
class Matrix
|
|
{
|
|
public:
|
|
typedef Vector<T, Rows> Element;
|
|
typedef T Scalar;
|
|
|
|
enum
|
|
{
|
|
SIZE = Cols,
|
|
ROWS = Rows,
|
|
COLS = Cols,
|
|
};
|
|
|
|
Matrix (void);
|
|
explicit Matrix (const T& src);
|
|
explicit Matrix (const T src[Rows*Cols]);
|
|
Matrix (const Vector<T, Rows>& src);
|
|
Matrix (const Matrix<T, Rows, Cols>& src);
|
|
~Matrix (void);
|
|
|
|
Matrix<T, Rows, Cols>& operator= (const Matrix<T, Rows, Cols>& src);
|
|
Matrix<T, Rows, Cols>& operator*= (const Matrix<T, Rows, Cols>& src);
|
|
|
|
void setRow (int rowNdx, const Vector<T, Cols>& vec);
|
|
void setColumn (int colNdx, const Vector<T, Rows>& vec);
|
|
|
|
Vector<T, Cols> getRow (int ndx) const;
|
|
Vector<T, Rows>& getColumn (int ndx);
|
|
const Vector<T, Rows>& getColumn (int ndx) const;
|
|
|
|
Vector<T, Rows>& operator[] (int ndx) { return getColumn(ndx); }
|
|
const Vector<T, Rows>& operator[] (int ndx) const { return getColumn(ndx); }
|
|
|
|
inline const T& operator() (int row, int col) const { return m_data[col][row]; }
|
|
inline T& operator() (int row, int col) { return m_data[col][row]; }
|
|
|
|
Array<T, Rows*Cols> getRowMajorData (void) const;
|
|
Array<T, Rows*Cols> getColumnMajorData (void) const;
|
|
|
|
private:
|
|
Vector<Vector<T, Rows>, Cols> m_data;
|
|
} DE_WARN_UNUSED_TYPE;
|
|
|
|
// Operators.
|
|
|
|
// Mat * Mat.
|
|
template <typename T, int Rows0, int Cols0, int Rows1, int Cols1>
|
|
Matrix<T, Rows0, Cols1> operator* (const Matrix<T, Rows0, Cols0>& a, const Matrix<T, Rows1, Cols1>& b);
|
|
|
|
// Mat * Vec (column vector).
|
|
template <typename T, int Rows, int Cols>
|
|
Vector<T, Rows> operator* (const Matrix<T, Rows, Cols>& mtx, const Vector<T, Cols>& vec);
|
|
|
|
// Vec * Mat (row vector).
|
|
template <typename T, int Rows, int Cols>
|
|
Vector<T, Cols> operator* (const Vector<T, Rows>& vec, const Matrix<T, Rows, Cols>& mtx);
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
bool operator== (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs);
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
bool operator!= (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs);
|
|
|
|
// Further operations
|
|
|
|
template <typename T, int Size>
|
|
struct SquareMatrixOps
|
|
{
|
|
static T doDeterminant (const Matrix<T, Size, Size>& mat);
|
|
static Matrix<T, Size, Size> doInverse (const Matrix<T, Size, Size>& mat);
|
|
};
|
|
|
|
template <typename T>
|
|
struct SquareMatrixOps<T, 2>
|
|
{
|
|
static T doDeterminant (const Matrix<T, 2, 2>& mat);
|
|
static Matrix<T, 2, 2> doInverse (const Matrix<T, 2, 2>& mat);
|
|
};
|
|
|
|
template <typename T>
|
|
struct SquareMatrixOps<T, 3>
|
|
{
|
|
static T doDeterminant (const Matrix<T, 3, 3>& mat);
|
|
static Matrix<T, 3, 3> doInverse (const Matrix<T, 3, 3>& mat);
|
|
};
|
|
|
|
template <typename T>
|
|
struct SquareMatrixOps<T, 4>
|
|
{
|
|
static T doDeterminant (const Matrix<T, 4, 4>& mat);
|
|
static Matrix<T, 4, 4> doInverse (const Matrix<T, 4, 4>& mat);
|
|
};
|
|
|
|
namespace matrix
|
|
{
|
|
|
|
template <typename T, int Size>
|
|
T determinant (const Matrix<T, Size, Size>& mat)
|
|
{
|
|
return SquareMatrixOps<T, Size>::doDeterminant(mat);
|
|
}
|
|
|
|
template <typename T, int Size>
|
|
Matrix<T, Size, Size> inverse (const Matrix<T, Size, Size>& mat)
|
|
{
|
|
return SquareMatrixOps<T, Size>::doInverse(mat);
|
|
}
|
|
|
|
} // matrix
|
|
|
|
// Template implementations.
|
|
|
|
template <typename T>
|
|
T SquareMatrixOps<T, 2>::doDeterminant (const Matrix<T, 2, 2>& mat)
|
|
{
|
|
return mat(0,0) * mat(1,1) - mat(1,0) * mat(0,1);
|
|
}
|
|
|
|
template <typename T>
|
|
T SquareMatrixOps<T, 3>::doDeterminant (const Matrix<T, 3, 3>& mat)
|
|
{
|
|
return + mat(0,0) * mat(1,1) * mat(2,2)
|
|
+ mat(0,1) * mat(1,2) * mat(2,0)
|
|
+ mat(0,2) * mat(1,0) * mat(2,1)
|
|
- mat(0,0) * mat(1,2) * mat(2,1)
|
|
- mat(0,1) * mat(1,0) * mat(2,2)
|
|
- mat(0,2) * mat(1,1) * mat(2,0);
|
|
}
|
|
|
|
template <typename T>
|
|
T SquareMatrixOps<T, 4>::doDeterminant (const Matrix<T, 4, 4>& mat)
|
|
{
|
|
using matrix::determinant;
|
|
|
|
const T minorMatrices[4][3*3] =
|
|
{
|
|
{
|
|
mat(1,1), mat(2,1), mat(3,1),
|
|
mat(1,2), mat(2,2), mat(3,2),
|
|
mat(1,3), mat(2,3), mat(3,3),
|
|
},
|
|
{
|
|
mat(1,0), mat(2,0), mat(3,0),
|
|
mat(1,2), mat(2,2), mat(3,2),
|
|
mat(1,3), mat(2,3), mat(3,3),
|
|
},
|
|
{
|
|
mat(1,0), mat(2,0), mat(3,0),
|
|
mat(1,1), mat(2,1), mat(3,1),
|
|
mat(1,3), mat(2,3), mat(3,3),
|
|
},
|
|
{
|
|
mat(1,0), mat(2,0), mat(3,0),
|
|
mat(1,1), mat(2,1), mat(3,1),
|
|
mat(1,2), mat(2,2), mat(3,2),
|
|
}
|
|
};
|
|
|
|
return + mat(0,0) * determinant(Matrix<T, 3, 3>(minorMatrices[0]))
|
|
- mat(0,1) * determinant(Matrix<T, 3, 3>(minorMatrices[1]))
|
|
+ mat(0,2) * determinant(Matrix<T, 3, 3>(minorMatrices[2]))
|
|
- mat(0,3) * determinant(Matrix<T, 3, 3>(minorMatrices[3]));
|
|
}
|
|
|
|
template <typename T>
|
|
Matrix<T, 2, 2> SquareMatrixOps<T, 2>::doInverse (const Matrix<T, 2, 2>& mat)
|
|
{
|
|
using matrix::determinant;
|
|
|
|
const T det = determinant(mat);
|
|
Matrix<T, 2, 2> retVal;
|
|
|
|
retVal(0, 0) = mat(1, 1) / det;
|
|
retVal(0, 1) = -mat(0, 1) / det;
|
|
retVal(1, 0) = -mat(1, 0) / det;
|
|
retVal(1, 1) = mat(0, 0) / det;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
template <typename T>
|
|
Matrix<T, 3, 3> SquareMatrixOps<T, 3>::doInverse (const Matrix<T, 3, 3>& mat)
|
|
{
|
|
// Blockwise inversion
|
|
using matrix::inverse;
|
|
|
|
const T areaA[2*2] =
|
|
{
|
|
mat(0,0), mat(0,1),
|
|
mat(1,0), mat(1,1)
|
|
};
|
|
const T areaB[2] =
|
|
{
|
|
mat(0,2),
|
|
mat(1,2),
|
|
};
|
|
const T areaC[2] =
|
|
{
|
|
mat(2,0), mat(2,1),
|
|
};
|
|
const T areaD[1] =
|
|
{
|
|
mat(2,2)
|
|
};
|
|
const T nullField[4] = { T(0.0f) };
|
|
|
|
const Matrix<T, 2, 2> invA = inverse(Matrix<T, 2, 2>(areaA));
|
|
const Matrix<T, 2, 1> matB = Matrix<T, 2, 1>(areaB);
|
|
const Matrix<T, 1, 2> matC = Matrix<T, 1, 2>(areaC);
|
|
const Matrix<T, 1, 1> matD = Matrix<T, 1, 1>(areaD);
|
|
|
|
const T schurComplement = T(1.0f) / (matD - matC*invA*matB)(0,0);
|
|
const Matrix<T, 2, 2> zeroMat = Matrix<T, 2, 2>(nullField);
|
|
|
|
const Matrix<T, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
|
|
const Matrix<T, 2, 1> blockB = (zeroMat-invA)*matB*schurComplement;
|
|
const Matrix<T, 1, 2> blockC = matC*invA*(-schurComplement);
|
|
const T blockD = schurComplement;
|
|
|
|
const T result[3*3] =
|
|
{
|
|
blockA(0,0), blockA(0,1), blockB(0,0),
|
|
blockA(1,0), blockA(1,1), blockB(1,0),
|
|
blockC(0,0), blockC(0,1), blockD,
|
|
};
|
|
|
|
return Matrix<T, 3, 3>(result);
|
|
}
|
|
|
|
template <typename T>
|
|
Matrix<T, 4, 4> SquareMatrixOps<T, 4>::doInverse (const Matrix<T, 4, 4>& mat)
|
|
{
|
|
// Blockwise inversion
|
|
using matrix::inverse;
|
|
|
|
const T areaA[2*2] =
|
|
{
|
|
mat(0,0), mat(0,1),
|
|
mat(1,0), mat(1,1)
|
|
};
|
|
const T areaB[2*2] =
|
|
{
|
|
mat(0,2), mat(0,3),
|
|
mat(1,2), mat(1,3)
|
|
};
|
|
const T areaC[2*2] =
|
|
{
|
|
mat(2,0), mat(2,1),
|
|
mat(3,0), mat(3,1)
|
|
};
|
|
const T areaD[2*2] =
|
|
{
|
|
mat(2,2), mat(2,3),
|
|
mat(3,2), mat(3,3)
|
|
};
|
|
const T nullField[4] = { T(0.0f) };
|
|
|
|
const Matrix<T, 2, 2> invA = inverse(Matrix<T, 2, 2>(areaA));
|
|
const Matrix<T, 2, 2> matB = Matrix<T, 2, 2>(areaB);
|
|
const Matrix<T, 2, 2> matC = Matrix<T, 2, 2>(areaC);
|
|
const Matrix<T, 2, 2> matD = Matrix<T, 2, 2>(areaD);
|
|
|
|
const Matrix<T, 2, 2> schurComplement = inverse(matD - matC*invA*matB);
|
|
const Matrix<T, 2, 2> zeroMat = Matrix<T, 2, 2>(nullField);
|
|
|
|
const Matrix<T, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
|
|
const Matrix<T, 2, 2> blockB = (zeroMat-invA)*matB*schurComplement;
|
|
const Matrix<T, 2, 2> blockC = (zeroMat-schurComplement)*matC*invA;
|
|
const Matrix<T, 2, 2> blockD = schurComplement;
|
|
|
|
const T result[4*4] =
|
|
{
|
|
blockA(0,0), blockA(0,1), blockB(0,0), blockB(0,1),
|
|
blockA(1,0), blockA(1,1), blockB(1,0), blockB(1,1),
|
|
blockC(0,0), blockC(0,1), blockD(0,0), blockD(0,1),
|
|
blockC(1,0), blockC(1,1), blockD(1,0), blockD(1,1),
|
|
};
|
|
|
|
return Matrix<T, 4, 4>(result);
|
|
}
|
|
|
|
// Initialize to identity.
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>::Matrix (void)
|
|
{
|
|
for (int row = 0; row < Rows; row++)
|
|
for (int col = 0; col < Cols; col++)
|
|
(*this)(row, col) = (row == col) ? T(1) : T(0);
|
|
}
|
|
|
|
// Initialize to diagonal matrix.
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>::Matrix (const T& src)
|
|
{
|
|
for (int row = 0; row < Rows; row++)
|
|
for (int col = 0; col < Cols; col++)
|
|
(*this)(row, col) = (row == col) ? src : T(0);
|
|
}
|
|
|
|
// Initialize from data array.
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>::Matrix (const T src[Rows*Cols])
|
|
{
|
|
for (int row = 0; row < Rows; row++)
|
|
for (int col = 0; col < Cols; col++)
|
|
(*this)(row, col) = src[row*Cols + col];
|
|
}
|
|
|
|
// Initialize to diagonal matrix.
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>::Matrix (const Vector<T, Rows>& src)
|
|
{
|
|
DE_STATIC_ASSERT(Rows == Cols);
|
|
for (int row = 0; row < Rows; row++)
|
|
for (int col = 0; col < Cols; col++)
|
|
(*this)(row, col) = (row == col) ? src.m_data[row] : T(0);
|
|
}
|
|
|
|
// Copy constructor.
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>::Matrix (const Matrix<T, Rows, Cols>& src)
|
|
{
|
|
*this = src;
|
|
}
|
|
|
|
// Destructor.
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>::~Matrix (void)
|
|
{
|
|
}
|
|
|
|
// Assignment operator.
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>& Matrix<T, Rows, Cols>::operator= (const Matrix<T, Rows, Cols>& src)
|
|
{
|
|
for (int row = 0; row < Rows; row++)
|
|
for (int col = 0; col < Cols; col++)
|
|
(*this)(row, col) = src(row, col);
|
|
return *this;
|
|
}
|
|
|
|
// Multipy and assign op
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols>& Matrix<T, Rows, Cols>::operator*= (const Matrix<T, Rows, Cols>& src)
|
|
{
|
|
*this = *this * src;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
void Matrix<T, Rows, Cols>::setRow (int rowNdx, const Vector<T, Cols>& vec)
|
|
{
|
|
for (int col = 0; col < Cols; col++)
|
|
(*this)(rowNdx, col) = vec.m_data[col];
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
void Matrix<T, Rows, Cols>::setColumn (int colNdx, const Vector<T, Rows>& vec)
|
|
{
|
|
m_data[colNdx] = vec;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Vector<T, Cols> Matrix<T, Rows, Cols>::getRow (int rowNdx) const
|
|
{
|
|
Vector<T, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
res[col] = (*this)(rowNdx, col);
|
|
return res;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Vector<T, Rows>& Matrix<T, Rows, Cols>::getColumn (int colNdx)
|
|
{
|
|
return m_data[colNdx];
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
const Vector<T, Rows>& Matrix<T, Rows, Cols>::getColumn (int colNdx) const
|
|
{
|
|
return m_data[colNdx];
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Array<T, Rows*Cols> Matrix<T, Rows, Cols>::getColumnMajorData (void) const
|
|
{
|
|
Array<T, Rows*Cols> a;
|
|
T* dst = a.getPtr();
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
*dst++ = (*this)(row, col);
|
|
return a;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Array<T, Rows*Cols> Matrix<T, Rows, Cols>::getRowMajorData (void) const
|
|
{
|
|
Array<T, Rows*Cols> a;
|
|
T* dst = a.getPtr();
|
|
for (int row = 0; row < Rows; row++)
|
|
for (int col = 0; col < Cols; col++)
|
|
*dst++ = (*this)(row, col);
|
|
return a;
|
|
}
|
|
|
|
// Multiplication of two matrices.
|
|
template <typename T, int Rows0, int Cols0, int Rows1, int Cols1>
|
|
Matrix<T, Rows0, Cols1> operator* (const Matrix<T, Rows0, Cols0>& a, const Matrix<T, Rows1, Cols1>& b)
|
|
{
|
|
DE_STATIC_ASSERT(Cols0 == Rows1);
|
|
Matrix<T, Rows0, Cols1> res;
|
|
for (int row = 0; row < Rows0; row++)
|
|
{
|
|
for (int col = 0; col < Cols1; col++)
|
|
{
|
|
T v = T(0);
|
|
for (int ndx = 0; ndx < Cols0; ndx++)
|
|
v += a(row,ndx) * b(ndx,col);
|
|
res(row,col) = v;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// Multiply of matrix with column vector.
|
|
template <typename T, int Rows, int Cols>
|
|
Vector<T, Rows> operator* (const Matrix<T, Rows, Cols>& mtx, const Vector<T, Cols>& vec)
|
|
{
|
|
Vector<T, Rows> res;
|
|
for (int row = 0; row < Rows; row++)
|
|
{
|
|
T v = T(0);
|
|
for (int col = 0; col < Cols; col++)
|
|
v += mtx(row,col) * vec.m_data[col];
|
|
res.m_data[row] = v;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// Multiply of matrix with row vector.
|
|
template <typename T, int Rows, int Cols>
|
|
Vector<T, Cols> operator* (const Vector<T, Rows>& vec, const Matrix<T, Rows, Cols>& mtx)
|
|
{
|
|
Vector<T, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
{
|
|
T v = T(0);
|
|
for (int row = 0; row < Rows; row++)
|
|
v += mtx(row,col) * vec.m_data[row];
|
|
res.m_data[col] = v;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// Common typedefs.
|
|
typedef Matrix<float, 2, 2> Matrix2f;
|
|
typedef Matrix<float, 3, 3> Matrix3f;
|
|
typedef Matrix<float, 4, 4> Matrix4f;
|
|
|
|
// GLSL-style naming \note CxR.
|
|
typedef Matrix2f Mat2;
|
|
typedef Matrix<float, 3, 2> Mat2x3;
|
|
typedef Matrix<float, 4, 2> Mat2x4;
|
|
typedef Matrix<float, 2, 3> Mat3x2;
|
|
typedef Matrix3f Mat3;
|
|
typedef Matrix<float, 4, 3> Mat3x4;
|
|
typedef Matrix<float, 2, 4> Mat4x2;
|
|
typedef Matrix<float, 3, 4> Mat4x3;
|
|
typedef Matrix4f Mat4;
|
|
|
|
//using tcu::Matrix;
|
|
// Common typedefs 16Bit.
|
|
typedef Matrix<deUint16, 2, 2> Matrix2f16b;
|
|
typedef Matrix<deUint16, 3, 3> Matrix3f16b;
|
|
typedef Matrix<deUint16, 4, 4> Matrix4f16b;
|
|
|
|
// GLSL-style naming \note CxR.
|
|
typedef Matrix2f16b Mat2_16b;
|
|
typedef Matrix<deUint16, 3, 2> Mat2x3_16b;
|
|
typedef Matrix<deUint16, 4, 2> Mat2x4_16b;
|
|
typedef Matrix<deUint16, 2, 3> Mat3x2_16b;
|
|
typedef Matrix3f16b Mat3_16b;
|
|
typedef Matrix<deUint16, 4, 3> Mat3x4_16b;
|
|
typedef Matrix<deUint16, 2, 4> Mat4x2_16b;
|
|
typedef Matrix<deUint16, 3, 4> Mat4x3_16b;
|
|
typedef Matrix4f16b Mat4_16b;
|
|
|
|
// 64-bit matrices.
|
|
typedef Matrix<double, 2, 2> Matrix2d;
|
|
typedef Matrix<double, 3, 3> Matrix3d;
|
|
typedef Matrix<double, 4, 4> Matrix4d;
|
|
|
|
// GLSL-style naming \note CxR.
|
|
typedef Matrix2d Mat2d;
|
|
typedef Matrix<double, 3, 2> Mat2x3d;
|
|
typedef Matrix<double, 4, 2> Mat2x4d;
|
|
typedef Matrix<double, 2, 3> Mat3x2d;
|
|
typedef Matrix3d Mat3d;
|
|
typedef Matrix<double, 4, 3> Mat3x4d;
|
|
typedef Matrix<double, 2, 4> Mat4x2d;
|
|
typedef Matrix<double, 3, 4> Mat4x3d;
|
|
typedef Matrix4d Mat4d;
|
|
|
|
// Matrix-scalar operators.
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols> operator+ (const Matrix<T, Rows, Cols>& mtx, T scalar)
|
|
{
|
|
Matrix<T, Rows, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
res(row, col) = mtx(row, col) + scalar;
|
|
return res;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols> operator- (const Matrix<T, Rows, Cols>& mtx, T scalar)
|
|
{
|
|
Matrix<T, Rows, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
res(row, col) = mtx(row, col) - scalar;
|
|
return res;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols> operator* (const Matrix<T, Rows, Cols>& mtx, T scalar)
|
|
{
|
|
Matrix<T, Rows, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
res(row, col) = mtx(row, col) * scalar;
|
|
return res;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols> operator/ (const Matrix<T, Rows, Cols>& mtx, T scalar)
|
|
{
|
|
Matrix<T, Rows, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
res(row, col) = mtx(row, col) / scalar;
|
|
return res;
|
|
}
|
|
|
|
// Matrix-matrix component-wise operators.
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols> operator+ (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
|
|
{
|
|
Matrix<T, Rows, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
res(row, col) = a(row, col) + b(row, col);
|
|
return res;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols> operator- (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
|
|
{
|
|
Matrix<T, Rows, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
res(row, col) = a(row, col) - b(row, col);
|
|
return res;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
Matrix<T, Rows, Cols> operator/ (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
|
|
{
|
|
Matrix<T, Rows, Cols> res;
|
|
for (int col = 0; col < Cols; col++)
|
|
for (int row = 0; row < Rows; row++)
|
|
res(row, col) = a(row, col) / b(row, col);
|
|
return res;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
bool operator== (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs)
|
|
{
|
|
for (int row = 0; row < Rows; row++)
|
|
for (int col = 0; col < Cols; col++)
|
|
if (lhs(row, col) != rhs(row, col))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
template <typename T, int Rows, int Cols>
|
|
bool operator!= (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs)
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
} // tcu
|
|
|
|
#endif // _TCUMATRIX_HPP
|