1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
#include <iostream>
#include <iomanip>
#include <complex>
template< typename T > struct Matrix44
{
// inplicitly defaulted default consteructor
static constexpr std::size_t N = 4 ;
using row_type = T[N] ; // a row is an array of N T
row_type& operator[] ( std::size_t row_num ) noexcept { return m[row_num] ; }
const row_type& operator[] ( std::size_t row_num ) const noexcept { return m[row_num] ; }
T m[N][N] {} ; // initialise to all T{}
// note: within the class template definition, the template name Matrix44 (without any template arguments)
// means Matrix44<T> (in jargon, this is known as 'the injected-class-name)
// the following line is equivalent to: static Matrix44<T> identity() // return an identity matrix
static Matrix44 identity() // return an identity matrix
{
return
{
{
{ T{1}, T{}, T{}, T{} },
{ T{}, T{1}, T{}, T{} },
{ T{}, T{}, T{1}, T{} },
{ T{}, T{}, T{}, T{1} }
}
};
}
// overloaded as a non member function
/* note: to overload as a member function, declare
Matrix44 operator* ( const Matrix44& b ) const
and change 'a' to '(*this)': result[i][j] += (*this)[i][k] * b[k][j]; */
friend Matrix44 operator* ( const Matrix44& a, const Matrix44& b )
{
Matrix44 result ; // note: initialised to all zeroes
for( std::size_t i = 0 ; i<N ; ++i )
for( std::size_t j = 0 ; j<N ; ++j )
for( std::size_t k = 0 ; k<N ; ++k )
result[i][j] += a[i][k] * b[k][j];
return result ;
}
friend std::ostream& operator<< ( std::ostream& stm, const Matrix44& mtx )
{
for( std::size_t i = 0 ; i < N ; ++i )
{
// warning: hard-coded std::setw(16) for brevity
for( const auto& v : mtx[i] ) stm << std::setw(16) << v ;
stm << '\n' ;
}
return stm ;
}
};
int main()
{
std::ios_base::Init init{} ;
// note: { { {}, {}, {}, {}, } }
const Matrix44<double> a { { { 1,2,3,4 }, { 5,6,7,8 }, { 9,10,11,12 }, { 13,14,15,16 } } } ;
std::cout << a << '\n' ;
std::cout << a * Matrix44<double>::identity() << '\n' ; // multiply with identity matrix
std::cout << a*a << '\n' ; // multiply with itself
Matrix44< std::complex<double> > b { { { 1,2,3,4 }, { 5,6,7,8 }, { 9,10,11,12 }, { 13,14,15,16 } } } ;
using namespace std::literals ;
for( std::size_t i = 0 ; i < b.N ; ++i ) for( auto& cmplx : b[i] ) cmplx += 0.1i ;
std::cout << b << '\n' ;
std::cout << b * Matrix44< std::complex<double> >::identity() << '\n' ; // multiply with identity matrix
std::cout << b*b << '\n' ; // multiply with itself
}
|