Classes Matrix question

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Hypnotik
    New Member
    • Jun 2007
    • 87

    Classes Matrix question

    Hello everyone. I'm writing a program which uses a class called matrix. I have written all of the different functions, constructor, etc.

    When I run the program I receive "Constructo r", which I placed in the constructor, and then the program crashes. I have no clue where my problem is.

    The matrix is for size 2x2 up to 10x10, and it must be square.

    Below is the code:

    Code:
    #include <iostream>
    #include <ctype.h>
    using namespace std;
    int innerprod(int s[][10],int t[][10],int r,int c,int size)
    {
    	int temp=0,i;
    	for (i=0;i<=size;++i)
    	{
    		temp=temp+s[r][i]*t[i][c];
    	}
    	return temp;
    }
    class Matrix
    {
    public:
    	~Matrix(){};
    	Matrix();
    	void readm();
    	void addm(Matrix);
    	void multm(Matrix);
    	void print();
    private:
    	int a[10][10];
    	int size;
    };
    Matrix::Matrix()
    {
    	cout<<"Constructor"<<endl;
    	int i=0, j=0;
    	for (i=0;i<=10;++i)
    		for (j=0;j<=10;++i)
    		{
    			a[i][j]=0;
    		}
    }
    void Matrix::readm()
    {
    	int i=0,j=0;
    	for (i=0;i<=10;++i)
    		for (j=0;j<=10;++j)
    		{
    			cin>>a[i][j];
    		}
    }
    void Matrix::addm(Matrix B)
    {
    	int i=0,j=0;
    	for (i=0;i<=10;++i)
    		for (j=0;j<=10;++j)
    		{
    			a[i][j]=a[i][j]+B.a[i][j];
    		}
    }
    void Matrix::multm(Matrix B)
    {
    	int i=0,j=0,temp[10][10],n=2;
    	for(i=0;i<=10;++i)
    		for (j=0;j<=10;++j)
    		{
    			temp[i][j]=innerprod(a,B.a,i,j,n);
    		}
    	for (i=0;i<=10;++i)
    		for (j=0;j<=10;++j)
    		{
    			a[i][j]=temp[i][j];
    		}
    }
    void Matrix::print()
    {
    	int i=0,j=0;
    	for (i=0;i<=10;++i)
    	{
    		cout<<endl<<endl;
    		for (j=0;j<=10;++j)
    		{
    			cout<<"    "<<a[i][j];
    		}
    	}
    	cout<<endl;
    }
    void main()
    {
    	char choice;
    	Matrix x,y;
    	cout<<"   Welcome to Matrix Manipulations."<<endl;
    	x.print();
    	cout<<"   You may add or multiply a matrix."<<endl;
    	cout<<"   Enter choice: (a)dd or (m)multiply.  "<<endl;
    	cin>>choice;
    	choice>>tolower(choice);
    	cout<<"   Enter a square matrix from 2x2 to 10x10 in row order:"<<endl;
    	x.readm();
    	switch(choice)
    	{
    	case 'a':cout<<"Enter a square matrix from size 2x2 to 10x10 in row order:"<<endl;
    		y.readm();
    		x.print();
    		cout<<endl<<"    +";
    		y.print();
    		cout<<endl<<"    =";
    		x.addm(y);
    		x.print();
    		break;
    	case 'm':cout<<"Enter a square matrix from size 2xe to 10x10 in row order:"<<endl;
    		y.readm();
    		x.print();
    		x.multm(y);
    		cout<<endl<<"    *";
    		y.print();
    		cout<<endl<<"    =";
    		x.print();
    		break;
    	default: cout<<"    INVALID CHOICE!";
    		break;
    	};
    }
    Thanks,

    J
  • JosAH
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    Your loops all have an off by one error. When the maximum dimension of an array
    equals 10, valid index values are 0, 1, 2, 3, 4, 5, 6 , 7, 8, and 9 (count them:
    there are 10 different index values). Therefore your loops should all have a
    terminating condition such as:

    [code=cpp]
    for (int i= 0; i < 10; i++) ...
    [/code]

    kind regards,

    Jos

    Comment

    • Hypnotik
      New Member
      • Jun 2007
      • 87

      #3
      Back to my rescue again hun JosAH?

      I understand what you're saying, and that is right...I wasn't thinking when I made them less than or equal to 10. The program still crashes, so the functions aren't going out of scope (or whatever it's called).

      J

      Comment

      • JosAH
        Recognized Expert MVP
        • Mar 2007
        • 11453

        #4
        Originally posted by Hypnotik
        Back to my rescue again hun JosAH?

        I understand what you're saying, and that is right...I wasn't thinking when I made them less than or equal to 10. The program still crashes, so the functions aren't going out of scope (or whatever it's called).

        J
        I took a bit closer look at your code: have a look at the inner loop in your ctor:
        it increments 'i' instead of 'j' and it will shoot you in your foot for it ;-)

        kind regards,

        Jos

        Comment

        • Hypnotik
          New Member
          • Jun 2007
          • 87

          #5
          Awesome. I never used 'i' and 'j' before because they look so much alike! But seems that my instructor uses them so I've started.

          I also removed the destructor function...whic h stopped the program from crashing. Do you know why that would be?

          J

          Comment

          • Hypnotik
            New Member
            • Jun 2007
            • 87

            #6
            I know need to set the size of my matrix to the input from the user from the default size of the matrix (the constructor). Do I need to create an entirely differnent function for this?

            something like:

            void SetMatrix() ?

            Comment

            • Hypnotik
              New Member
              • Jun 2007
              • 87

              #7
              Originally posted by Hypnotik
              I know need to set the size of my matrix to the input from the user from the default size of the matrix (the constructor). Do I need to create an entirely differnent function for this?

              something like:

              void SetMatrix() ?

              Is passing the size of the array to the functions just like passing any other info to a function?

              Thanks,
              J

              Comment

              • Hypnotik
                New Member
                • Jun 2007
                • 87

                #8
                Well I have found my problem, however there is a problem with my multiplication.

                J

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  Originally posted by Hypnotik
                  Well I have found my problem, however there is a problem with my multiplication.

                  J
                  What's the problem then? And please don't say "it produces the wrong results" ;-)

                  kind regards,

                  Jos

                  Comment

                  • Hypnotik
                    New Member
                    • Jun 2007
                    • 87

                    #10
                    Hah. Well it does give the wrong answer. Anyway, I think the problem is in the innerprod function. When I do addition the program works great. When I do the multiplication it returns a HUGE number for a matrix with all 1's as the input. I pass all types of information to the innnerprod function including both matrices and size. The size is correct, however the numbers within the matrix are incorrect.

                    I'm going to check my code and make sure the one posted in the thread is up to date.


                    Thanks,
                    J

                    Comment

                    • Hypnotik
                      New Member
                      • Jun 2007
                      • 87

                      #11
                      Current code:


                      Code:
                      #include <iostream>
                      #include <ctype.h>
                      using namespace std;
                      int innerprod(int s[][10],int t[][10],int r,int c,int size)
                      {
                      	int temp=0,i;
                      	for (i=0;i<size;++i)
                      	{
                      		temp=temp+s[r][i]*t[i][c];
                      	}
                      	return temp;
                      }
                      class Matrix
                      {
                      public:
                      	~Matrix(){};
                      	Matrix();
                      	void readm(int r, int t);
                      	void addm(Matrix,int r,int t);
                      	void multm(Matrix,int r, int t);
                      	void print(int r,int t);
                      	Matrix(int r,int t);
                      private:
                      	int a[10][10];
                      	int size;
                      };
                      Matrix::Matrix()
                      {
                      	cout<<"In the Constructor function....."<<endl<<endl;
                      	int i=0, j=0;
                      	for (i=0;i<2;++i)
                      		for (j=0;j<2;++j)
                      		{
                      			a[i][j]=0;
                      		}
                      }
                      Matrix::Matrix(int r,int t)
                      {
                      	int i=0,j=0;
                      	cout<<"   Initializing new Matrix....."<<endl;
                      	for (i=0;i<r;++i)
                      		for (j=0;j<t;++j)
                      		{
                      			a[r][t]=0;
                      		}
                      	for (i=0;i<r;++i)
                      	{
                      		cout<<endl<<endl;
                      		for (j=0;j<t;++j)
                      			cout<<"   "<<a[r][t];
                      	}
                      	cout<<endl;
                      	
                      }
                      void Matrix::readm(int r, int t)
                      {
                      	int i=0,j=0;
                      	for (i=0;i<r;++i)
                      		for (j=0;j<t;++j)
                      		{
                      			cin>>a[i][j];
                      		}
                      }
                      void Matrix::addm(Matrix B,int r, int t)
                      {
                      	int i=0,j=0;
                      	for (i=0;i<r;++i)
                      		for (j=0;j<t;++j)
                      		{
                      			a[i][j]=a[i][j]+B.a[i][j];
                      		}
                      }
                      void Matrix::multm(Matrix B,int r, int t)
                      {
                      	int i=0,j=0,temp[10][10],n=r;
                      	for(i=0;i<r;++i)
                      		for (j=0;j<t;++j)
                      		{
                      			temp[i][j]=innerprod(a,B.a,r,t,n);
                      		}
                      	for (i=0;i<r;++i)
                      		for (j=0;j<t;++j)
                      		{
                      			a[i][j]=temp[i][j];
                      		}
                      }
                      void Matrix::print(int r,int t)
                      {
                      	int i=0,j=0;
                      	for (i=0;i<r;++i)
                      	{
                      		cout<<endl<<endl;
                      		for (j=0;j<t;++j)
                      		{
                      			cout<<"    "<<a[i][j];
                      		}
                      	}
                      	cout<<endl;
                      }
                      void main()
                      {
                      	int r=0, t=0;
                      	char choice,s;
                      	Matrix x,y;
                      	s=6;
                      	cout<<"   Welcome to Matrix Manipulations for Square Matrices."<<endl;
                      	x.print(r,t);
                      	do
                      	{
                      		cout<<"   What size matrix do you have??  Enter a matrix size 2x2 to 10x10."<<endl;
                      		cin>>r>>t;
                      	}
                      	while (r>10||t>10||r<2||t<2||r!=t);
                      	Matrix(r,t);
                      	cout<<endl<<"   You may add or multiply a matrix."<<endl;
                      	cout<<"   Enter choice: (a)dd or (m)multiply.  "<<endl;
                      	cin>>choice;
                      	choice>>tolower(choice);
                      	cout<<"   Enter a square matrix from 2x2 to 10x10 in row order:"<<endl;
                      	x.readm(r,t);
                      	switch(choice)
                      	{
                      	case 'a':cout<<"Enter a square matrix from size 2x2 to 10x10 in row order:"<<endl;
                      		y.readm(r,t);
                      		x.print(r,t);
                      		cout<<endl<<"    +";
                      		y.print(r,t);
                      		cout<<endl<<"    =";
                      		x.addm(y,r,t);
                      		x.print(r,t);
                      		break;
                      	case 'm':cout<<"Enter a square matrix from size 2x2 to 10x10 in row order:"<<endl;
                      		y.readm(r,t);
                      		x.print(r,t);
                      		x.multm(y,r,t);
                      		cout<<endl<<"    *";
                      		y.print(r,t);
                      		cout<<endl<<"    =";
                      		x.print(r,t);
                      		break;
                      	default :cout<<"    INVALID CHOICE!";
                      		break;
                      	};
                      }
                      j

                      Comment

                      • Hypnotik
                        New Member
                        • Jun 2007
                        • 87

                        #12
                        Hey everyone. I'm still having a problem when multiplying the 2 matrices. When I multiply them I receive an outrageously large "garbage" number. I have a feeling the problem is in my innerprod function, but I'm just not seeing it.

                        The current code is posted above.

                        Thanks,
                        J

                        Comment

                        • OuaisBla
                          New Member
                          • Jun 2007
                          • 18

                          #13
                          Depending on the input, having int a underlying datatype can easily overflow.

                          May be you can try with double. Double don't overflow easily but may lose precision over time. But int is almost sure to overflow, specialy for a 10 by 10 matrix.

                          Code:
                          class Matrix
                          {
                          public:
                              ~Matrix(){};
                              Matrix();
                              void readm(int r, int t);
                              void addm(Matrix,int r,int t);
                              void multm(Matrix,int r, int t);
                              void print(int r,int t);
                              Matrix(int r,int t);
                          private:
                              double a[10][10];
                              int size;
                          };
                          Also don't forget than floating point number if not exact regarding the binary representation. This is an issues mostly for the == operator when double(0.333333 3) != double(1.0/3.0);

                          In that case you have to use something like this to test equality:

                          epsilon is an arbitrary value. For my part I always took the sqrt root of the defaut epsilon of a floating point type.

                          Code:
                          float const FloatEspsilon = 0.00034526698; // == sqrtf( std::numeric_limits<float>::epsilon() );
                          
                          inline bool FloatEqual( float _a, float _b )
                          {
                            float const a = _a;
                            float const b = _b;
                          
                            return fabsf( a - b ) < FloatEspsilon;
                          }
                          I tell you that before you ask. And also maybe you already know that. But if you are going to work with double without knowing that, you may have some trouble that are hard to find. (it happens to me once working with a my own matrix class)

                          Comment

                          • Hypnotik
                            New Member
                            • Jun 2007
                            • 87

                            #14
                            Thanks for the reply. I'm not sure I understand the whole overflow thing. I made the change you suggested and I still receive an incorrect answer. I assume by overflow you mean out of scope?

                            I wrote a matrix multiplication problem not to long ago and didn't have half the problems I'm having with this program...seems like classes just complicate things, but I'm sure they'll help out down the road.

                            Thanks again,

                            J

                            Comment

                            • OuaisBla
                              New Member
                              • Jun 2007
                              • 18

                              #15
                              By overflow I mean maybe your intermediate value is greater than the maximum value supported by a int (~2 billion).

                              Did you convert intermediate variable of int by double too?
                              innerproduct must return a double too.

                              Code:
                              void Matrix::multm(Matrix B,int r, int t)
                              {
                                  int i=0,j=0,n=r;
                              
                                  double temp[10][10];
                              
                                  for(i=0;i<r;++i)
                                      for (j=0;j<t;++j)
                                      {
                                          temp[i][j]=innerprod(a,B.a,r,t,n);
                                      }
                                  for (i=0;i<r;++i)
                                      for (j=0;j<t;++j)
                                      {
                                          a[i][j]=temp[i][j];
                                      }
                              }

                              Comment

                              Working...