@@ -53,20 +53,15 @@ class PIP_EXPORT PIMathMatrixT {
static_assert ( Cols > 0 , " Column count must be > 0 " ) ;
public :
/**
* @brief Constructor that calls the private resize method
*
* @return identitied matrix of type PIMathMatrixT
* @brief Constructs PIMa thM atrixT that is filled by \a new_value
*/
PIMathMatrixT ( ) { resize ( Rows , Cols ) ; }
PIMathMatrixT ( const Type & new_value = Type ( ) ) { PIMM_FOR m [ r ] [ c ] = new_value ; }
/**
* @brief Cons tructor that calls the private resize method
*
* @param val is the PIVector with which the matrix is filled
* @return identitied matrix of type PIMathMatrixT
* @brief Contructs PIMathMatrixT from PIVector
*/
PIMathMatrixT ( const PIVector < Type > & val ) {
resize ( Rows , Cols ) ;
assert ( Rows * Cols = = val . size ( ) ) ;
int i = 0 ;
PIMM_FOR m [ r ] [ c ] = val [ i + + ] ;
}
@@ -91,31 +86,19 @@ public:
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 tm . m [ r ] [ c ] = v ;
return tm ;
}
/**
* @brief Method which returns number of columns in matrix
*
* @return type uint shows number of columns
*/
uint cols ( ) const { return Cols ; }
constexpr 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 ; }
constexpr uint rows ( ) const { return Rows ; }
/**
* @brief Method which returns the selected column in PIMathVectorT format.
@@ -177,13 +160,8 @@ public:
* @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 {
t = m [ r0 ] [ i ] ;
m [ r0 ] [ i ] = m [ r1 ] [ i ] ;
m [ r1 ] [ i ] = t ;
}
_CMatrix & swapRows ( uint rf , uint rs ) {
PIMM_FOR_C piSwap < Type > ( m [ rf ] [ i ] , m [ rs ] [ i ] ) ;
return * this ;
}
@@ -195,13 +173,8 @@ public:
* @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 {
t = m [ i ] [ c0 ] ;
m [ i ] [ c0 ] = m [ i ] [ c1 ] ;
m [ i ] [ c1 ] = t ;
}
_CMatrix & swapCols ( uint cf , uint cs ) {
PIMM_FOR_R piSwap < Type > ( m [ i ] [ cf ] , m [ i ] [ cs ] ) ;
return * this ;
}
@@ -221,7 +194,7 @@ public:
*
* @return true if matrix is square, else false
*/
bool isSquare ( ) const { return cols ( ) = = rows ( ) ; }
constexpr bool isSquare ( ) const { return Rows = = Cols ; }
/**
* @brief Method which checks if main diagonal of matrix consists of ones and another elements are zeros
@@ -243,30 +216,41 @@ public:
return true ;
}
/**
* @brief Full access to elements reference by row "row" and col "col".
* If you enter an index out of the border of the matrix there will be "undefined behavior"
*
* @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" .
* @brief Read-only access to element by \a row and \a col.
* If you enter an index out of the border of the matrix there will be "undefined behavior"
*
* @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"
* @param row of matrix
* @param col of matrix
* @return copy of element of matrix
*/
Type at ( uint row , uint col ) const { return m [ row ] [ col ] ; }
/**
* @brief Full access to element by \a row and \a col.
* If you enter an index out of the border of the matrix there will be "undefined behavior"
*
* @param row of matrix
* @param col of matrix
* @return element of matrix
*/
inline Type & element ( uint row , uint col ) { return m [ row ] [ col ] ; }
/**
* @brief Read-only access to element by \a row and \a col.
* If you enter an index out of the border of the matrix there will be "undefined behavior"
*
* @param row of matrix
* @param col of matrix
* @return element of matrix
*/
inline const Type & element ( uint row , uint col ) const { return m [ row ] [ col ] ; }
/**
* @brief Full access to the matrix row pointer. If you enter an index out of the border of the matrix there will be "undefined behavior"
*
* @param row is a row of necessary matrix
* @param row of matrix
* @return matrix row pointer
*/
Type * operator [ ] ( uint row ) { return m [ row ] ; }
@@ -274,26 +258,15 @@ public:
/**
* @brief Read-only access to the matrix row pointer. If you enter an index out of the border of the matrix there will be "undefined behavior"
*
* @param row is a row of necessary matrix
* @param row of matrix
* @return matrix row pointer
*/
const Type * operator [ ] ( uint row ) const { return m [ row ] ; }
/**
* @brief Matrix assignment to matrix "sm"
* @brief Matrix compare
*
* @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
* @param sm matrix for compare
* @return if matrices are equal true, else false
*/
bool operator = = ( const _CMatrix & sm ) const {
@@ -302,9 +275,9 @@ public:
}
/**
* @brief Compare with matrix "sm"
* @brief Matrix negative compare
*
* @param sm matrix for the compare
* @param sm matrix for compare
* @return if matrices are not equal true, else false
*/
bool operator ! = ( const _CMatrix & sm ) const { return ! ( * this = = sm ) ; }
@@ -328,14 +301,19 @@ public:
*
* @param v value for the multiplication assigment
*/
void operator * = ( const Type & v ) { PIMM_FOR m [ r ] [ c ] * = v ; }
void operator * = ( const Type & v ) {
PIMM_FOR m [ r ] [ c ] * = v ;
}
/**
* @brief Division assignment with value "v"
*
* @param v value for the division assigment
*/
void operator / = ( const Type & v ) { PIMM_FOR m [ r ] [ c ] / = v ; }
void operator / = ( const Type & v ) {
assert ( piAbs < Type > ( v ) > PIMATHVECTOR_ZERO_CMP ) ;
PIMM_FOR m [ r ] [ c ] / = v ;
}
/**
* @brief Matrix substraction
@@ -391,6 +369,7 @@ public:
* @return the result of matrix division
*/
_CMatrix operator / ( const Type & v ) const {
assert ( piAbs < Type > ( v ) > PIMATHVECTOR_ZERO_CMP ) ;
_CMatrix tm = _CMatrix ( * this ) ;
PIMM_FOR tm . m [ r ] [ c ] / = v ;
return tm ;
@@ -446,7 +425,7 @@ public:
for ( uint k = i ; k < Cols ; + + k ) smat . m [ k ] [ j ] - = mul * smat . m [ k ] [ i ] ;
}
if ( i < Cols - 1 ) {
if ( fabs ( smat . m [ i + 1 ] [ i + 1 ] ) < Type ( 1E-200 ) ) {
if ( piAbs < Type > ( smat . m [ i + 1 ] [ i + 1 ] ) < Type ( 1E-200 ) ) {
if ( ok ! = 0 ) * ok = false ;
return * this ;
}
@@ -490,7 +469,7 @@ public:
for ( uint k = 0 ; k < Cols ; + + k ) mtmp . m [ k ] [ j ] - = mul * mtmp . m [ k ] [ i ] ;
}
if ( i < Cols - 1 ) {
if ( fabs ( smat . m [ i + 1 ] [ i + 1 ] ) < Type ( 1E-200 ) ) {
if ( piAbs < Type > ( smat . m [ i + 1 ] [ i + 1 ] ) < Type ( 1E-200 ) ) {
if ( ok ! = 0 ) * ok = false ;
return * this ;
}
@@ -534,23 +513,25 @@ public:
return tm ;
}
private :
void resize ( uint rows_ , uint c ols_ , const Type & new_value = Type ( ) ) {
r_ = rows_ ;
c_ = cols_ ;
PIMM_FOR m [ r ] [ c ] = new_value ;
_CMatrix rotate ( Type angle ) {
static_assert ( Rows = = 2 & & C ols = = 2 , " Works only with 2x2 matrix " ) ;
Type c = std : : cos ( angle ) ;
Type s = std : : sin ( angle ) ;
PIMathMatrixT < 2u , 2u > tm ;
tm [ 0 ] [ 0 ] = tm [ 1 ] [ 1 ] = c ;
tm [ 0 ] [ 1 ] = - s ;
tm [ 1 ] [ 0 ] = s ;
* this = * this * tm ;
return * this ;
}
int c_ , r_ ;
private :
Type m [ Rows ] [ Cols ] ;
} ;
# pragma pack(pop)
# ifdef PIP_STD_IOSTREAM
template < uint Rows , uint Cols , typename Type >
inline std : : ostream & operator < < ( std : : ostream & s , const PIMathMatrixT < Rows , Cols , Type > & m ) {
@@ -687,11 +668,10 @@ class PIMathMatrix;
/// Matrix
# define PIMM_FOR(c, r) for (uint c = 0; c < _V2D::col s_; ++c ) for (uint r = 0; r < _V2D::row s_; ++r )
# define PIMM_FOR_I(c, r) for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_ ; ++c )
# define PIMM_FOR_A(v) for (uint v = 0; v < _V2D::mat.size() ; ++v )
# define PIMM_FOR_C(v) for (uint v = 0; v < _V2D::col s_; ++v )
# define PIMM_FOR_R(v) for (uint v = 0; v < _V2D::rows_; ++v)
# define PIMM_FOR for (uint r = 0; r < _V2D::row s_; ++r ) for (uint c = 0; c < _V2D::col s_; ++c )
# define PIMM_FOR_A for (uint i = 0; i < _V2D::mat.size() ; ++i )
# define PIMM_FOR_C for (uint i = 0; i < _V2D::cols_ ; ++i )
# define PIMM_FOR_R for (uint i = 0; i < _V2D::row s_; ++i )
//! \brief A class that works with matrix operations, the input data of which is the data type of the matrix
//! @tparam There are can be basic C++ language data and different classes where the arithmetic operators(=, +=, -=, *=, /=, ==, !=, +, -, *, /)
@@ -700,7 +680,6 @@ template<typename Type>
class PIP_EXPORT PIMathMatrix : public PIVector2D < Type > {
typedef PIVector2D < Type > _V2D ;
typedef PIMathMatrix < Type > _CMatrix ;
typedef PIMathVector < Type > _CMCol ;
public :
/**
* @brief Constructor of class PIMathMatrix, which creates a matrix
@@ -721,7 +700,7 @@ public:
PIMathMatrix ( const uint cols , const uint rows , const PIVector < Type > & val ) {
_V2D : : resize ( rows , cols ) ;
int i = 0 ;
PIMM_FOR_I ( c , r ) _V2D : : element ( r , c ) = val [ i + + ] ;
PIMM_FOR _V2D : : element ( r , c ) = val [ i + + ] ;
}
/**
@@ -732,7 +711,11 @@ 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 ] ;
for ( uint r = 0 ; r < _V2D : : rows_ ; + + r ) {
assert ( val [ r ] . size ( ) = = _V2D : : cols_ ) ;
for ( uint c = 0 ; c < _V2D : : cols_ ; + + c )
_V2D : : element ( r , c ) = val [ r ] [ c ] ;
}
}
}
@@ -744,7 +727,7 @@ public:
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 ) ;
PIMM_FOR _V2D : : element ( r , c ) = val . element ( r , c ) ;
}
}
@@ -761,19 +744,6 @@ public:
return tm ;
}
/**
* @brief Creates a matrix filled by zeros
*
* @param cols is number of matrix column uint type
* @param rows is number of matrix row uint type
* @return zero matrix(cols,rows)
*/
static _CMatrix zero ( const uint cols , const uint rows ) {
_CMatrix tm ( cols , rows ) ;
tm . fill ( Type ( 0 ) ) ;
return tm ;
}
/**
* @brief Creates a row matrix of every element that is equal to every element of the vector
*
@@ -798,8 +768,9 @@ public:
* @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 ] ;
_CMatrix & setCol ( uint index , const PIMathVector < Type > & v ) {
assert ( _V2D : : rows = = v . size ( ) ) ;
PIMM_FOR_R _V2D : : element ( i , index ) = v [ i ] ;
return * this ;
}
@@ -810,8 +781,9 @@ public:
* @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 ] ;
_CMatrix & setRow ( uint index , const PIMathVector < Type > & v ) {
assert ( _V2D : : cols = = v . size ( ) ) ;
PIMM_FOR_C _V2D : : element ( index , i ) = v [ i ] ;
return * this ;
}
@@ -824,7 +796,7 @@ public:
* @return matrix type _CMatrix
*/
_CMatrix & swapCols ( uint r0 , uint r1 ) {
PIMM_FOR_C( i ) { piSwap ( _V2D : : element ( i , r0 ) , _V2D : : element ( i , r1 ) ) ; }
PIMM_FOR_C piSwap < Type > ( _V2D : : element ( i , r0 ) , _V2D : : element ( i , r1 ) ) ;
return * this ;
}
@@ -837,7 +809,7 @@ public:
* @return matrix type _CMatrix
*/
_CMatrix & swapRows ( uint c0 , uint c1 ) {
PIMM_FOR_R( i ) { piSwap ( _V2D : : element ( c0 , i ) , _V2D : : element ( c1 , i ) ) ; }
PIMM_FOR_R piSwap ( _V2D : : element ( c0 , i ) , _V2D : : element ( c1 , i ) ) ;
return * this ;
}
@@ -848,7 +820,7 @@ public:
* @return filled matrix type _CMatrix
*/
_CMatrix & fill ( const Type & v ) {
PIMM_FOR_A( i ) _V2D : : mat [ i ] = v ;
PIMM_FOR_A _V2D : : mat [ i ] = v ;
return * this ;
}
@@ -865,7 +837,7 @@ public:
* @return true if matrix is identity, 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 ;
PIMM_FOR if ( ( c = = r ) ? _V2D : : element ( r , c ) ! = Type ( 1 ) : _V2D : : element ( r , c ) ! = Type ( 0 ) ) return false ;
return true ;
}
@@ -875,7 +847,7 @@ public:
* @return true if matrix elements equal to zero, else false
*/
bool isNull ( ) const {
PIMM_FOR_A( i ) if ( _V2D : : mat [ i ] ! = Type ( 0 ) ) return false ;
PIMM_FOR_A if ( _V2D : : mat [ i ] ! = Type ( 0 ) ) return false ;
return true ;
}
@@ -894,7 +866,7 @@ public:
void operator + = ( const _CMatrix & sm ) {
assert ( _V2D : : rows ( ) = = sm . rows ( ) ) ;
assert ( _V2D : : cols ( ) = = sm . cols ( ) ) ;
PIMM_FOR_A( i ) _V2D : : mat [ i ] + = sm . mat [ i ] ;
PIMM_FOR_A _V2D : : mat [ i ] + = sm . mat [ i ] ;
}
/**
@@ -905,7 +877,7 @@ public:
void operator - = ( const _CMatrix & sm ) {
assert ( _V2D : : rows ( ) = = sm . rows ( ) ) ;
assert ( _V2D : : cols ( ) = = sm . cols ( ) ) ;
PIMM_FOR_A( i ) _V2D : : mat [ i ] - = sm . mat [ i ] ;
PIMM_FOR_A _V2D : : mat [ i ] - = sm . mat [ i ] ;
}
/**
@@ -913,14 +885,19 @@ public:
*
* @param v value for the multiplication assigment
*/
void operator * = ( const Type & v ) { PIMM_FOR_A ( i ) _V2D : : mat [ i ] * = v ; }
void operator * = ( const Type & v ) {
PIMM_FOR_A _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 ; }
void operator / = ( const Type & v ) {
assert ( piAbs < Type > ( v ) > PIMATHVECTOR_ZERO_CMP ) ;
PIMM_FOR_A _V2D : : mat [ i ] / = v ;
}
/**
* @brief Matrix substraction
@@ -929,7 +906,7 @@ public:
*/
_CMatrix operator - ( ) const {
_CMatrix tm ( * this ) ;
PIMM_FOR_A( i ) tm . mat [ i ] = - _V2D : : mat [ i ] ;
PIMM_FOR_A tm . mat [ i ] = - _V2D : : mat [ i ] ;
return tm ;
}
@@ -943,7 +920,7 @@ public:
_CMatrix tm ( * this ) ;
assert ( tm . rows ( ) = = sm . rows ( ) ) ;
assert ( tm . cols ( ) = = sm . cols ( ) ) ;
PIMM_FOR_A( i ) tm . mat [ i ] + = sm . mat [ i ] ;
PIMM_FOR_A tm . mat [ i ] + = sm . mat [ i ] ;
return tm ;
}
@@ -957,7 +934,7 @@ public:
_CMatrix tm ( * this ) ;
assert ( tm . rows ( ) = = sm . rows ( ) ) ;
assert ( tm . cols ( ) = = sm . cols ( ) ) ;
PIMM_FOR_A( i ) tm . mat [ i ] - = sm . mat [ i ] ;
PIMM_FOR_A tm . mat [ i ] - = sm . mat [ i ] ;
return tm ;
}
@@ -969,7 +946,7 @@ public:
*/
_CMatrix operator * ( const Type & v ) const {
_CMatrix tm ( * this ) ;
PIMM_FOR_A( i ) tm . mat [ i ] * = v ;
PIMM_FOR_A tm . mat [ i ] * = v ;
return tm ;
}
@@ -980,8 +957,9 @@ public:
* @return the result of matrix division
*/
_CMatrix operator / ( const Type & v ) const {
assert ( piAbs < Type > ( v ) > PIMATHVECTOR_ZERO_CMP ) ;
_CMatrix tm ( * this ) ;
PIMM_FOR_A( i ) tm . mat [ i ] / = v ;
PIMM_FOR_A tm . mat [ i ] / = v ;
return tm ;
}
@@ -1075,7 +1053,7 @@ public:
* @param sv is a vector multiplier
* @return copy of inverted matrix
*/
_CMatrix & invert ( bool * ok = 0 , _CMCol * sv = 0 ) {
_CMatrix & invert ( bool * ok = 0 , PIMathVector < Type > * sv = 0 ) {
if ( ! isSquare ( ) ) {
if ( ok ! = 0 ) * ok = false ;
return * this ;
@@ -1149,7 +1127,7 @@ public:
*/
_CMatrix transposed ( ) const {
_CMatrix tm ( _V2D : : rows_ , _V2D : : cols_ ) ;
PIMM_FOR( c , r ) tm . element ( c , r ) = _V2D : : element ( r , c ) ;
PIMM_FOR tm . element ( c , r ) = _V2D : : element ( r , c ) ;
return tm ;
}
} ;
@@ -1309,7 +1287,6 @@ PIMathMatrix<complex<T> > hermitian(const PIMathMatrix<complex<T> > &m) {
}
# undef PIMM_FOR
# undef PIMM_FOR_I
# undef PIMM_FOR_A
# undef PIMM_FOR_C
# undef PIMM_FOR_R