Page 1 of 1

## 14 Replies - 2708 Views - Last Post: 09 July 2014 - 07:45 AMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=349918&amp;s=7a32e78fd3c52f55a8cbe26e24777dc6&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

Reputation: 1
• Posts: 79
• Joined: 07-July 14

Posted 07 July 2014 - 11:53 AM

Howdy,

I'm working on a matrix class and I've hit a few snags. This is the first time I've ever really played around with stuff like this, so I'm coming to ya'll for help.

Here's what I've got so far:

Matrix.h
#include <iostream>
#include <conio.h>

using namespace std;

class Matrix
{
private:
int matrix[50][50];

public:
void matrixInput(int R, int C); //This member function allows the user to manually input values into a matrix.
void setMatrix(int R, int C, int sum); //This member function assigns values to a matrix.
int outputInput(int R, int C); //This member function returns the value of a given matrix position.
void printMatrix(int R, int C); //This member function will print the contents of a matrix.
};

Matrix.cpp
#include "Matrix.h"

void Matrix::matrixInput(int R, int C)
{
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cout << "Please enter a value for: matrix[" << i+1 << "][" << j+1 << "].";
cin >> matrix[i][j];
}
}
}

void Matrix::setMatrix(int R, int C, int sum)
{
matrix[R][C] = sum;
}

int Matrix::outputInput(int R, int C)
{
return matrix[R][C];
}

void Matrix::printMatrix(int R, int C)
{
for (int i = 0; i < R; i++)
{
cout << "| ";
for (int j = 0; j < C; j++)
{
cout << matrix[i][j] << " ";
}
cout << "|\n";
}
}

main.cpp
#include <iostream>

#include "Matrix.h"

using namespace std;

void main()
{
Matrix matrix1;
Matrix matrix2;
Matrix matrix3;
Matrix matrix4;

int row = 2;
int col = 2;
int sum = 0;
int dif = 0;

cout << "Matrix 1" << endl;
matrix1.matrixInput(row,col);
cout << "Matrix 2" << endl;
matrix2.matrixInput(row,col);

cout << "Sum of 2 Matrices" << endl;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
sum = matrix1.outputInput(i,j) + matrix2.outputInput(i,j);
matrix3.setMatrix(i,j,sum);
}
}

matrix3.printMatrix(row,col);

cout << "Difference of 2 Matrices" << endl;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
dif = matrix1.outputInput(i,j) - matrix2.outputInput(i,j);
matrix4.setMatrix(i,j,dif);
}
}

matrix4.printMatrix(row,col);
}

Where I have questions is in implementing the addition and subtraction bits into the class itself. I understand that I'm going to have to do a copy operation (this from reading in C++ Primer Plus 5th Edition). Right now I'm just after adding/subtracting as the rest will be variations on the same theme. I wanted to run my implementation ideas by you all first to see if I'm understanding this correctly.

So, here it goes:

As I understand the problem, I need to pass my two matrices as arguments to an addition function. This is going to involve having to copy the values of the two existing matrices into temporary matrices within the addition function, then I'll add them, and store them in a new matrix which will be my return value. So...something like this:

int Matrix::matrixAdd(int R, int C, const Matrix & matrix1, const Matrix & matrix2)
{
int sum;
Matrix matrix;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
sum = matrix1.outputInput(i,j) + matrix2.outputInput(i,j);
return matrix.setMatrix(i,j,sum);
}
}
}

I do end up with errors there...C2240, and C2662. Again, I'm new to working through this, but that's what I've got. My idea is that I'm passing the maximum size of the array as defined by the user, in this case a 2x2 array, it'll cycle through and add up to that imposed limit...I went 2x2 because it's small enough that testing doesn't drive me up a wall. Hope that's enough information to give an idea of what I'm trying to do.

V/R

Is This A Good Question/Topic? 0

### #2 #define

• Duke of Err

Reputation: 1853
• Posts: 6,671
• Joined: 19-February 09

Posted 07 July 2014 - 02:13 PM

Hi, welcome to DIC.

Let us consider the operation to add two matrices.

matrix1 + matrix2

Neither matrix1 or matrix2 is changed. Usually the result of the addition is assigned to another object/variable.

matrix3 = matrix1 + matrix2;

You can create two different functions to achieve that, one is a class member the other is not.

Not a class member, probably a friend function :

Matrix matrixAdd(const Matrix &lhs, const Matrix &rhs);

Function is a class member, the left-hand side is the calling class object, this is similar to the overloading of the + operator:

Reputation: 1
• Posts: 79
• Joined: 07-July 14

Posted 07 July 2014 - 07:56 PM

So...I'm kind of getting there. Based on your description, I implemented as best as I could understand your description and came up with this (which is a variation on my original theme from above...got it to compile, so I count that as a win!):

int Matrix::matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>
{
int sum;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
sum = matrix1.outputInput(i,j) + matrix2.outputInput(i,j);
result.setMatrix(i,j,sum);
return result.outputInput(i,j);
}
}
}

The problem I was running into was that I couldn't get the values to cycle without the R and C being passed...based on how I've got it setup right now, that was the solution I found that worked. So, when it compiles, I'm able to pass all the data through without any issues, when it comes time to actually print the results however I get what I think may be addresses...it's similar to a problem I had been having earlier, with my setMatrix function. It was working the way it was supposed to, but it ended up starting at the end of the run, meaning it would sum up positions (0,1) and (1,1) and then give me random numbers. So, I suspect I'm close here...I think it may have to do with where the return is located...

Actually, I just did a quick test. Instead of having it return result, I had it print what was being sent to the matrix using:

void Matrix::matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>
{
int sum;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
sum = matrix1.outputInput(i,j) + matrix2.outputInput(i,j);
result.setMatrix(i,j,sum);
}
}
result.printMatrix(R,C);
}

That right there just proved my implementation is working...because it prints out the results fine at that point. It's when I compare the results in the main.cpp and call matrix5.printMatrix(R,C) that I get crazy numbers...So somehow I have to figure out how to return the matrix result so it overwrites the matrix that's calling matrixAdd. I think I'm close...Any other help would be appreciated!

V/R

### #4 Skydiver

• Code herder

Reputation: 6155
• Posts: 21,226
• Joined: 05-May 12

Posted 07 July 2014 - 08:14 PM

For matrix addition and subtraction, you should never need your R and C parameters. This is because:

* Each matrix should store its number of rows and columns. You shouldn't have any need to to carry this around. A matrix should know this itself.

* You can only add and subtract matrices of the same dimensions.

Think of it this way: When you instantiate a car object and get it running up to a constant speed, the car should remember its speed. You shouldn't have to have a an extra variable outside of the car to keep track of the speed for the car.

Reputation: 1
• Posts: 79
• Joined: 07-July 14

Posted 08 July 2014 - 04:23 AM

...So...Huh. Heh, you know what. I just realized what I'm missing then...The most obvious thing of them all, the constructor. Right now all I've got is a 2D array of a fixed size. That's not really ideal in this case. What I need is something along the lines of:

Public:
Matrix();
Matrix(int R, int C);

Private:
int row, col;

Matrix.cpp

Matrix::Matrix()
{
row = 0;
col = 0;
}

Matrix::Matrix(int R, int C)
{
row = R;
col = C;
}

I think a bit of modification is required here. And absolutely right with the square matrix bit for addition/subtraction. So really, I can say:

public:
Matrix();
Matrix(int N);

private:
int NUM;

Matrix.cpp

Matrix()
{
NUM = 0;
}

Matrix(int N)
{
NUM = N;
}

The only reason I was setting it up for an M x N matrix was so I could expand upon the program later, but I think going simpler at this point will be helpful. Am I a bit more on the right track now?

### #6 baavgai

• Dreaming Coder

Reputation: 7160
• Posts: 14,924
• Joined: 16-October 07

Posted 08 July 2014 - 04:35 AM

class Matrix {
private:
// no, not really
// int matrix[50][50];
// better
int *data, rows, cols;

public:
Matrix(int rows, int cols); // store rows and calls, allocate data
~Matrix(); // always clean up
// input and output is kind of unclear
// void matrixInput(int R, int C); //This member function allows the user to manually input values into a matrix.
// void setMatrix(int R, int C, int sum); //This member function assigns values to a matrix.
// int outputInput(int R, int C); //This member function returns the value of a given matrix position.
int get(int row, int col) const; // note the const here, this operation doesn't change any data
void set(int row, int col, int value); // also note we've dropped "matrix" from method names; they are redundant

// expose size
int getRows() const;
int getCols() const;

// why the hell pass anything?
// void printMatrix(int R, int C); //This member function will print the contents of a matrix.
void print(std::ostream &) const; // note, we take the stream to send the output to

// the the above says is that we take another matrix, which is unchanged
// we do work, which doesn't change our instance
// and we return a new instance of Matrix as a result

};

// check the size
if (rows==other.getRows() && cols==other.getCols()) {
// good, we can do work
Matrix result(rows, cols);
for(int row=0; row<rows; row++) {
// you code here
}
return result;
} else {
// oops, they gave you a crap matrix
// figure out what you want to do about it
}
}

Hope this helps.

### #7 snoopy11

• Engineering ● Software

Reputation: 1460
• Posts: 4,726
• Joined: 20-March 10

Posted 08 July 2014 - 04:41 AM

Yes in addition to what Skydiver has said,

your class should have a validate function and a way of representing a matrix

so your constructor could look like

Matrix::Matrix(int r, int c)
{
Rows =r; //sets variable Rows
Cols = c; //sets variable Cols
matrix =  Array<double>(Rows, Cols); //Array is a template which dynamically allocates memory

srand((unsigned)time(NULL)); // For Randomize function
}

In which as Skydiver has said sets the Rows, and Cols to keep track of them.
matrix is a variable of type double**.

In this way we can dynamically size and even re-size arrays for the matrices.

A randomize function could look like..

void Matrix::Randomize(double min, double max)
{

double Random = rand() % max + min;

for (int r = 0; r < this->Rows; r++)
{
for (int c = 0; c < this->Cols; c++)
{
this->matrix[r][c] = Random;
Random = rand() % max + min;

}
}
}

This would be useful as then we could fill matrices with random values note the use of the this pointer.

A Clear function would be useful to zero a matrix of any size too.

For your Add function it would be easier to make the function take the address of 2 matrices as arguments

then use the this pointer and set the sum matrix to the value of the 1st Matrix and the 2nd Matrix at the specified array location.

This means looping through rows and cols and setting the values something like this.

double newvalue = Other1->matrix[j][i] + Other2->matrix[j][i];
this->matrix[j][i] = newvalue;

This is of course a rough idea of what you need to do I will leave you to fill in the details.

Snoopy.

Reputation: 1
• Posts: 79
• Joined: 07-July 14

Posted 08 July 2014 - 06:13 AM

You guys are awesome!

And, you'll laugh..but I've slowly come to the conclusions you all pointed out after just poking and prodding this thing. So, here's where I'm at right now.

Matrix.h
#include <iostream>

using namespace std;

enum {SIZE = 50}; //Rather than changing this in umpteen million places throughout the code, I decided to just create an ENUM where I can define it for the whole program.

class Matrix
{
private:
int ROW, COL;					//Declaring the rows and columns for the array.
int DATA[SIZE][SIZE];			//Declaring the 2D array that will hold all of our data, this uses my ENUM: SIZE which is set to 50.

public:
Matrix();						//The default constructor, will set rows and columns to 0.
Matrix(int M, int N);			//This definition allows for user defined arguments to be passed and define the rows (M) and columns (N) of the matrix.
~Matrix();						//The destructor.

int& operator()(int M, int N);	//Assignment operator, this is what allows something like: a(0,0) = 1. It is what assigns the passed data to the DATA[SIZE][SIZE] array.
Matrix(const Matrix &input);	//This is the copy constructor...In theory it's supposed to copy all the elements of a passed matrix to a new matrix...it...sort of works.

/*************************************************************************************************************
void matrixInput(int R, int C); //This member function allows the user to manually input values into a matrix.
void setMatrix(int R, int C, int sum); //This member function assigns values to a matrix.
int outputInput(int R, int C); //This member function returns the value of a given matrix position.
void printMatrix(int R, int C); //This member function will print the contents of a matrix.

void matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>;
void matrixSub(int R, int C, const Matrix &a, const Matrix &B)/>;
*************************************************************************************************************/
};

Matrix.cpp
#include "Matrix.h"

Matrix::Matrix()
{
ROW = 0;
COL = 0;
}

Matrix::Matrix(int M, int N)
{
ROW = M;
COL = N;
}

Matrix::~Matrix()
{
}

int& Matrix::operator ()(int M, int N)
{
if (M >= ROW || N >= COL)
{
cout << "Matrix Entry: [" << M << "][" << N << "] is out of Bounds." << endl;
}
return DATA[M][N];
}

Matrix::Matrix(const Matrix &input)
{
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
DATA[i][j] = input.DATA[i][j];
}
}
}

/*************************************************************************************************************
void Matrix::matrixInput(int R, int C)
{
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cout << "Please enter a value for: matrix[" << i+1 << "][" << j+1 << "].";
cin >> matrix[i][j];
}
}
}

void Matrix::setMatrix(int R, int C, int sum)
{
matrix[R][C] = sum;
}

int Matrix::outputInput(int R, int C)
{
return matrix[R][C];
}

void Matrix::printMatrix(int R, int C)
{
for (int i = 0; i < R; i++)
{
cout << "| ";
for (int j = 0; j < C; j++)
{
cout << matrix[i][j] << " ";
}
cout << "|\n";
}
}

void Matrix::matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>
{
int sum;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
sum = matrix1.outputInput(i,j) + matrix2.outputInput(i,j);
result.setMatrix(i,j,sum);
}
}
result.printMatrix(R,C);
}

void Matrix::matrixSub(int R, int C, const Matrix &a, const Matrix &B)/>
{
int dif;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
dif = matrix1.outputInput(i,j) - matrix2.outputInput(i,j);
result.setMatrix(i,j,dif);
}
}
result.printMatrix(R,C);
}
*************************************************************************************************************/

main.cpp
#include <iostream>

#include "Matrix.h"

using namespace std;

void main()
{
Matrix a(2,2);
a(0,0) = 5;
a(0,1) = 3;
a(1,0) = 1;
a(1,1) = 2;
a(2,0) = 4;

Matrix b(2,2);

b(0,0) = a(0,0);
b(1,1) = 7;
b(0,1) = 9;

Matrix c(B)/>;

cout << c(0,0) << endl;
cout << c(0,1) << endl;
cout << c(1,0) << endl;
cout << c(1,1) << endl;

/*************************************************************************************************************
Matrix matrix1;
Matrix matrix2;
Matrix sub;

int row = 2;
int col = 2;
int sum = 0;
int dif = 0;

cout << "Matrix 1" << endl;
matrix1.matrixInput(row,col);
cout << "Matrix 2" << endl;
matrix2.matrixInput(row,col);

cout << "Sum of 2 Matrices" << endl;

cout << "Difference of 2 Matrices" << endl;
sub.matrixSub(row, col, matrix1, matrix2);
*************************************************************************************************************/
}

I was playing around with the copy constructor in main.cpp, so don't mind the random weirdness there. But, within the confines of what I'm working on here, I've got this rig working. Where I was stumbling was, the fixed memory (and wasteful I know) size of 50x50 for the Array. It took me a bit to realize that the assignment operator piece was where I was assigning the values I pass to the array...once I sorted that out it started to click a bit better with what I was doing. The one thing now that's confusing me is why my error message keeps getting thrown. When I run this, on things like a[0,0] it'll throw the message 'this is out of bounds'...The only thing I can figure is that the ROW and COL bits aren't being reset, which means I probably need to add ROW and COL to the copy constructor to ensure that ROW and COL is set appropriately.

I thank you all for your help! I'm definitely learning a lot!

V/R

### #9 baavgai

• Dreaming Coder

Reputation: 7160
• Posts: 14,924
• Joined: 16-October 07

Posted 08 July 2014 - 06:53 AM

Don't forget to assign row and col in that copy constructor.

Prefer this form: Matrix::Matrix(int M, int N) : ROW(M), COL(N) { } Also, upper case generally means const in C++. Be consistent, M or ROW, not both. Or, better, rows. Because, you will want to operate on a single row.

Get rid of the empty constructor. You don't need a destructor, if you have nothing to clean up. If you used dynamic allocation, you'd have something to clean up.

### #10 snoopy11

• Engineering ● Software

Reputation: 1460
• Posts: 4,726
• Joined: 20-March 10

Posted 08 July 2014 - 11:58 AM

Yeah you could overload the + and = operators as baavgai has said to get a cleaner interface,

a theoretical implementation.

Matrix Matrix::operator+ (Matrix &Other)
{
int row = this->Rows;
int col = this->Cols;
this->Validate(Other.Rows, Other.Cols);

double** newMatrix= Array<double>(row,col);

for(int i =0; i<row; i++)
{
for(int j=0; j<col; j++)
{
double newvalue = this->matrix[i][j] + Other.matrix[i][j];
newMatrix[i][j] = newvalue;
}
}

return Matrix(newMatrix,row,col);// **see note
}

Matrix* Matrix::operator= (Matrix &Other)
{
for(int i =0; i<this->Rows; i++)
{
for(int j=0; j<this->Cols; j++)
{
this->matrix[i][j] = Other.matrix[i][j];
}
}

return this;
};

where **see note is an overloaded Matrix constructor which takes a source matrix. something like

Matrix::Matrix(double** sourceMatrix,int rSize, int cSize)
{
Rows = rSize;
Cols = cSize;
matrix= Array<double>(Rows,Cols);

for(int i =0; i<Rows; i++)
{
int j=0;
for(j=0; j<Cols; j++)
{
matrix[i][j]= sourceMatrix[i][j];
}
}

}

there are so many ways to implement this, but I would definitely go for dynamic allocation as opposed to a matrix of a MAX size, this is because to be useful a matrix could be used for so many things it could be used to form an AI or to store an image, I would prefer to use a generic class that I could reuse for any subject, but that is just me I guess.

Snoopy.

Reputation: 1
• Posts: 79
• Joined: 07-July 14

Posted 08 July 2014 - 04:49 PM

Here's my updated work ,and I have a question with it. Something I haven't quite been able to work out on my own.

Matrix.h
#include <iostream>

using namespace std;

enum {SIZE = 50};							//Rather than changing this in umpteen million places throughout the code, I decided to just create an ENUM where I can define it for the whole program.

class Matrix
{
private:
int rows, cols;							//Declaring the rows and columns for the array.
int data[SIZE][SIZE];					//Declaring the 2D array that will hold all of our data, this uses my ENUM: SIZE which is set to 50.

public:
Matrix();								//The default constructor, will set rows and columns to 0.
Matrix(int m, int n);					//This definition allows for user defined arguments to be passed and define the rows (M) and columns (N) of the matrix.

int& operator()(int m, int n);			//Assignment operator, this is what allows something like: a(0,0) = 1. It is what assigns the passed data to the DATA[SIZE][SIZE] array.
Matrix(const Matrix &input);			//This is the copy constructor...In theory it's supposed to copy all the elements of a passed matrix to a new matrix...it...sort of works.
Matrix operator+(const Matrix &input);	//The operator+ will add two matrices. I still have to add error checking mechanisms to ensure the matrices are square.
Matrix operator-(const Matrix &input);	//The operator- will subtract two matrices. I still have to add error checking mechanisms to ensure the matrices are square.

/*************************************************************************************************************
void matrixInput(int R, int C); //This member function allows the user to manually input values into a matrix.
void setMatrix(int R, int C, int sum); //This member function assigns values to a matrix.
int outputInput(int R, int C); //This member function returns the value of a given matrix position.
void printMatrix(int R, int C); //This member function will print the contents of a matrix.

void matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>;
void matrixSub(int R, int C, const Matrix &a, const Matrix &B)/>;
*************************************************************************************************************/
};

matrix.cpp
#include "Matrix.h"

Matrix::Matrix()
{
rows = 0;
cols = 0;
}
/*******************************************************************************************************************************************************
This is the parameterized Constructor which sets rows and columns for the matrix.
*******************************************************************************************************************************************************/
Matrix::Matrix(int m, int n)
{
rows = m;
cols = n;
}
/*******************************************************************************************************************************************************
The Assignment Operator allows users to enter data into the matrix in the form: matrix(m,n) = value;. This also tells the user if they are out of bounds,
say with a 2x2 matrix they enter matrix(2,0) = 4. Since it's a 2x2 matrix, and the range for the array is 0 to 1 (for a 2x2 matrix) it will let the user
know they have entered a value outside of this range.
*******************************************************************************************************************************************************/
int& Matrix::operator ()(int m, int n)
{
if (m >= rows || n >= cols)
{
cout << "Matrix Entry: [" << m << "][" << n << "] is out of Bounds." << endl;
}
return data[m][n];
}

Matrix::Matrix(const Matrix &input)
{
cout << "Copy Constructor." << endl;
rows = input.rows;
cols = input.cols;

for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
data[i][j] = input.data[i][j];
}
}

}

Matrix Matrix::operator+(const Matrix &input)
{
cout << "Operator+" << endl;
Matrix sum(rows,cols);

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
sum.data[i][j] = data[i][j] + input.data[i][j];
}
}
return sum;
}

Matrix Matrix::operator-(const Matrix &input)
{
cout << "Operator-" << endl;
Matrix dif(rows,cols);

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
dif.data[i][j] = data[i][j] - input.data[i][j];
}
}
return dif;
}

/*************************************************************************************************************
void Matrix::matrixInput(int R, int C)
{
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cout << "Please enter a value for: matrix[" << i+1 << "][" << j+1 << "].";
cin >> matrix[i][j];
}
}
}

void Matrix::setMatrix(int R, int C, int sum)
{
matrix[R][C] = sum;
}

int Matrix::outputInput(int R, int C)
{
return matrix[R][C];
}

void Matrix::printMatrix(int R, int C)
{
for (int i = 0; i < R; i++)
{
cout << "| ";
for (int j = 0; j < C; j++)
{
cout << matrix[i][j] << " ";
}
cout << "|\n";
}
}

void Matrix::matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>
{
int sum;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
sum = matrix1.outputInput(i,j) + matrix2.outputInput(i,j);
result.setMatrix(i,j,sum);
}
}
result.printMatrix(R,C);
}

void Matrix::matrixSub(int R, int C, const Matrix &a, const Matrix &B)/>
{
int dif;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
dif = matrix1.outputInput(i,j) - matrix2.outputInput(i,j);
result.setMatrix(i,j,dif);
}
}
result.printMatrix(R,C);
}
*************************************************************************************************************/

main.cpp
#include <iostream>

#include "Matrix.h"

using namespace std;

void main()
{
Matrix a(2,2);
a(0,0) = 1;
a(0,1) = 2;
a(1,0) = 3;
a(1,1) = 4;
//a(2,0) = 4;

Matrix b(2,2);

b(0,0) = 5;
b(0,1) = 6;
b(1,0) = 7;
b(1,1) = 8;

Matrix c(2,2);
c = a + b;

cout << c(0,0) << endl;
cout << c(0,1) << endl;
cout << c(1,0) << endl;
cout << c(1,1) << endl;

Matrix d(2,2);
d = a - b;

cout << d(0,0) << endl;
cout << d(0,1) << endl;
cout << d(1,0) << endl;
cout << d(1,1) << endl;

Matrix e(2,2);
e = b;
cout << e(0,0) << endl;
cout << e(0,1) << endl;
cout << e(1,0) << endl;
cout << e(1,1) << endl;

/*************************************************************************************************************
Matrix matrix1;
Matrix matrix2;
Matrix sub;

int row = 2;
int col = 2;
int sum = 0;
int dif = 0;

cout << "Matrix 1" << endl;
matrix1.matrixInput(row,col);
cout << "Matrix 2" << endl;
matrix2.matrixInput(row,col);

cout << "Sum of 2 Matrices" << endl;

cout << "Difference of 2 Matrices" << endl;
sub.matrixSub(row, col, matrix1, matrix2);
*************************************************************************************************************/
}

So here's my question...in the main.cpp I set a matrix equal to another matrix with:
e = b;

This doesn't use the copy constructor I've created for this purpose though. The thing I did note, and confirmed by having flags thrown when I enter into them, is that the copy constructor is used with the overloaded operators (which took me forever to figure out...but they are neat!). Why is this the case? I'm sure it's obvious, and something I should know, but I don't and I'm trying to understand the why's of what's going on. Is it because there is an under the hood operation going on, i.e. a default equals/copy operator?

Also, I do agree that a dynamic allocation would be the best solution for this. I went the way I went because it's a requirement for the program, and I don't understand the in's and outs of the dynamic allocation process enough yet to venture into those waters.

### #12 snoopy11

• Engineering ● Software

Reputation: 1460
• Posts: 4,726
• Joined: 20-March 10

Posted 08 July 2014 - 11:48 PM

In the case of e=b,

it does use a copy constructor but one that the compiler creates, this is termed a shallow copy if you overload the assignment operator '=' it will use the copy constructor you have provided.

Regards

Snoopy.

Reputation: 1
• Posts: 79
• Joined: 07-July 14

Posted 09 July 2014 - 06:40 AM

Awesome, okay! So now I get it, whereas the operator '=' is a 'deep copy' meaning it overwrites everything?

So, got a bit more clarification on the assignment, and...well, what I was doing was WAY overkill, but the good news is I've learned a crap ton through this process! I hadn't ever built my own operator overloads or anything like that before, so that's a win in my book. Ya'll have been awesome! Here's my modifications. The intent was to build specific helper functions to handle tasks we can do way more efficiently for the purposes of updating/changing data. I was able to simplify things a lot by making things based on a purely square matrix (which was pointed out above and I hadn't implemented yet). So..yeah. Here it is!

Matrix.h
#include <iostream>

using namespace std;

enum {SIZE = 50};								//Defines the maximum size of the Array used to store data.

class Matrix
{
private:
int rows, cols;								//Declaring the rows and columns for the array.
int data[SIZE][SIZE];						//Declaring the 2D array that will hold all of our data, this uses my ENUM: SIZE which is set to 50.

public:
Matrix();									//The default constructor, will set rows and columns to 0.
Matrix(int n);								//This definition allows for user defined arguments to be passed and define the rows (M) and columns (N) of the matrix.

void autoInput();							//This function will prompt the user to manually fill up the available spaces of a defined matrix.
void manualInput(int r, int c, int input);	//This function allows the user to manually input data into the matrix using: a.inputData(0,0,5);
void printMatrix();							//This function will print the contents of a matrix in a nice orderly fashion.
void setToZero();							//This function will set ALL spaces in a defined matrix to 0.
void copyMatrix(const Matrix &input);		//This function will copy the values of one matrix to another.
void subMatrices(const Matrix &left, const Matrix &right);	//Subtracts two passed matrices.

/*************************************************************************************************************
int& operator()(int r, int c);				//Assignment operator, this is what allows something like: a(0,0) = 1. It is what assigns the passed data to the data[SIZE][SIZE] array.
Matrix(const Matrix &input);				//This is the copy constructor...In theory it's supposed to copy all the elements of a passed matrix to a new matrix...it...sort of works.
Matrix operator+(const Matrix &input);		//The operator+ will add two matrices.
Matrix operator-(const Matrix &input);		//The operator- will subtract two matrices.
*************************************************************************************************************/

/*************************************************************************************************************
void matrixInput(int R, int C); //This member function allows the user to manually input values into a matrix.
void setMatrix(int R, int C, int sum); //This member function assigns values to a matrix.
int outputInput(int R, int C); //This member function returns the value of a given matrix position.
void printMatrix(int R, int C); //This member function will print the contents of a matrix.

void matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>;
void matrixSub(int R, int C, const Matrix &a, const Matrix &B)/>;
*************************************************************************************************************/
};

Matrix.cpp
#include "Matrix.h"
/*******************************************************************************************************************************************************
The default constructor. It initializes rows and columns to zero in the absence of actual useful data.
*******************************************************************************************************************************************************/
Matrix::Matrix()
{
rows = 0;
cols = 0;
}
/*******************************************************************************************************************************************************
This is the parameterized Constructor which sets rows and columns for the matrix.
*******************************************************************************************************************************************************/
Matrix::Matrix(int n)
{
rows = n;
cols = n;
}
/*******************************************************************************************************************************************************
This function is responsible for prompting the user to assign values to a matrix of defined size. Not fun for matrices much bigger than 2x2...there's a
lot of empty space to fill and it gets old quick.
*******************************************************************************************************************************************************/
void Matrix::autoInput()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "Please enter a value for: matrix[" << i+1 << "][" << j+1 << "].";
cin >> data[i][j];
}
}
}
/*******************************************************************************************************************************************************
This function is responsible for prompting the user to assign values to a matrix of defined size. Not fun for matrices much bigger than 2x2...there's a
lot of empty space to fill and it gets old quick.
*******************************************************************************************************************************************************/
void Matrix::manualInput(int r, int c, int input)
{
data[r][c] = input;
}
/*******************************************************************************************************************************************************
This function is responsible for jumping into your matrix and printing its contents to the screen. It gets all up in there and uses the Row and Column
information of the defined matrix as limit of advance for the for loops. It then cycles through the loops and couts the stored data like a boss.
*******************************************************************************************************************************************************/
void Matrix::printMatrix()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << data[i][j] << " ";
}
cout << "\n";
}
}
/*******************************************************************************************************************************************************
Sets the contents of a matrix to 0.
*******************************************************************************************************************************************************/
void Matrix::setToZero()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
data[i][j] = 0;
}
}
}
/*******************************************************************************************************************************************************
This function will copy the contents of one matrix to another.
*******************************************************************************************************************************************************/
void Matrix::copyMatrix(const Matrix &input)
{
Matrix copy(input.n);

for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
data[i][j] = input.data[i][j];
}
}
}
/*******************************************************************************************************************************************************
This function will add two matrices.
*******************************************************************************************************************************************************/
void Matrix::addMatrices(const Matrix &left, const Matrix &right)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
data[i][j] = left.data[i][j] + right.data[i][j];
}
}
}
/*******************************************************************************************************************************************************
This function will subract two matrices.
*******************************************************************************************************************************************************/
void Matrix::subMatrices(const Matrix &left, const Matrix &right)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
data[i][j] = left.data[i][j] - right.data[i][j];
}
}
}

/*******************************************************************************************************************************************************
The Assignment Operator allows users to enter data into the matrix in the form: matrix(m,n) = value;. This also tells the user if they are out of bounds,
say with a 2x2 matrix they enter matrix(2,0) = 4. Since it's a 2x2 matrix, and the range for the array is 0 to 1 (for a 2x2 matrix) it will let the user
know they have entered a value outside of this range.
*******************************************************************************************************************************************************/
/*******************************************************************************************************************************************************
int& Matrix::operator ()(int r, int c)
{
if (r >= rows || c >= cols)
{
cout << "Matrix Entry: [" << r << "][" << c << "] is out of Bounds." << endl;
}
return data[r][c];
}

Matrix::Matrix(const Matrix &input)
{
cout << "Copy Constructor." << endl;
rows = input.rows;
cols = input.cols;

for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
data[i][j] = input.data[i][j];
}
}
}

Matrix Matrix::operator+(const Matrix &input)
{
cout << "Operator+" << endl;
Matrix sum(n);

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
sum.data[i][j] = data[i][j] + input.data[i][j];
}
}
return sum;
}

Matrix Matrix::operator-(const Matrix &input)
{
cout << "Operator-" << endl;
Matrix dif(n);

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
dif.data[i][j] = data[i][j] - input.data[i][j];
}
}
return dif;
}
*******************************************************************************************************************************************************/
/*************************************************************************************************************
void Matrix::matrixInput(int R, int C)
{
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cout << "Please enter a value for: matrix[" << i+1 << "][" << j+1 << "].";
cin >> matrix[i][j];
}
}
}

void Matrix::setMatrix(int R, int C, int sum)
{
matrix[R][C] = sum;
}

int Matrix::outputInput(int R, int C)
{
return matrix[R][C];
}

void Matrix::printMatrix(int R, int C)
{
for (int i = 0; i < R; i++)
{
cout << "| ";
for (int j = 0; j < C; j++)
{
cout << matrix[i][j] << " ";
}
cout << "|\n";
}
}

void Matrix::matrixAdd(int R, int C, const Matrix &a, const Matrix &B)/>
{
int sum;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
sum = matrix1.outputInput(i,j) + matrix2.outputInput(i,j);
result.setMatrix(i,j,sum);
}
}
result.printMatrix(R,C);
}

void Matrix::matrixSub(int R, int C, const Matrix &a, const Matrix &B)/>
{
int dif;
Matrix matrix1 = a;
Matrix matrix2 = b;
Matrix result;

for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
dif = matrix1.outputInput(i,j) - matrix2.outputInput(i,j);
result.setMatrix(i,j,dif);
}
}
result.printMatrix(R,C);
}
*************************************************************************************************************/

main.cpp
#include <iostream>

#include "Matrix.h"

using namespace std;

void main()
{
cout << "Matrix a:" << endl;
Matrix a(2);
cout << "Using: manualInput(r, c, input)" << endl;
a.manualInput(0,0,1);
a.manualInput(0,1,2);
a.manualInput(1,0,3);
a.manualInput(1,1,4);
a.printMatrix();

cout << "Matrix b:" << endl;
Matrix b(2);
cout << "Using: autoInput()" << endl;
b.autoInput();
b.printMatrix();

Matrix c(2);
cout << "Using: addMatrices(a,B)/>" << endl;
c.printMatrix();
cout << "Using: subMatrices(a,B)/>" << endl;
c.subMatrices(a,B)/>;
c.printMatrix();
cout << "Using: setToZero()" << endl;
c.setToZero();
c.printMatrix();
cout << "Using: copyMatrix(a)" << endl;
c.copyMatrix(a);
c.printMatrix();

/*************************************************************************************************************
Matrix matrix1;
Matrix matrix2;
Matrix sub;

int row = 2;
int col = 2;
int sum = 0;
int dif = 0;

cout << "Matrix 1" << endl;
matrix1.matrixInput(row,col);
cout << "Matrix 2" << endl;
matrix2.matrixInput(row,col);

cout << "Sum of 2 Matrices" << endl;

cout << "Difference of 2 Matrices" << endl;
sub.matrixSub(row, col, matrix1, matrix2);
*************************************************************************************************************/
}

I'm happy though because I'm definitely set up for expansion and streamlining thanks to the things I learned working on this. I'm not saying I'm done, but I've achieved the intended end state. Will definitely experiment with this more. I'll be needing it for the future flight sim I hope to one day code. Thank you all!

### #14 Skydiver

• Code herder

Reputation: 6155
• Posts: 21,226
• Joined: 05-May 12

Posted 09 July 2014 - 06:47 AM

Actually, I was just pointing out that matrix addition and subtraction require that both matrices have the same dimensions. They need not be square. The following assertions must be true:

Notice that there is no assertion that augend.getRowCount() == addend.getColumnCount().

What having a square matrix does, though, is it will help you write parallelized algorithms a lot more simply, but that is for later in your programming learning curve.

This post has been edited by Skydiver: 09 July 2014 - 07:11 AM
Reason for edit:: Fixed inline code tags to be real code tags.

### #15 snoopy11

• Engineering ● Software

Reputation: 1460
• Posts: 4,726
• Joined: 20-March 10

Posted 09 July 2014 - 07:45 AM

Just for your own benefit now you are done with this....

This is a fragment from a Matrix Library I wrote to do some AI work.

main.cpp

#include <iostream>
#include "Matrix.h"

int main()

{
Matrix One(2,4);
Matrix Two(2,4);
Matrix Sum(2,4);

One.Randomize(1,20);
Two.Randomize(1,20);
Sum.Clear();

Sum = One + Two;

std::cout << "Matrix 1:" << std::endl;
One.Print();
std::cout << std::endl << "Matrix 2:" << std::endl;
Two.Print();
std::cout << std::endl << "Sum of 1 and 2:" << std::endl;
Sum.Print();

std::cin.get(); // used to hold window open replace as you see fit//
return 0;

}

Matrix.h

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <limits>
#include <iostream>
#include <sstream>

template <typename T>
T **Array( int x, int y)
{
T **dynamicArray;

dynamicArray = new T*[x];
for( int i = 0 ; i < x ; i++ )
dynamicArray[i] = new T [y];

return dynamicArray;
}

template <typename T>
void FreeArray(T** dArray)
{
delete [] *dArray;
delete [] dArray;
}

class Matrix
{

public:

Matrix(int r, int c);
Matrix(double** sourceMatrix, int rSize, int cSize);

~Matrix();

Matrix operator+(Matrix &Other);
Matrix* operator=(Matrix &Other);
void Clear();
void Randomize(int min, int max);
void Print();
double** matrix;

private:
void Validate(int row, int col);
int Rows;
int Cols;

};

class MatrixError
{
public:
std::string message;
MatrixError(std::string text);

};

Matrix.cpp

#include "Matrix.h"

Matrix::Matrix(int r, int c):Rows(r),Cols(c)
{

matrix =  Array<double>(Rows, Cols); //Array is a template which dynamically allocates memory

srand((unsigned)time(NULL)); // For Randomize function
}

Matrix::Matrix(double** sourceMatrix,int rSize, int cSize)
{
Rows = rSize;
Cols = cSize;
matrix= Array<double>(Rows,Cols);

for(int i =0; i<Rows; i++)
{
int j=0;
for(j=0; j<Cols; j++)
{
matrix[i][j]= sourceMatrix[i][j];
}
}

}

Matrix::~Matrix()
{
FreeArray(matrix);

}

Matrix Matrix::operator+ (Matrix &Other)
{
int row = this->Rows;
int col = this->Cols;
this->Validate(Other.Rows, Other.Cols);

double** newMatrix= Array<double>(row,col);

for(int i =0; i<row; i++)
{
for(int j=0; j<col; j++)
{
double newvalue = this->matrix[i][j] + Other.matrix[i][j];
newMatrix[i][j] = newvalue;
}
}

return Matrix(newMatrix,row,col);
}

Matrix* Matrix::operator= (Matrix &Other)
{
for(int i =0; i<this->Rows; i++)
{
for(int j=0; j<this->Cols; j++)
{
this->matrix[i][j] = Other.matrix[i][j];
}
}

return this;
};

void Matrix::Clear()
{
for(int i =0; i<Rows; i++)
{
for(int j=0; j<Cols; j++)
{
this->matrix[i][j] =0;
}
}
}

void Matrix::Randomize(int min, int max)
{

double Random = rand() % max + min;

for (int r = 0; r < this->Rows; r++)
{
for (int c = 0; c < this->Cols; c++)
{

this->matrix[r][c] = Random;
Random = rand() % max + min;

}
}
}

void Matrix::Print()
{
for (int r = 0; r < this->Rows; r++)
{
for (int c = 0; c < this->Cols; c++)
{
std::cout << this->matrix[r][c] << " ";
}
std::cout << std::endl;
}
};

//private member function

void Matrix::Validate(int row, int col)
{

std::stringstream messagebuilder;
messagebuilder.clear();

if ((row != this->Rows) || (row < 0))
{
messagebuilder << "The row: " << row << " is not equal at " << this->Rows;
throw new MatrixError(messagebuilder.str());
}

if ((col != this->Cols) || (col < 0))
{

messagebuilder << "The col: " << col << " is not equal at " << this->Cols;
throw new MatrixError(messagebuilder.str());
}
}

//Class MatrixError starts here

#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
#include<Windows.h>            // used for MessageBox only

MatrixError::MatrixError(std::string text)
{
message.assign(text);
MessageBox(NULL,message.c_str(),"Matrix Error",MB_OK);
};

It is definitely better to write your own code but sometimes also good after you have worked out a problem to see how others have approached it, to gain further insight into the problem.

Best of Luck with the studies,

Snoopy.