Thread: Weird errors.

  1. #16
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I put the code you posted just above mine into a project with an empty main, so it wasn't that code that was the problem. I just added stuff to make sure it compiles (if you don't use a template it won't always get run through the compiler).

    I don't understand the errors you posted, so perhaps there is something wrong somewhere else in your original project that is causing strange parse errors. I dunno.

  2. #17
    Registered User
    Join Date
    May 2006
    Posts
    903
    You tested it with an empty main, but when I tested it at first, I had no main() at all.

  3. #18
    Registered User
    Join Date
    May 2006
    Posts
    903
    Alright, I'm done for today, I'll post it here for you guys so you can comment, criticize and suggest ideas. I haven't finished the Determinant() function. Right now it can only calculate determinants for matrice from 1x1 to 3x3 but no more since I haven't fully understood the LU decomposition method for faster calculation of determinants on large matrices.

    Anyway, here's the code. I haven't fully tested it but most of it works (tested) :
    Code:
    #ifndef MATRIX_H_INCLUDED
    #define MATRIX_H_INCLUDED
    
    #include <iostream>
    #include <vector>
    #include <memory>
    
    template < class T >
    class Matrix
    {
    public:
        typedef std::auto_ptr< Matrix< T > > MATRIX_PTR;
    
        Matrix(int Cols = 0, int Rows = 0);
    
    	void Output( )
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				std::cout << Data[j][i];
    			}
    			std::cout << std::endl;
    		}
    	}
    
    	void SetElement(int col, int row, T val);
    	void InterchangeRows(int row_1, int row_2);
    	void InterchangeCols(int col_1, int col_2);
    
    	bool LowerTriangle( ) const;
    	bool UpperTriangle( ) const;
        bool SquareMatrix( ) const;
    
    	T Determinant( );
    
        MATRIX_PTR& Minor(int col, int row);
    private:
    	unsigned int Rows, Cols;
        std::vector< std::vector< T > > Data;
        MATRIX_PTR Temp;
    };
    
    template < class T >
    Matrix< T >::Matrix< T >(int n_cols, int n_rows)
    	: Cols(n_cols), Rows(n_rows)
    {
    	if(n_cols > 0 && n_rows > 0)
    	{
    		for(int i = 0; i < Rows; i++)
    		{
    			Data.push_back(std::vector< T >( ));
    			Data[i].insert(Data[i].begin(), Cols, 0);
    		}
    	}
    	else
    	{
    		Cols = Rows = 0;
    	}
    }
    
    template < class T >
    void Matrix< T >::SetElement(int col, int row, T val)
    {
    	if(col >= 0 && row >= 0)
    	{
    		Data[row][col] = val;
    	}
    }
    
    template < class T >
    void Matrix< T >::InterchangeRows(int row_1, int row_2)
    {
    	if(row_1 != row_2 && (row_1 >= 0 && row_2 >= 0))
    	{
    		Data[row_1].swap(Data[row_2]);
    	}
    }
    
    template < class T>
    void Matrix< T >::InterchangeCols(int col_1, int col_2)
    {
    	// Parentheses for easier reading only
    	// Make sure both columns are different and range in [0, Cols[
    	if((col_1 != col_2) && (col_1 >= 0) && (col_2 >= 0) && (col_1 < Cols) && (col_2 < Cols))
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			T tmp = Data[j][col_1];
    			Data[j][col_1] = Data[j][col_2];
    			Data[j][col_2] = tmp;
    		}
    	}
    }
    
    template < class T >
    bool Matrix< T >::LowerTriangle( ) const
    {
    	// Only square matrixes bigger than 0,0
    	if(SquareMatrix() && (Cols != 0 && Rows != 0))
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				if(i > j && Data[j][i] != 0)
    				{
    					return false;
    				}
    			}
    		}
    	}
    	else
    	{
    		return false;
    	}
    	return true;
    }
    
    template < class T >
    bool Matrix< T >::UpperTriangle( ) const
    {
    	// Only square matrixes bigger than 0,0
    	if(SquareMatrix() && (Cols != 0 && Rows != 0))
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				if(i < j && Data[j][i] != 0)
    				{
    					return false;
    				}
    			}
    		}
    	}
    	else
    	{
    		return false;
    	}
    	return true;
    }
    
    template < class T >
    bool Matrix< T >::SquareMatrix( ) const
    {
        return (Rows == Cols);
    }
    
    template < class T >
    T Matrix< T >::Determinant( )
    {
    	if(SquareMatrix( ))
    	{
    		if(Cols == 0 && Rows == 0)
    		{
    			return static_cast< T >(0);
    		}
    		else if(Cols == 1 && Rows == 1)
    		{
    			return Data[0][0];
    		}
    		else if(Cols == 2 && Rows == 2)
    		{
    			return (Data[0][0] * Data[1][1] - Data[0][1] * Data[1][0]);
    		}
    		else if(Cols == 3 && Rows == 3)
    		{
    			if(UpperTriangle( ) || LowerTriangle( ))
    			{
    				return (Data[0][0] * Data[1][1] * Data[2][2]);
    			}
    
    			return (Data[0][0] * Data[1][1] * Data[2][2] +
    					Data[0][2] * Data[1][0] * Data[2][1] +
    					Data[0][1] * Data[1][2] * Data[2][0] -
    					Data[0][2] * Data[1][1] * Data[2][0] -
    					Data[0][0] * Data[1][2] * Data[2][1] -
    					Data[0][1] * Data[1][0] * Data[2][2]);
    		}
    		// Let's use the M = LU decomposition method for faster processing
    		else
    		{
    			
    		}
    	}
    }
    
    template < class T >
    typename Matrix< T >::MATRIX_PTR& Matrix< T >::Minor(int col, int row)
    {
    	if(SquareMatrix( ) && (Rows != 0 && Cols != 0))
    	{
    		Temp.reset(new Matrix< T >);
    
    		int y = 0;
    
    		// Move horizontally then down in the matrix
    		for(int j = 0; j < Rows; j++)
    		{
    
    			if(j != row)
    			{
    				// We're on a new line...
    				Temp->Data.push_back(std::vector< T >( ));
    				for(int i = 0; i < Cols; i++)
    				{
    					if(i != col)
    					{
    						(Temp->Data[y]).push_back(Data[j][i]);
    					}
    				}
    				y++;
    			}
    		}
    	}
    
    	Temp->Cols = Temp->Data[0].size();
    	Temp->Rows = Temp->Data.size();
    	return Temp;
    }
    
    #endif // MATRIX_H_INCLUDED
    PS: The Output() function is there only for testing purposes, I will take it out when I have finished testing / implementing.

    Thanks again !

  4. #19
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    some comments
    Code:
    template < class T >
    class Matrix
    {
    public:
    
        Matrix(int Cols = 0, int Rows = 0);
    private:
        unsigned int Rows, Cols;
    };
    
    template < class T >
    Matrix< T >::Matrix< T >(int n_cols, int n_rows)
    	: Cols(n_cols), Rows(n_rows)
    {
    	if(n_cols > 0 && n_rows > 0)
    	{
    		for(int i = 0; i < Rows; i++)
    		{
    			Data.push_back(std::vector< T >( ));
    			Data[i].insert(Data[i].begin(), Cols, 0);
    		}
    	}
    	else
    	{
    		Cols = Rows = 0;
    	}
    }
    your constructor arguements Cols and Rows have different names in the implementation (n_cols, n_rows). This is legal but bad style. Cols and Rows are both members and arguements in the class def. Personally I like to differentiate members somehow (this->var, m_var, var_, whatever you like). are default arguements of 0 useful?

    Also why are the arguements ints, but the members unsigned ints? surely the arguements should also be unsigned?

    The else is redundant. Cols and Rows have already been initiated to 0 in your initialiser list.

    you should reserve() your vectors since you know the size. It will increase efficiency.

    Code:
    	void SetElement(int col, int row, T val);
    	void InterchangeRows(int row_1, int row_2);
    	void InterchangeCols(int col_1, int col_2);
    same comment about unsigned int parameters.


    I won't comment on the matrix math since it's been a while since I used it in anger.

    Code:
    template < class T >
    typename Matrix< T >::MATRIX_PTR& Matrix< T >::Minor(int col, int row)
    {
        // snip...
        Temp.reset(new Matrix< T >);
        // snip...
        return Temp;
    }
    hmmm... this isn't really the best way to use auto_ptr.
    consider the following
    Code:
    Matrix<float> agentSmith(666, 666);
    MATRIX_PTR &neo = agentSmith.Minor();
    // some code
    
    MATRIX_PTR &trinity = agentSmith.Minor(); // arrghhh neo was killed!!
    You should really return an auto_ptr (not a reference) and forget your Temp member. This will allow the client to take ownership of the minor matrix.

    other than that, looks good. keep it up.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  5. #20
    Registered User
    Join Date
    May 2006
    Posts
    903
    Thanks ! I'll fix that up when I get back from College this afternoon. I'll add a copy constructor as well and operators such as multiplication, addition, substraction, equality, assignment... I'd also like to make a function to calculate the order of the matrix (usually noted 'k'). I'll try to find the other thread where someone mentioned points that he/she'd like to have in a matrix library. I might as well make a vector class after.

  6. #21
    Registered User
    Join Date
    May 2006
    Posts
    903
    Here we go, I quite a bit of stuff and I still need to work on determinants and more other stuff (making it possible to add vectors of numbers, adding scalar * matrix, adding matrix transpose...). I'm not completely satisfied with the design yet but it's not that ugly either.

    Here it is:

    Code:
    #ifndef MATRIX_H_INCLUDED
    #define MATRIX_H_INCLUDED
    
    #include <iostream>
    #include <vector>
    #include <memory>
    
    template < class T >
    class Matrix
    {
    public:
        typedef std::auto_ptr< Matrix< T > > MATRIX_PTR;
    
        Matrix(unsigned int n_cols = 0, unsigned int n_rows = 0);
    	Matrix(const Matrix& m);
    
    	void Output( )
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				std::cout << Data[j][i];
    			}
    			std::cout << std::endl;
    		}
    	}
    
    	void SetElement(unsigned int col, unsigned int row, T val);
    	void InterchangeRows(unsigned int row_1, unsigned int row_2);
    	void InterchangeCols(unsigned int col_1, unsigned int col_2);
    
    	bool LowerTriangle( ) const;
    	bool UpperTriangle( ) const;
        bool SquareMatrix( ) const;
    
    	T Determinant( );
    
    	static MATRIX_PTR IdentityMatrix(unsigned int size);
    	static MATRIX_PTR NullMatrix(unsigned int size);
    
        MATRIX_PTR Minor(unsigned int col, unsigned int row);
    
    	Matrix< T >& operator = (const Matrix< T >&);
    	Matrix< T >& operator += (const Matrix< T >&);
    	Matrix< T >& operator -= (const Matrix< T >&);
    	Matrix< T > operator * (const Matrix< T >&) const;
    	Matrix< T > operator - (const Matrix< T >&) const;
    	Matrix< T > operator + (const Matrix< T >&) const;
    private:
    	unsigned int Rows, Cols;
        std::vector< std::vector< T > > Data;
    };
    
    template < class T >
    Matrix< T >::Matrix< T >(unsigned int n_cols, unsigned int n_rows)
    	: Cols(n_cols), Rows(n_rows)
    {
    	if(Cols > 0 && Rows > 0)
    	{
    		Data.reserve(Rows);
    		for(int i = 0; i < Rows; i++)
    		{
    			Data.push_back(std::vector< T >( ));
    
    			Data[i].reserve(Cols);
    			Data[i].insert(Data[i].begin(), Cols, 0);
    		}
    	}
    	else if(Cols < 0 && Rows < 0)
    	{
    		Cols = Rows = 0;
    	}
    }
    
    template < class T >
    Matrix< T >::Matrix< T >(const Matrix& m)
    {
    	*this = m;
    }
    
    template < class T >
    void Matrix< T >::SetElement(unsigned int col, unsigned int row, T val)
    {
    	if(col >= 0 && row >= 0 && col < Cols && row < Rows)
    	{
    		Data[row][col] = val;
    	}
    }
    
    template < class T >
    void Matrix< T >::InterchangeRows(unsigned int row_1, unsigned int row_2)
    {
    	if(row_1 != row_2 && (row_1 >= 0 && row_2 >= 0))
    	{
    		Data[row_1].swap(Data[row_2]);
    	}
    }
    
    template < class T>
    void Matrix< T >::InterchangeCols(unsigned int col_1, unsigned int col_2)
    {
    	// Parentheses for easier reading only
    	// Make sure both columns are different and range in [0, Cols[
    	if((col_1 != col_2) && (col_1 >= 0) && (col_2 >= 0) && (col_1 < Cols) && (col_2 < Cols))
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			T tmp = Data[j][col_1];
    			Data[j][col_1] = Data[j][col_2];
    			Data[j][col_2] = tmp;
    		}
    	}
    }
    
    template < class T >
    bool Matrix< T >::LowerTriangle( ) const
    {
    	// Only square matrixes bigger than 0,0
    	if(SquareMatrix() && (Cols != 0 && Rows != 0))
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				if(i > j && Data[j][i] != 0)
    				{
    					return false;
    				}
    			}
    		}
    	}
    	else
    	{
    		return false;
    	}
    	return true;
    }
    
    template < class T >
    bool Matrix< T >::UpperTriangle( ) const
    {
    	// Only square matrixes bigger than 0,0
    	if(SquareMatrix() && (Cols != 0 && Rows != 0))
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				if(i < j && Data[j][i] != 0)
    				{
    					return false;
    				}
    			}
    		}
    	}
    	else
    	{
    		return false;
    	}
    	return true;
    }
    
    template < class T >
    bool Matrix< T >::SquareMatrix( ) const
    {
        return (Rows == Cols);
    }
    
    template < class T >
    T Matrix< T >::Determinant( )
    {
    	if(SquareMatrix( ))
    	{
    		if(Cols == 0 && Rows == 0)
    		{
    			return static_cast< T >(0);
    		}
    		if(Cols == 1 && Rows == 1)
    		{
    			return Data[0][0];
    		}
    
    		if(UpperTriangle( ) || LowerTriangle( ))
    		{
    			int total = 1;
    			for(int i = 0; i < Cols; i++)
    			{
    				total *= Data[i][i];
    			}
    			return total;
    		}
    
    		if(Cols == 2 && Rows == 2)
    		{
    			return (Data[0][0] * Data[1][1] - Data[0][1] * Data[1][0]);
    		}
    		if(Cols == 3 && Rows == 3)
    		{
    			return (Data[0][0] * Data[1][1] * Data[2][2] +
    					Data[0][2] * Data[1][0] * Data[2][1] +
    					Data[0][1] * Data[1][2] * Data[2][0] -
    					Data[0][2] * Data[1][1] * Data[2][0] -
    					Data[0][0] * Data[1][2] * Data[2][1] -
    					Data[0][1] * Data[1][0] * Data[2][2]);
    		}
    		// Let's use the M = LU decomposition method for faster processing
    		else
    		{
    			
    		}
    	}
    }
    
    template < class T >
    typename Matrix< T >::MATRIX_PTR Matrix< T >::IdentityMatrix(unsigned int size)
    {
    	MATRIX_PTR tmp(new Matrix< T >(size, size));
    
    	for(int j = 0; j < tmp->Rows; j++)
    	{
    		for(int i = 0; i < tmp->Cols; i++)
    		{
    			tmp->Data[j][i] = i == j ? 1 : 0;
    		}
    	}
    
    	return tmp;
    }
    
    template < class T >
    typename Matrix< T >::MATRIX_PTR Matrix< T >::NullMatrix(unsigned int size)
    {
    	return MATRIX_PTR(new Matrix< T >(size, size));
    }
    
    template < class T >
    typename Matrix< T >::MATRIX_PTR Matrix< T >::Minor(unsigned int col, unsigned int row)
    {
    	static MATRIX_PTR tmp;
    
    	if(SquareMatrix( ) && (Rows != 0 && Cols != 0))
    	{
    		tmp.reset(new Matrix< T >);
    
    		int y = 0;
    
    		// Move horizontally then down in the matrix
    		for(int j = 0; j < Rows; j++)
    		{
    
    			if(j != row)
    			{
    				// We're on a new line...
    				tmp->Data.push_back(std::vector< T >( ));
    				for(int i = 0; i < Cols; i++)
    				{
    					if(i != col)
    					{
    						(tmp->Data[y]).push_back(Data[j][i]);
    					}
    				}
    				y++;
    			}
    		}
    		tmp->Cols = tmp->Data[0].size();
    		tmp->Rows = tmp->Data.size();
    	}
    
    	return tmp;
    }
    
    template< class T >
    Matrix< T >& Matrix< T >::operator = (const Matrix< T >& m)
    {
    	Rows = m.Rows;
    	Cols = m.Cols;
    
    	Data.assign(m.Data.begin(), m.Data.end());
    
    	return *this;
    }
    
    template< class T >
    Matrix< T >& Matrix< T >::operator += (const Matrix< T >& m)
    {
    	*this = *this + m;
    	return *this;
    }
    
    template< class T >
    Matrix< T >& Matrix< T >::operator -= (const Matrix< T >& m)
    {
    	*this = *this - m;
    	return *this;
    }
    
    template< class T >
    Matrix< T > Matrix< T >::operator * (const Matrix< T >& m) const
    {
    	// A Matrix A(a, b) and a matrix B(c, d) yield a matric C(b, c) when multiplied
    	Matrix< T > tmp(Rows, m.Cols);
    
    	if(Cols == m.Rows && Rows == m.Cols && Rows > 0 && Cols > 0)
    	{
    		for(int j_result = 0; j_result < Rows; j_result++)
    		{
    			for(int i_result = 0; i_result < m.Cols; i_result++)
    			{
    				int sum = 0;
    				for(int j = 0, i = 0; j < m.Rows && i < Cols; j++, i++)
    				{
    					sum += Data[j_result][i] * m.Data[j][i_result];
    				}
    				tmp.Data[j_result][i_result] = sum;
    			}
    		}
    	}
    
    	return tmp;
    }
    
    template< class T >
    Matrix< T > Matrix< T >::operator - (const Matrix< T >& m) const
    {
    	Matrix< T > tmp(Cols, Rows);
    
    	if(Rows == m.Rows && Cols == m.Cols && Rows > 0 && Cols > 0)
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				tmp.Data[j][i] = Data[j][i] - m.Data[j][i];
    			}
    		}
    	}
    
    	return tmp;
    }
    
    template< class T >
    Matrix< T > Matrix< T >::operator + (const Matrix< T >& m) const
    {
    	Matrix< T > tmp(Cols, Rows);
    
    	if(Rows == m.Rows && Cols == m.Cols && Rows > 0 && Cols > 0)
    	{
    		for(int j = 0; j < Rows; j++)
    		{
    			for(int i = 0; i < Cols; i++)
    			{
    				tmp.Data[j][i] = Data[j][i] + m.Data[j][i];
    			}
    		}
    	}
    
    	return tmp;
    }
    
    #endif // MATRIX_H_INCLUDED

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. HELP with DX9 Errors!!!
    By Tommaso in forum Game Programming
    Replies: 7
    Last Post: 06-28-2006, 02:51 PM
  2. Errors with header files in OpenGL using VisualC++
    By wile_spice in forum Game Programming
    Replies: 3
    Last Post: 06-22-2006, 08:56 AM
  3. Weird Errors in VS 2003
    By Devil Panther in forum Windows Programming
    Replies: 1
    Last Post: 10-01-2005, 06:16 AM
  4. executing errors
    By s0ul2squeeze in forum C++ Programming
    Replies: 3
    Last Post: 03-26-2002, 01:43 PM