@@ -1,5 +1,7 @@
/*! \file pimathmatrix.h
* \brief PIMathMatrix
*
* This file declare math matrix class, which performs various matrix operations
*/
/*
PIP - Platform Independent Primitives
@@ -54,12 +56,13 @@ inline bool _PIMathMatrixNullCompare<complexd >(const complexd v) {
# define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
# pragma pack(push, 1)
//! \brief A class that works with square matrix operations, the input data of which are columns, rows and the data type of the matrix
template < uint Rows , uint Cols = Rows , typename Type = double >
class PIP_EXPORT PIMathMatrixT {
typedef PIMathMatrixT < Rows , Cols , Type > _CMatrix ;
typedef PIMathMatrixT < Cols , Rows , Type > _CMatrixI ;
typedef PIMathVectorT < Rows , Type > _CMCol ;
typedef PIMathVectorT < Cols , Type > _CMRow ;
typedef PIMathMatrixT < Rows , Cols , Type > _CMatrix ;
typedef PIMathMatrixT < Cols , Rows , Type > _CMatrixI ;
typedef PIMathVectorT < Rows , Type > _CMCol ;
typedef PIMathVectorT < Cols , Type > _CMRow ;
static_assert ( std : : is_arithmetic < Type > : : value , " Type must be arithmetic " ) ;
static_assert ( Rows > 0 , " Row count must be > 0 " ) ;
static_assert ( Cols > 0 , " Column count must be > 0 " ) ;
@@ -67,46 +70,302 @@ public:
PIMathMatrixT ( ) { resize ( Rows , Cols ) ; }
PIMathMatrixT ( const PIVector < Type > & val ) { resize ( Rows , Cols ) ; int i = 0 ; PIMM_FOR_I_WB ( r , c ) m [ r ] [ c ] = val [ i + + ] ; }
/**
* @brief С reates a matrix whose main diagonal is filled with ones and the remaining elements are zeros
*
* @return identitied matrix of type PIMathMatrixT
*/
static _CMatrix identity ( ) { _CMatrix tm = _CMatrix ( ) ; PIMM_FOR_WB ( r , c ) tm . m [ r ] [ c ] = ( c = = r ? Type ( 1 ) : Type ( 0 ) ) ; return tm ; }
/**
* @brief Creates a matrix that is filled with elements
*
* @param v is a parameter the type and value of which is selected and later filled into the matrix
* @return filled matrix of type PIMathMatrixT
*/
static _CMatrix filled ( const Type & v ) { _CMatrix tm ; PIMM_FOR_WB ( r , c ) tm . m [ r ] [ c ] = v ; return tm ; }
/**
* @brief Rotation the matrix by an "angle"
*
* @param angle is the angle of rotation of the matrix
* @return rotated matrix
*/
static _CMatrix rotation ( double angle ) { return _CMatrix ( ) ; }
/**
* @brief Rotation of the matrix by an "angle" along the X axis
*
* @param angle is the angle of rotation of the matrix along the X axis
* @return rotated matrix
*/
static _CMatrix rotationX ( double angle ) { return _CMatrix ( ) ; }
/**
* @brief Rotation of the matrix by an "angle" along the Y axis
*
* @param angle is the angle of rotation of the matrix along the Y axis
* @return rotated matrix
*/
static _CMatrix rotationY ( double angle ) { return _CMatrix ( ) ; }
/**
* @brief Rotation of the matrix by an "angle" along the Z axis
*
* @param angle is the angle of rotation of the matrix along the Z axis
* @return rotated matrix
*/
static _CMatrix rotationZ ( double angle ) { return _CMatrix ( ) ; }
/**
* @brief Scaling the matrix along the X axis by the value "factor"
*
* @param factor is the value of scaling by X axis
* @return rotated matrix
*/
static _CMatrix scaleX ( double factor ) { return _CMatrix ( ) ; }
/**
* @brief Scaling the matrix along the Y axis by the value "factor"
*
* @param factor is the value of scaling by Y axis
* @return rotated matrix
*/
static _CMatrix scaleY ( double factor ) { return _CMatrix ( ) ; }
/**
* @brief Scaling the matrix along the Z axis by the value "factor"
*
* @param factor is the value of scaling by Z axis
* @return rotated matrix
*/
static _CMatrix scaleZ ( double factor ) { return _CMatrix ( ) ; }
/**
* @brief Method which returns number of columns in matrix
*
* @return type uint shows number of columns
*/
uint cols ( ) const { return Cols ; }
/**
* @brief Method which returns number of rows in matrix
*
* @return type uint shows number of rows
*/
uint rows ( ) const { return Rows ; }
/**
* @brief Method which returns the selected column in PIMathVectorT format
*
* @param index is the number of the selected column
* @return column in PIMathVectorT format
*/
_CMCol col ( uint index ) { _CMCol tv ; PIMM_FOR_R ( i ) tv [ i ] = m [ i ] [ index ] ; return tv ; }
/**
* @brief Method which returns the selected row in PIMathVectorT format
*
* @param index is the number of the selected row
* @return row in PIMathVectorT format
*/
_CMRow row ( uint index ) { _CMRow tv ; PIMM_FOR_C ( i ) tv [ i ] = m [ index ] [ i ] ; return tv ; }
/**
* @brief Set the selected column in matrix
*
* @param index is the number of the selected column
* @param v is a vector of the type _CMCol that needs to fill the column
* @return matrix type _CMatrix
*/
_CMatrix & setCol ( uint index , const _CMCol & v ) { PIMM_FOR_R ( i ) m [ i ] [ index ] = v [ i ] ; return * this ; }
/**
* @brief Set the selected row in matrix
*
* @param index is the number of the selected row
* @param v is a vector of the type _CMCol that needs to fill the row
* @return matrix type _CMatrix
*/
_CMatrix & setRow ( uint index , const _CMRow & v ) { PIMM_FOR_C ( i ) m [ index ] [ i ] = v [ i ] ; return * this ; }
/**
* @brief Method which changes selected rows in a matrix
*
* @param r0 is the number of the first selected row
* @param r1 is the number of the second selected row
* @return matrix type _CMatrix
*/
_CMatrix & swapRows ( uint r0 , uint r1 ) { Type t ; PIMM_FOR_C ( i ) { t = m [ r0 ] [ i ] ; m [ r0 ] [ i ] = m [ r1 ] [ i ] ; m [ r1 ] [ i ] = t ; } return * this ; }
/**
* @brief Method which changes selected columns in a matrix
*
* @param c0 is the number of the first selected column
* @param c1 is the number of the second selected column
* @return matrix type _CMatrix
*/
_CMatrix & swapCols ( uint c0 , uint c1 ) { Type t ; PIMM_FOR_R ( i ) { t = m [ i ] [ c0 ] ; m [ i ] [ c0 ] = m [ i ] [ c1 ] ; m [ i ] [ c1 ] = t ; } return * this ; }
/**
* @brief Method which fills the matrix with selected value
*
* @param v is a parameter the type and value of which is selected and later filled into the matrix
* @return filled matrix type _CMatrix
*/
_CMatrix & fill ( const Type & v ) { PIMM_FOR_WB ( r , c ) m [ r ] [ c ] = v ; return * this ; }
/**
* @brief Method which checks if matrix is square
*
* @return true if matrix is square, else false
*/
bool isSquare ( ) const { return cols ( ) = = rows ( ) ; }
/**
* @brief Method which checks if main diagonal of matrix consists of ones and another elements are zeros
*
* @return true if matrix is identitied, else false
*/
bool isIdentity ( ) const { PIMM_FOR_WB ( r , c ) if ( ( c = = r ) ? m [ r ] [ c ] ! = Type ( 1 ) : m [ r ] [ c ] ! = Type ( 0 ) ) return false ; return true ; }
/**
* @brief Method which checks if every elements of matrix are zeros
*
* @return true if matrix is null, else false
*/
bool isNull ( ) const { PIMM_FOR_WB ( r , c ) if ( m [ r ] [ c ] ! = Type ( 0 ) ) return false ; return true ; }
/**
* @brief Full access to elements reference by row "row" and col "col"
*
* @param row is a parameter that shows the row number of the matrix of the selected element
* @param col is a parameter that shows the column number of the matrix of the selected element
* @return reference to element of matrix by row "row" and col "col"
*/
Type & at ( uint row , uint col ) { return m [ row ] [ col ] ; }
/**
* @brief Full access to element by row "row" and col "col"
*
* @param row is a parameter that shows the row number of the matrix of the selected element
* @param col is a parameter that shows the column number of the matrix of the selected element
* @return element of matrix by row "row" and col "col"
*/
Type at ( uint row , uint col ) const { return m [ row ] [ col ] ; }
/**
* @brief Full access to the matrix row pointer
*
* @param row is a row of necessary matrix
* @return matrix row pointer
*/
Type * operator [ ] ( uint row ) { return m [ row ] ; }
/**
* @brief Read-only access to the matrix row pointer
*
* @param row is a row of necessary matrix
* @return matrix row pointer
*/
const Type * operator [ ] ( uint row ) const { return m [ row ] ; }
/**
* @brief Matrix assignment to matrix "sm"
*
* @param sm matrix for the assigment
* @return matrix equal with sm
*/
_CMatrix & operator = ( const _CMatrix & sm ) { memcpy ( m , sm . m , sizeof ( Type ) * Cols * Rows ) ; return * this ; }
/**
* @brief Compare with matrix "sm"
*
* @param sm matrix for the compare
* @return if matrices are equal true, else false
*/
bool operator = = ( const _CMatrix & sm ) const { PIMM_FOR_WB ( r , c ) if ( m [ r ] [ c ] ! = sm . m [ r ] [ c ] ) return false ; return true ; }
/**
* @brief Compare with matrix "sm"
*
* @param sm matrix for the compare
* @return if matrices are not equal true, else false
*/
bool operator ! = ( const _CMatrix & sm ) const { return ! ( * this = = sm ) ; }
/**
* @brief Addition assignment with matrix "sm"
*
* @param sm matrix for the addition assigment
*/
void operator + = ( const _CMatrix & sm ) { PIMM_FOR_WB ( r , c ) m [ r ] [ c ] + = sm . m [ r ] [ c ] ; }
/**
* @brief Subtraction assignment with matrix "sm"
*
* @param sm matrix for the subtraction assigment
*/
void operator - = ( const _CMatrix & sm ) { PIMM_FOR_WB ( r , c ) m [ r ] [ c ] - = sm . m [ r ] [ c ] ; }
/**
* @brief Multiplication assignment with value "v"
*
* @param v value for the multiplication assigment
*/
void operator * = ( const Type & v ) { PIMM_FOR_WB ( r , c ) m [ r ] [ c ] * = v ; }
/**
* @brief Division assignment with value "v"
*
* @param v value for the division assigment
*/
void operator / = ( const Type & v ) { PIMM_FOR_WB ( r , c ) m [ r ] [ c ] / = v ; }
/**
* @brief Matrix substraction
*
* @return the result of matrix substraction
*/
_CMatrix operator - ( ) const { _CMatrix tm ; PIMM_FOR_WB ( r , c ) tm . m [ r ] [ c ] = - m [ r ] [ c ] ; return tm ; }
/**
* @brief Matrix addition
*
* @param sm is matrix term
* @return the result of matrix addition
*/
_CMatrix operator + ( const _CMatrix & sm ) const { _CMatrix tm = _CMatrix ( * this ) ; PIMM_FOR_WB ( r , c ) tm . m [ r ] [ c ] + = sm . m [ r ] [ c ] ; return tm ; }
/**
* @brief Matrix substraction
*
* @param sm is matrix subtractor
* @return the result of matrix substraction
*/
_CMatrix operator - ( const _CMatrix & sm ) const { _CMatrix tm = _CMatrix ( * this ) ; PIMM_FOR_WB ( r , c ) tm . m [ r ] [ c ] - = sm . m [ r ] [ c ] ; return tm ; }
/**
* @brief Matrix multiplication
*
* @param v is value factor
* @return the result of matrix multiplication
*/
_CMatrix operator * ( const Type & v ) const { _CMatrix tm = _CMatrix ( * this ) ; PIMM_FOR_WB ( r , c ) tm . m [ r ] [ c ] * = v ; return tm ; }
/**
* @brief Matrix division
*
* @param v is value divider
* @return the result of matrix division
*/
_CMatrix operator / ( const Type & v ) const { _CMatrix tm = _CMatrix ( * this ) ; PIMM_FOR_WB ( r , c ) tm . m [ r ] [ c ] / = v ; return tm ; }
/**
* @brief Determinant of the matrix is calculated
*
* @return matrix determinant
*/
Type determinant ( bool * ok = 0 ) const {
_CMatrix m ( * this ) ;
bool k ;
@@ -122,6 +381,11 @@ public:
return ret ;
}
/**
* @brief Transforming matrix to upper triangular
*
* @return transformed upper triangular matrix
*/
_CMatrix & toUpperTriangular ( bool * ok = 0 ) {
if ( Cols ! = Rows ) {
if ( ok ! = 0 ) * ok = false ;
@@ -159,6 +423,11 @@ public:
return * this ;
}
/**
* @brief Matrix inversion operation
*
* @return inverted matrix
*/
_CMatrix & invert ( bool * ok = 0 ) {
static_assert ( Cols = = Rows , " Only square matrix invertable " ) ;
_CMatrix mtmp = _CMatrix : : identity ( ) , smat ( * this ) ;
@@ -206,7 +475,19 @@ public:
memcpy ( m , mtmp . m , sizeof ( Type ) * Cols * Rows ) ;
return * this ;
}
/**
* @brief Matrix inversion operation
*
* @return inverted matrix
*/
_CMatrix inverted ( bool * ok = 0 ) const { _CMatrix tm ( * this ) ; tm . invert ( ok ) ; return tm ; }
/**
* @brief Matrix transposition operation
*
* @return transposed matrix
*/
_CMatrixI transposed ( ) const { _CMatrixI tm ; PIMM_FOR_WB ( r , c ) tm [ c ] [ r ] = m [ r ] [ c ] ; return tm ; }
private :
@@ -321,6 +602,7 @@ class PIMathMatrix;
# define PIMM_FOR_C(v) for (uint v = 0; v < _V2D::cols_; ++v)
# define PIMM_FOR_R(v) for (uint v = 0; v < _V2D::rows_; ++v)
//! \brief A class that works with matrix operations, the input data of which is the data type of the matrix
template < typename Type >
class PIP_EXPORT PIMathMatrix : public PIVector2D < Type > {
typedef PIVector2D < Type > _V2D ;
@@ -332,33 +614,199 @@ public:
PIMathMatrix ( const PIVector < PIVector < Type > > & val ) { if ( ! val . isEmpty ( ) ) { _V2D : : resize ( val . size ( ) , val [ 0 ] . size ( ) ) ; PIMM_FOR_I ( c , r ) _V2D : : element ( r , c ) = val [ r ] [ c ] ; } }
PIMathMatrix ( const PIVector2D < Type > & val ) { if ( ! val . isEmpty ( ) ) { _V2D : : resize ( val . rows ( ) , val . cols ( ) ) ; PIMM_FOR_I ( c , r ) _V2D : : element ( r , c ) = val . element ( r , c ) ; } }
/**
* @brief С reates a matrix whose main diagonal is filled with ones and the remaining elements are zeros
*
* @param cols is number of matrix column uint type
* @param rows is number of matrix row uint type
* @return identitied matrix of type PIMathMatrix
*/
static _CMatrix identity ( const uint cols , const uint rows ) { _CMatrix tm ( cols , rows ) ; for ( uint r = 0 ; r < rows ; + + r ) for ( uint c = 0 ; c < cols ; + + c ) tm . element ( r , c ) = ( c = = r ? Type ( 1 ) : Type ( 0 ) ) ; return tm ; }
static _CMatrix matrixRow ( const PIMathVector < Type > & val ) { return _CMatrix ( val . size ( ) , 1 , val . toVector ( ) ) ; }
/**
* @brief С reates a matrix whose row equal to vector
*
* @param val is the vector type PIMathVector
* @return matrix identitied by vector
*/
static _CMatrix matrixRow ( const PIMathVector < Type > & val ) { return _CMatrix ( val . size ( ) , 1 , val . toVector ( ) ) ; }
/**
* @brief С reates a matrix whose column equal to vector
*
* @param val is the vector type PIMathVector
* @return matrix identitied by vector
*/
static _CMatrix matrixCol ( const PIMathVector < Type > & val ) { return _CMatrix ( 1 , val . size ( ) , val . toVector ( ) ) ; }
/**
* @brief Set the selected column in matrix
*
* @param index is the number of the selected column
* @param v is a vector of the type _CMCol that needs to fill the column
* @return matrix type _CMatrix
*/
_CMatrix & setCol ( uint index , const _CMCol & v ) { PIMM_FOR_R ( i ) _V2D : : element ( i , index ) = v [ i ] ; return * this ; }
/**
* @brief Set the selected row in matrix
*
* @param index is the number of the selected row
* @param v is a vector of the type _CMCol that needs to fill the row
* @return matrix type _CMatrix
*/
_CMatrix & setRow ( uint index , const _CMCol & v ) { PIMM_FOR_C ( i ) _V2D : : element ( index , i ) = v [ i ] ; return * this ; }
/**
* @brief Method which changes selected rows in a matrix
*
* @param r0 is the number of the first selected row
* @param r1 is the number of the second selected row
* @return matrix type _CMatrix
*/
_CMatrix & swapCols ( uint r0 , uint r1 ) { PIMM_FOR_C ( i ) { piSwap ( _V2D : : element ( i , r0 ) , _V2D : : element ( i , r1 ) ) ; } return * this ; }
/**
* @brief Method which changes selected columns in a matrix
*
* @param c0 is the number of the first selected column
* @param c1 is the number of the second selected column
* @return matrix type _CMatrix
*/
_CMatrix & swapRows ( uint c0 , uint c1 ) { PIMM_FOR_R ( i ) { piSwap ( _V2D : : element ( c0 , i ) , _V2D : : element ( c1 , i ) ) ; } return * this ; }
/**
* @brief Method which fills the matrix with selected value
*
* @param v is a parameter the type and value of which is selected and later filled into the matrix
* @return filled matrix type _CMatrix
*/
_CMatrix & fill ( const Type & v ) { PIMM_FOR_A ( i ) _V2D : : mat [ i ] = v ; return * this ; }
/**
* @brief Method which checks if matrix is square
*
* @return true if matrix is square, else false
*/
bool isSquare ( ) const { return _V2D : : cols_ = = _V2D : : rows_ ; }
/**
* @brief Method which checks if main diagonal of matrix consists of ones and another elements are zeros
*
* @return true if matrix is identitied, else false
*/
bool isIdentity ( ) const { PIMM_FOR ( c , r ) if ( ( c = = r ) ? _V2D : : element ( r , c ) ! = Type ( 1 ) : _V2D : : element ( r , c ) ! = Type ( 0 ) ) return false ; return true ; }
/**
* @brief Method which checks if every elements of matrix are zeros
*
* @return true if matrix is null, else false
*/
bool isNull ( ) const { PIMM_FOR_A ( i ) if ( _V2D : : mat [ i ] ! = Type ( 0 ) ) return false ; return true ; }
/**
* @brief Method which checks if matrix is empty
*
* @return true if matrix is valid, else false
*/
bool isValid ( ) const { return ! PIVector2D < Type > : : isEmpty ( ) ; }
/**
* @brief Matrix assignment to matrix "v"
*
* @param v matrix for the assigment
* @return matrix equal with v
*/
_CMatrix & operator = ( const PIVector < PIVector < Type > > & v ) { * this = _CMatrix ( v ) ; return * this ; }
/**
* @brief Compare with matrix "sm"
*
* @param sm matrix for the compare
* @return if matrices are equal true, else false
*/
bool operator = = ( const _CMatrix & sm ) const { PIMM_FOR_A ( i ) if ( _V2D : : mat [ i ] ! = sm . mat [ i ] ) return false ; return true ; }
/**
* @brief Compare with matrix "sm"
*
* @param sm matrix for the compare
* @return if matrices are not equal true, else false
*/
bool operator ! = ( const _CMatrix & sm ) const { return ! ( * this = = sm ) ; }
/**
* @brief Addition assignment with matrix "sm"
*
* @param sm matrix for the addition assigment
*/
void operator + = ( const _CMatrix & sm ) { PIMM_FOR_A ( i ) _V2D : : mat [ i ] + = sm . mat [ i ] ; }
/**
* @brief Subtraction assignment with matrix "sm"
*
* @param sm matrix for the subtraction assigment
*/
void operator - = ( const _CMatrix & sm ) { PIMM_FOR_A ( i ) _V2D : : mat [ i ] - = sm . mat [ i ] ; }
/**
* @brief Multiplication assignment with value "v"
*
* @param v value for the multiplication assigment
*/
void operator * = ( const Type & v ) { PIMM_FOR_A ( i ) _V2D : : mat [ i ] * = v ; }
/**
* @brief Division assignment with value "v"
*
* @param v value for the division assigment
*/
void operator / = ( const Type & v ) { PIMM_FOR_A ( i ) _V2D : : mat [ i ] / = v ; }
/**
* @brief Matrix substraction
*
* @return the result of matrix substraction
*/
_CMatrix operator - ( ) const { _CMatrix tm ( * this ) ; PIMM_FOR_A ( i ) tm . mat [ i ] = - _V2D : : mat [ i ] ; return tm ; }
/**
* @brief Matrix addition
*
* @param sm is matrix term
* @return the result of matrix addition
*/
_CMatrix operator + ( const _CMatrix & sm ) const { _CMatrix tm ( * this ) ; PIMM_FOR_A ( i ) tm . mat [ i ] + = sm . mat [ i ] ; return tm ; }
/**
* @brief Matrix substraction
*
* @param sm is matrix subtractor
* @return the result of matrix substraction
*/
_CMatrix operator - ( const _CMatrix & sm ) const { _CMatrix tm ( * this ) ; PIMM_FOR_A ( i ) tm . mat [ i ] - = sm . mat [ i ] ; return tm ; }
/**
* @brief Matrix multiplication
*
* @param v is value factor
* @return the result of matrix multiplication
*/
_CMatrix operator * ( const Type & v ) const { _CMatrix tm ( * this ) ; PIMM_FOR_A ( i ) tm . mat [ i ] * = v ; return tm ; }
/**
* @brief Matrix division
*
* @param v is value divider
* @return the result of matrix division
*/
_CMatrix operator / ( const Type & v ) const { _CMatrix tm ( * this ) ; PIMM_FOR_A ( i ) tm . mat [ i ] / = v ; return tm ; }
/**
* @brief Determinant of the matrix is calculated
*
* @return matrix determinant
*/
Type determinant ( bool * ok = 0 ) const {
_CMatrix m ( * this ) ;
bool k ;
@@ -374,6 +822,11 @@ public:
return ret ;
}
/**
* @brief Trace of the matrix is calculated
*
* @return matrix trace
*/
Type trace ( bool * ok = 0 ) const {
Type ret = Type ( 0 ) ;
if ( ! isSquare ( ) ) {
@@ -387,6 +840,11 @@ public:
return ret ;
}
/**
* @brief Transforming matrix to upper triangular
*
* @return transformed upper triangular matrix
*/
_CMatrix & toUpperTriangular ( bool * ok = 0 ) {
if ( ! isSquare ( ) ) {
if ( ok ! = 0 ) * ok = false ;
@@ -424,6 +882,11 @@ public:
return * this ;
}
/**
* @brief Matrix inversion operation
*
* @return inverted matrix
*/
_CMatrix & invert ( bool * ok = 0 , _CMCol * sv = 0 ) {
if ( ! isSquare ( ) ) {
if ( ok ! = 0 ) * ok = false ;
@@ -478,7 +941,19 @@ public:
PIVector2D < Type > : : swap ( mtmp ) ;
return * this ;
}
/**
* @brief Matrix inversion operation
*
* @return inverted matrix
*/
_CMatrix inverted ( bool * ok = 0 ) const { _CMatrix tm ( * this ) ; tm . invert ( ok ) ; return tm ; }
/**
* @brief Matrix transposition operation
*
* @return transposed matrix
*/
_CMatrix transposed ( ) const { _CMatrix tm ( _V2D : : rows_ , _V2D : : cols_ ) ; PIMM_FOR ( c , r ) tm . element ( c , r ) = _V2D : : element ( r , c ) ; return tm ; }
} ;