📄 matrixexpr.hpp
字号:
#ifndef _SDL_MATHS_MATRIX_MATRIX_EXPR_HPP_
#define _SDL_MATHS_MATRIX_MATRIX_EXPR_HPP_
#ifndef _SDL_MATHS_MATRIX_MATRIX_HPP_
#error "must be included by Matrix.hpp"
#endif
SDL_MATHS_MATRIX_BEGIN
/*
*
* BasicMatrixExpr:
* Value Semantic Support For Matrix Expression
*
*/
struct MatrixExpr{};
template<typename _MatType>
struct BasicMatrixExpr
: public MatrixExpr
{
public:
typedef BasicMatrixExpr SelfType;
typedef typename _MatType::NumberType NumberType;
BasicMatrixExpr(const _MatType& _Mat)
: Mat(_Mat)
{
}
Int32 row() const
{
return Mat.row();
}
Int32 col() const
{
return Mat.col();
}
ConstRowRef<SelfType> operator [] (Int32 _row) const
{
return ConstRowRef<SelfType>(*this, _row);
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return Mat(_row, _col);
}
ConstSubMatrixRef<SelfType> operator () (Int32 _RowBegin, Int32 _RowEnd,
Int32 _ColBegin, Int32 _ColEnd) const
{
return ConstSubMatrixRef<SelfType>(*this, _RowBegin, _RowEnd, _ColBegin, _ColEnd);
}
template<typename _OtherType>
Bool operator == (const _OtherType& other) const
{
if (row() != other.row() || col() != other.col())
{
return false;
}
for (int i = INDEX_OFFSET; i < row() + INDEX_OFFSET; ++i)
for (int j = INDEX_OFFSET; j < col() + INDEX_OFFSET; ++j)
{
if (operator () (i, j) != other(i, j))
{
return false;
}
}
return true;
}
Bool operator == (const SelfType& other) const
{
if (row() != other.row() || col() != other.col())
{
return false;
}
for (int i = INDEX_OFFSET; i < row() + INDEX_OFFSET; ++i)
for (int j = INDEX_OFFSET; j < col() + INDEX_OFFSET; ++j)
{
if (operator () (i, j) != other(i, j))
{
return false;
}
}
return true;
}
template<typename _OtherType>
Bool operator != (const _OtherType& other) const
{
return ! operator == (other);
}
Bool operator != (const SelfType& other) const
{
return ! operator == (other);;
}
protected:
_MatType Mat;
};
/*
*
* Add
*
*/
struct AddMatrixExpr
: public MatrixExpr
{
};
template<
typename _LMatType,
typename _RMatType
>
struct MatAddMatrixExpr
: public AddMatrixExpr
{
public:
typedef MatAddMatrixExpr SelfType;
typedef typename _LMatType::NumberType NumberType;
MatAddMatrixExpr(const _LMatType& _LMat, const _RMatType& _RMat)
: LMat(FULL_CREF(_LMat, _LMatType)),
RMat(FULL_CREF(_RMat, _RMatType))
{
RT_CONDITION(LMat.row() == RMat.row() && LMat.col() == RMat.col());
}
Int32 row() const
{
return LMat.row();
}
Int32 col() const
{
return LMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return LMat(_row, _col) + RMat(_row, _col);
}
protected:
ConstSubMatrixRef<_LMatType> LMat;
ConstSubMatrixRef<_RMatType> RMat;
};
template<
typename _LMatType,
typename _RMatType
>
struct ScalarAddMatrixExpr
: public AddMatrixExpr
{
public:
typedef ScalarAddMatrixExpr SelfType;
typedef typename _LMatType::NumberType NumberType;
ScalarAddMatrixExpr(const _LMatType& _LMat, _RMatType _RScalar)
: LMat(FULL_CREF(_LMat, _LMatType)),
RScalar(_RScalar)
{
}
Int32 row() const
{
return LMat.row();
}
Int32 col() const
{
return LMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return LMat(_row, _col) + RScalar;
}
protected:
ConstSubMatrixRef<_LMatType> LMat;
const _RMatType RScalar;
};
/*
*
* Sub
*
*/
struct SubMatrixExpr
: public MatrixExpr
{
};
template<
typename _LMatType,
typename _RMatType
>
struct MatSubMatrixExpr
: public SubMatrixExpr
{
public:
typedef MatSubMatrixExpr SelfType;
typedef typename _LMatType::NumberType NumberType;
MatSubMatrixExpr(const _LMatType& _LMat, const _RMatType& _RMat)
: LMat(FULL_CREF(_LMat, _LMatType)),
RMat(FULL_CREF(_RMat, _RMatType))
{
RT_CONDITION(LMat.row() == RMat.row() && LMat.col() == RMat.col());
}
Int32 row() const
{
return LMat.row();
}
Int32 col() const
{
return LMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return LMat(_row, _col) - RMat(_row, _col);
}
protected:
ConstSubMatrixRef<_LMatType> LMat;
ConstSubMatrixRef<_RMatType> RMat;
};
template<
typename _LMatType,
typename _RMatType
>
struct ScalarSubMatrixExprL
: public SubMatrixExpr
{
public:
typedef ScalarSubMatrixExprL SelfType;
typedef typename _RMatType::NumberType NumberType;
ScalarSubMatrixExprL(_LMatType _LScalar, const _RMatType& _RMat)
: LScalar(_LScalar),
RMat(FULL_CREF(_RMat, _RMatType))
{
}
Int32 row() const
{
return RMat.row();
}
Int32 col() const
{
return RMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return LScalar - RMat(_row, _col);
}
protected:
const _LMatType LScalar;
ConstSubMatrixRef<_RMatType> RMat;
};
template<
typename _LMatType,
typename _RMatType
>
struct ScalarSubMatrixExprR
: public SubMatrixExpr
{
public:
typedef ScalarSubMatrixExprR SelfType;
typedef typename _LMatType::NumberType NumberType;
ScalarSubMatrixExprR(const _LMatType& _LMat, _RMatType _RScalar)
: LMat(FULL_CREF(_LMat, _LMatType)),
RScalar(_RScalar)
{
}
Int32 row() const
{
return LMat.row();
}
Int32 col() const
{
return LMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return LMat(_row, _col) - RScalar;
}
protected:
ConstSubMatrixRef<_LMatType> LMat;
const _RMatType RScalar;
};
/*
*
* Mul
*
*/
struct MulMatrixExpr
: public MatrixExpr
{
};
template<
typename _LMatType,
typename _RMatType
>
struct MatMulMatrixExpr
: public MulMatrixExpr
{
public:
typedef MatMulMatrixExpr SelfType;
typedef typename _LMatType::NumberType NumberType;
MatMulMatrixExpr(const _LMatType& _LMat, const _RMatType& _RMat)
: LMat(FULL_CREF(_LMat, _LMatType)),
RMat(FULL_CREF(_RMat, _RMatType))
{
RT_CONDITION(LMat.col() == RMat.row());
}
Int32 row() const
{
return LMat.row();
}
Int32 col() const
{
return RMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
NumberType result = 0;
for (int i = INDEX_OFFSET; i < LMat.col()+INDEX_OFFSET; ++i)
{
result += LMat(_row, i) * RMat(i, _col);
}
return result;
}
protected:
ConstSubMatrixRef<_LMatType> LMat;
ConstSubMatrixRef<_RMatType> RMat;
};
template<
typename _LMatType,
typename _RMatType
>
struct ScalarMulMatrixExpr
: public MulMatrixExpr
{
public:
typedef ScalarMulMatrixExpr SelfType;
typedef typename _LMatType::NumberType NumberType;
ScalarMulMatrixExpr(const _LMatType& _LMat, _RMatType _RScalar)
: LMat(FULL_CREF(_LMat, _LMatType)),
RScalar(_RScalar)
{
}
Int32 row() const
{
return LMat.row();
}
Int32 col() const
{
return LMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return LMat(_row, _col) * RScalar;
}
protected:
ConstSubMatrixRef<_LMatType> LMat;
const _RMatType RScalar;
};
template<typename _MatType>
struct NegMatrixExpr
: public MatrixExpr
{
public:
typedef NegMatrixExpr SelfType;
typedef typename _MatType::NumberType NumberType;
NegMatrixExpr(const _MatType& _Mat)
: Mat(FULL_CREF(_Mat, _MatType))
{
}
Int32 row() const
{
return Mat.row();
}
Int32 col() const
{
return Mat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return -Mat(_row, _col);
}
protected:
ConstSubMatrixRef<_MatType> Mat;
};
/*
*
* Div
*
*/
struct DivMatrixExpr
: public MatrixExpr
{
};
template<
typename _LMatType,
typename _RMatType
>
struct MatDivMatrixExpr
: public DivMatrixExpr
{
public:
typedef MatDivMatrixExpr SelfType;
typedef typename _LMatType::NumberType NumberType;
MatDivMatrixExpr(const _LMatType& _LMat, const _RMatType& _RMat)
: Result(_LMat.row(), _LMat.col())
{
RT_CONDITION(_RMat.row() == _RMat.col() && _LMat.col() == _RMat.row());
if ((void*)&_LMat == (void*)&_RMat)
{
Result.Diag();
}
else
{
Result = _LMat * Inv(_RMat);
}
}
Int32 row() const
{
return Result.row();
}
Int32 col() const
{
return Result.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return Result(_row, _col);
}
protected:
BasicMatrix<NumberType> Result;
};
template<
typename _LMatType,
typename _RMatType
>
struct ScalarDivMatrixExprL
: public DivMatrixExpr
{
public:
typedef ScalarDivMatrixExprL SelfType;
typedef typename _RMatType::NumberType NumberType;
ScalarDivMatrixExprL(_LMatType _LScalar, const _RMatType _RMat)
: Result(_RMat.row(), _RMat.col())
{
Result = Inv(_RMat);
Result = Result * _LScalar;
}
Int32 row() const
{
return Result.row();
}
Int32 col() const
{
return Result.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return Result(_row, _col);
}
protected:
BasicMatrix<NumberType> Result;
};
template<
typename _LMatType,
typename _RMatType
>
struct ScalarDivMatrixExprR
: public DivMatrixExpr
{
public:
typedef ScalarDivMatrixExprR SelfType;
typedef typename _LMatType::NumberType NumberType;
ScalarDivMatrixExprR(const _LMatType& _LMat, _RMatType _RScalar)
: LMat(FULL_CREF(_LMat, _LMatType)),
RScalar(_RScalar)
{
}
Int32 row() const
{
return LMat.row();
}
Int32 col() const
{
return LMat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return LMat(_row, _col) / RScalar;
}
protected:
ConstSubMatrixRef<_LMatType> LMat;
const _RMatType RScalar;
};
/*
*
* Power
*
*/
template<typename _MatType>
struct PowMatrixExpr
: public MatrixExpr
{
public:
typedef PowMatrixExpr SelfType;
typedef typename _MatType::NumberType NumberType;
PowMatrixExpr(const _MatType& _Mat, Int32 n)
: Result(_Mat.row(), _Mat.row())
{
RT_CONDITION(_Mat.row() == _Mat.col() && n >= 0);
BasicMatrix<NumberType> f(_Mat.row(), _Mat.row());
BasicMatrix<NumberType> t(_Mat.row(), _Mat.row());
Result.Diag();
f = _Mat;
for (; n; n >>= 1)
{
if (n & 1)
{
Result *= f;
}
f *= f;
}
}
Int32 row() const
{
return Result.row();
}
Int32 col() const
{
return Result.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return Result(_row, _col);
}
protected:
BasicMatrix<NumberType> Result;
};
/*
*
* Transpose
*
*/
template<typename _MatType>
struct TranMatrixExpr
: public MatrixExpr
{
public:
typedef TranMatrixExpr SelfType;
typedef typename _MatType::NumberType NumberType;
TranMatrixExpr(const _MatType& _Mat)
: Mat(FULL_CREF(_Mat, _MatType))
{
}
Int32 row() const
{
return Mat.col();
}
Int32 col() const
{
return Mat.row();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return Mat(_col, _row);
}
protected:
ConstSubMatrixRef<_MatType> Mat;
};
/*
*
* Abs
*
*/
template<typename _MatType>
struct AbsMatrixExpr
: public MatrixExpr
{
public:
typedef AbsMatrixExpr SelfType;
typedef typename _MatType::NumberType NumberType;
AbsMatrixExpr(const _MatType& _Mat)
: Mat(FULL_CREF(_Mat, _MatType))
{
}
Int32 row() const
{
return Mat.row();
}
Int32 col() const
{
return Mat.col();
}
NumberType operator () (Int32 _row, Int32 _col) const
{
return fabs(Mat(_row, _col));
}
protected:
ConstSubMatrixRef<_MatType> Mat;
};
SDL_MATHS_MATRIX_END
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -