Advertisement
Guest User

Untitled

a guest
Sep 14th, 2015
414
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.74 KB | None | 0 0
  1. #ifndef _MATRIX_h_
  2.  
  3. #define _MATRIX_h_
  4.  
  5. #ifdef _MSC_VER
  6. #pragma once
  7. #endif
  8.  
  9. #include <array>
  10. #include <string>
  11. #include <type_traits>
  12. #include <iostream>
  13.  
  14. template < typename T, size_t ROWS, size_t COLS >
  15. class Matrix
  16. {
  17. private:
  18.     std::array< T, ROWS* COLS > m_cValues;
  19.  
  20. public:
  21.     Matrix( void )
  22.     {
  23.         static_assert( std::is_arithmetic< T >::value, "Type T has to be arithmetic!" );
  24.         static_assert( ROWS >= 1 && COLS >= 1, "Minimal row and col dimensions are 1." );
  25.         m_cValues.fill( static_cast<T>( 0 ) );
  26.     }
  27.  
  28.     ~Matrix( )
  29.     {
  30.     }
  31.  
  32.     explicit Matrix( std::array< T, ( ROWS* COLS ) > cValues )
  33.         : m_cValues( cValues )
  34.     {
  35.         static_assert( std::is_arithmetic< T >::value, "Type T has to be arithmetic!" );
  36.     }
  37.  
  38.     template < typename... K >
  39.     Matrix( K ... args )
  40.     {
  41.         static_assert( std::is_arithmetic< T >::value, "Type T has to be arithmetic!" );
  42.         m_cValues = std::array< T, ROWS* COLS > { static_cast<T>( args )... };
  43.     }
  44.  
  45.     constexpr static auto rows( void ) -> size_t
  46.     {
  47.         return ROWS;
  48.     }
  49.  
  50.     constexpr static auto cols( void ) -> size_t
  51.     {
  52.         return COLS;
  53.     }
  54.  
  55.     constexpr static auto size( void ) -> size_t
  56.     {
  57.         return ROWS * COLS;
  58.     }
  59.  
  60.     constexpr static auto isVector( void ) -> bool
  61.     {
  62.         return ROWS == 1 || COLS == 1;
  63.     }
  64.  
  65.     auto row( size_t iRow ) const -> Matrix< T, 1, COLS >
  66.     {
  67.         std::array< T, COLS > values;
  68.  
  69.         for( size_t i = 0; i < COLS; ++i )
  70.             values.at( i ) = at( iRow, i );
  71.  
  72.         return Matrix< T, 1, COLS >{ values };
  73.     }
  74.  
  75.     auto col( size_t iCol ) const -> Matrix< T, ROWS, 1 >
  76.     {
  77.         std::array< T, ROWS > values;
  78.  
  79.         for( size_t i = 0; i < ROWS; ++i )
  80.             values.at( i ) = at( i, iCol );
  81.  
  82.         return Matrix< T, ROWS, 1 >{ values };
  83.     }
  84.  
  85.     auto row( size_t iRow, Matrix< T, 1, COLS > mat ) -> void
  86.     {
  87.         for( size_t i = 0; i < COLS; ++i )
  88.             at( iRow, i ) = mat( i );
  89.     }
  90.  
  91.     auto col( size_t iCol, Matrix< T, ROWS, 1 > mat ) -> void
  92.     {
  93.         for( size_t i = 0; i < ROWS; ++i )
  94.             at( i, iCol ) = mat( i );
  95.     }
  96.  
  97.     auto at( size_t i ) -> T&
  98.     {
  99.         return m_cValues.at( i );
  100.     }
  101.  
  102.     auto at( size_t i ) const -> const T&
  103.     {
  104.         return m_cValues.at( i );
  105.     }
  106.  
  107.     auto at( size_t iRow, size_t iCol ) -> T&
  108.     {
  109.         return m_cValues.at( iRow * COLS + iCol );
  110.     }
  111.  
  112.     auto at( size_t iRow, size_t iCol ) const -> const T&
  113.     {
  114.         return m_cValues.at( iRow * COLS + iCol );
  115.     }
  116.  
  117.     auto operator()( size_t i ) -> T&
  118.     {
  119.         return at( i );
  120.     }
  121.  
  122.     auto operator()( size_t i ) const -> const T&
  123.     {
  124.         return at( i );
  125.     }
  126.  
  127.     auto operator()( size_t iRow, size_t iCol ) -> T&
  128.     {
  129.         return at( iRow, iCol );
  130.     }
  131.  
  132.     auto operator()( size_t iRow, size_t iCol ) const -> const T&
  133.     {
  134.         return at( iRow, iCol );
  135.     }
  136.  
  137.     auto operator+( T other ) const -> Matrix< T, ROWS, COLS >
  138.     {
  139.         auto buf = *this;
  140.         buf += other;
  141.         return buf;
  142.     }
  143.  
  144.     auto operator-( T other ) const -> Matrix< T, ROWS, COLS >
  145.     {
  146.         auto buf = *this;
  147.         buf -= other;
  148.         return buf;
  149.     }
  150.  
  151.     auto operator*( T other ) const -> Matrix< T, ROWS, COLS >
  152.     {
  153.         auto buf = *this;
  154.         buf *= other;
  155.         return buf;
  156.     }
  157.  
  158.     auto operator/( T other ) const -> Matrix< T, ROWS, COLS >
  159.     {
  160.         auto buf = *this;
  161.         buf /= other;
  162.         return buf;
  163.     }
  164.  
  165.     auto operator+=( T other ) -> Matrix< T, ROWS, COLS >&
  166.     {
  167.         for( auto& val : m_cValues )
  168.             val += other;
  169.  
  170.         return *this;
  171.     }
  172.  
  173.     auto operator-=( T other ) -> Matrix< T, ROWS, COLS >&
  174.     {
  175.         for( auto& val : m_cValues )
  176.             val -= other;
  177.  
  178.         return *this;
  179.     }
  180.  
  181.     auto operator*=( T other ) -> Matrix< T, ROWS, COLS >&
  182.     {
  183.         for( auto& val : m_cValues )
  184.             val *= other;
  185.  
  186.         return *this;
  187.     }
  188.  
  189.     auto operator/=( T other ) -> Matrix< T, ROWS, COLS >&
  190.     {
  191.         for( auto& val : m_cValues )
  192.             val /= other;
  193.  
  194.         return *this;
  195.     }
  196.  
  197.     auto operator+( const Matrix< T, ROWS, COLS >& other ) const -> Matrix< T, ROWS, COLS >
  198.     {
  199.         auto buf = *this;
  200.  
  201.         for( size_t i = 0; i < size( ); ++i )
  202.             buf( i ) += other( i );
  203.  
  204.         return buf;
  205.     }
  206.  
  207.     auto operator-( const Matrix< T, ROWS, COLS >& other ) const -> Matrix< T, ROWS, COLS >
  208.     {
  209.         auto buf = *this;
  210.  
  211.         for( size_t i = 0; i < size( ); ++i )
  212.             buf( i ) -= other( i );
  213.  
  214.         return buf;
  215.     }
  216.  
  217.     auto operator+=( const Matrix< T, ROWS, COLS >& other ) -> Matrix< T, ROWS, COLS >&
  218.     {
  219.         for( size_t i = 0; i < size( ); ++i )
  220.             at( i ) += other( i );
  221.  
  222.         return ( *this );
  223.     }
  224.  
  225.     auto operator==( const Matrix< T, ROWS, COLS >& other ) const -> bool
  226.     {
  227.         for( size_t i = 0; i < size( ); ++i )
  228.             if( at( i ) != other.at( i ) )
  229.                 return false;
  230.  
  231.         return true;
  232.     }
  233.  
  234.     auto operator!=( const Matrix< T, ROWS, COLS >& other ) const -> bool
  235.     {
  236.         return !( ( *this ) == other );
  237.     }
  238.  
  239.     auto operator-=( const Matrix< T, ROWS, COLS >& other ) -> Matrix< T, ROWS, COLS >&
  240.     {
  241.         for( size_t i = 0; i < size( ); ++i )
  242.             at( i ) -= other( i );
  243.  
  244.         return ( *this );
  245.     }
  246.  
  247.     auto norm( void ) const -> T
  248.     {
  249.         static_assert( Matrix< T, ROWS, COLS >::isVector( ), "Matrix::norm can only be used on vectors!" );
  250.  
  251.         T buf = static_cast<T>( 0 );
  252.  
  253.         for( auto v : m_cValues )
  254.             buf += ( v * v );
  255.  
  256.         return sqrt( buf );
  257.     }
  258.  
  259.     auto normalize( void ) -> void
  260.     {
  261.         static_assert( Matrix< T, ROWS, COLS >::isVector( ), "Matrix::normalize can only be used on vectors!" );
  262.         ( *this ) /= this->norm( );
  263.     }
  264.  
  265.     auto normalized( void ) const -> Matrix< T, ROWS, COLS >
  266.     {
  267.         static_assert( Matrix< T, ROWS, COLS >::isVector( ), "Matrix::normalized can only be used on vectors!" );
  268.  
  269.         auto buf = *this;
  270.         buf.normalize( );
  271.         return buf;
  272.     }
  273.  
  274.     friend std::ostream& operator <<( std::ostream& os, const Matrix< T, ROWS, COLS >& v )
  275.     {
  276.         for( size_t i = 0; i < ROWS; ++i )
  277.         {
  278.             for( size_t j = 0; j < COLS; j++ )
  279.                 os << v.at( i, j ) << "\t";
  280.  
  281.             os << "\n";
  282.         }
  283.  
  284.         return os;
  285.     }
  286.  
  287.     template < typename K, size_t OROWS, size_t OCOLS >
  288.     auto dot( const Matrix< K, OROWS, OCOLS >& other ) const -> T
  289.     {
  290.         static_assert( Matrix< T, ROWS, COLS >::isVector( ) && Matrix< K, OROWS, OCOLS >::isVector( ), "Matrix::dot can only be used on vectors!" );
  291.  
  292.         T buf = static_cast<T>( 0 );
  293.  
  294.         for( size_t i = 0; i < min( size( ), other.size( ) ); ++i )
  295.             buf += at( i ) * other.at( i );
  296.  
  297.         return buf;
  298.     }
  299.  
  300.     auto cross( const Matrix< T, ROWS, COLS >& other ) const -> Matrix< T, ROWS, COLS >
  301.     {
  302.         static_assert( Matrix< T, ROWS, COLS >::size( ) == 3, "Matrix::cross can only be called for 3 dimensional vectors!" );
  303.  
  304.         return{
  305.             at( 1 )* other.at( 2 ) - at( 2 )* other.at( 1 ),
  306.             at( 2 )* other.at( 0 ) - at( 0 )* other.at( 2 ),
  307.             at( 0 )* other.at( 1 ) - at( 1 )* other.at( 0 ),
  308.         };
  309.     }
  310.  
  311.     auto ncross( const Matrix< T, ROWS, COLS >& other ) const -> Matrix< T, ROWS, COLS >
  312.     {
  313.         static_assert( Matrix< T, ROWS, COLS >::size( ) == 3, "Matrix::ncross can only be called for 3 dimensional vectors!" );
  314.  
  315.         return cross( other ).normalized( );
  316.     }
  317. };
  318.  
  319. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement