I have a 3x3 matrix with values:
(0,0)=3
(1,1)=4
(2,0)=2.4
the rest of the values are zero
and the code:

#include <iostream>
using namespace std;

class sMatrix
{
public:
	sMatrix();
	sMatrix(int,int);
	int getR();
	int getC();
	bool rValid(int);
	bool cValid(int);
	void setEl(int,int,double);
	double getEl(int i,int j);
	void print();
	
private:
	int nr, nc;	//number of row and cols
	int nent;	//number of entries
	int nmax;	//the max number of entries
	double *data;	//store the data, the size of the storage is nmax*3
};

sMatrix::sMatrix(int rr,int cc)
{
	nr=rr;
	nc=cc;
	nent=0;
	nmax=(nr*nc)/2;
	data=new double [3*nmax];
	for (int i=0; i<3*nmax; i++)
		data [i]=0.0;
}

int sMatrix::getR()
{
	return nr;
}

int sMatrix::getC()
{
	return nc;
}

bool sMatrix::rValid(int r)
{
	if (r<0 || r>=nr)
		return false;
	return true;
}

bool sMatrix::cValid(int r)
{
	if (r<0 || r>=nc)
		return false;
	return true;
}

void sMatrix::setEl(int r,int c, double val)
{
	int i;
	if (rValid(r) && cValid(c))
	{
		i=3*nent;
		data[i]=r;
		data[i+1]=c;
		data[i+2]=val;
		nent++;
	}
}

void sMatrix::print()
{
	int i;
	for (i=0;i<3*nent;i+=3)
	{
		cout<<"<"<<data[i]<<",";
		cout<<""<<data[i+1]<<",";
		cout<<""<<data[i+2]<<">"<<endl;
	}
}

void main ()
{
	sMatrix M(3,3),N(3,3);
	M.setEl(0,0,3);
	M.setEl(1,1,4);
	M.setEl(2,0,2.4);
	M.print();
        N.setEl(0,0,3);
	N.setEl(1,1,4);
	N.setEl(2,0,2.4);
        N.print();
	M.add(N);   //I know this needs to be in the code someplace
        M.print();
}

This part is given by the professor and I have to work with it:

sMatrix::sMatrix(int rr,int cc)
{
	nr=rr;
	nc=cc;
	nent=0;
	nmax=(nr*nc)/2;
	data=new double [3*nmax];
	for (int i=0; i<3*nmax; i++)
		data [i]=0.0;
}

Needs:
1) a getVal function that retrieves the value of the element row i and column j. (The function mst check both i and j values are in range)

2)Provide a putVal function that puts a value v in rown i and column j. This operation must make sure that i and j values do not exists in the storage.

3) a funtion to print the matrix in full form or in triple form.

4) should do addition, subtraction, and multiplication

I've been playing with the code to get the things I need but nothing is working.

Recommended Answers

All 11 Replies

>>I've been playing with the code to get the things I need but nothing is working.

That's nice -- now post the code you tried because we are not clairvoyant.

>>I've been playing with the code to get the things I need but nothing is working.

That's nice -- now post the code you tried because we are not clairvoyant.

#include <iostream>
using namespace std;

class sMatrix
{
public:
	sMatrix();
	sMatrix(int,int);
	int getR();
	int getC();
	bool rValid(int);
	bool cValid(int);
	void setEl(int,int,double);
	double getEl(int i,int j);
	int getVal(int,int);
	void print();
	void add();
private:
	int nr, nc;	//number of row and cols
	int nent;	//number of entries
	int nmax;	//the max number of entries
	double *data;	//store the data, the size of the storage is nmax*3
};

sMatrix::sMatrix(int rr,int cc)
{
	nr=rr;
	nc=cc;
	nent=0;
	nmax=(nr*nc)/2;
	data=new double [3*nmax];
	for (int i=0; i<3*nmax; i++)
		data [i]=0.0;
}

int sMatrix::getR()
{
	return nr;
}

int sMatrix::getC()
{
	return nc;
}

bool sMatrix::rValid(int r)
{
	if (r<0 || r>=nr)
		return false;
	return true;
}

bool sMatrix::cValid(int r)
{
	if (r<0 || r>=nc)
		return false;
	return true;
}

void sMatrix::setEl(int r,int c, double val)
{
	int i;
	if (rValid(r) && cValid(c))
	{
		i=3*nent;
		data[i]=r;
		data[i+1]=c;
		data[i+2]=val;
		nent++;
	}
}

void sMatrix::print()
{
	int i;
	for (i=0;i<3*nent;i+=3)
	{
		cout<<"<"<<data[i]<<",";
		cout<<""<<data[i+1]<<",";
		cout<<""<<data[i+2]<<">"<<endl;
	}
}


int sMatrix::getVal(int row,int col)
{
	return nmax[row,col];	//sunscript requires array or pointer
}


void sMatrix::add()
{
	int i,j;
	for (i=0;i<=nr;i++)
	{	
		for (j=0;j<=nc;j++)
		{
			m(i,j)+=n(i,j);	//m and n undeclared identifier
		}
	}
}

void main ()
{
	sMatrix M(3,3);
	M.setEl(0,0,3);
	M.setEl(1,1,4);
	M.setEl(2,0,2.4);
	M.print();
	sMatrix N(3,3);
	N.setEl(0,0,3);
	N.setEl(1,1,4);
	N.setEl(2,0,2.4);
	N.print();
	M.add(N);
	M.print();
}

Now tell us what is wrong with the code you posted? Compiler errors? Yes, then post some of them.

I've messed with the code some more since the last time. the red comments are compiler error messages

#include <iostream>
using namespace std;

class sMatrix
{
public:
	sMatrix(int,int);
	sMatrix (sMatrix&);
	int getR();
	int getC();
	bool rValid(double);
	bool cValid(double);
	void setEl(double,double,double);
	double getEl(int i,int j);
	int getVal();
	void print();
	void add(sMatrix&);
private:
	int nr, nc;	//number of row and cols
	int nent;	//number of entries
	int nmax;	//the max number of entries
	double *data;	//store the data, the size of the storage is nmax*3
};

sMatrix::sMatrix(int rr,int cc)
{
	nr=rr;
	nc=cc;
	nent=0;
	nmax=(nr*nc)/2;
	data=new double [3*nmax];
	for (int i=0; i<3*nmax; i++)
		data [i]=0.0;
}

int sMatrix::getR()
{
	return nr;
}

int sMatrix::getC()
{
	return nc;
}

bool sMatrix::rValid(double r)
{
	if (r<0 || r>=nr)
		return false;
	return true;
}

bool sMatrix::cValid(double r)
{
	if (r<0 || r>=nc)
		return false;
	return true;
}

void sMatrix::setEl(double r,double c, double val)
{
	int i;
	if (rValid(r) && cValid(c))
	{
		i=3*nent;
		data[i]=r;
		data[i+1]=c;
		data[i+2]=val;
		nent++;
	}
}

void sMatrix::print()
{
	int i;
	for (i=0;i<3*nent;i+=3)
	{
		cout<<"<"<<data[i]<<",";
		cout<<""<<data[i+1]<<",";
		cout<<""<<data[i+2]<<">"<<endl;
	}
}


int sMatrix::getVal()
{
	int i,j;
	for (j=0;nent--;j++)
		i=j*3;
		if (nr==data[i] && nc==data[i+1])
			return data[i+2];     //conversion from double to int possible loss of data
		else
			return 0;	
}


void sMatrix::add(sMatrix &N)
{
	int i,j;
	for (i=0;i<=nr;i++)
	{	
		for (j=0;j<=nc;j++)
		{
			setEl(i,j)+=N.setEl(i,j);	//function doesn't take 2 arguments
		}
	}
}

void main ()
{
	sMatrix M(3,3);
	M.setEl(0,0,3);
	M.setEl(1,1,4);
	M.setEl(2,0,2.4);
	M.print();
	sMatrix N(3,3);
	N.setEl(0,0,3);
	N.setEl(1,1,4);
	N.setEl(2,0,2.4);
	N.print();
	M.add(N);
	M.print();
}

//For the rest of the project it needs:
//1) a getVal function that retrieves the value of the element row i and column j.
//(The function mst check both i and j values are in range)
//2)Provide a putVal function that puts a value v in rown i and column j.
//This operation must make sure that i and j values do not exists in the storage.
//3) a funtion to print the matrix in full form or in triple form.
//4) should do addition, subtraction, and multiplication

>conversion from double to int possible loss of data

Return data type of getVal() must be double.

double sMatrix::getVal() {
  ...
 }

>function doesn't take 2 arguments

Method setEl() has three parameters. e.g setEl(row,col,value) First two parameters must be int type.

Replace setEl(i,j)+=N.setEl(i,j) with,

setEl(i,j, getEl(i,j) + N.getEl(i,j));

Following-on from some of your comments in the thread that has been closed on this some basic things to note:

This is not a standard way of dealing with matrices and the name of
the class is misleading.

What is happening is that the data is being logged as a series of
points with each value having a row and column stored for it

In the constructor I am still uneasy about the nmax = nr*nc/2;
for your example nr = 3, nc = 3 so nmax = 4 (rounds down as int)
And therefore you can only have four records maximum even for a sparse matrix this can be an issue for adding.

As you have started to write your get_val needs to search the data
until it finds the point that you are looking for to find the value.

You have a mistake in your for loop stop condition: for(j = 0; nent--; j++) you are changing nent each time you go through the loop so when you set the next value...

When you add
+= (is a special function known as an operator so does not exist for your new class);
you need to add an element by
check size of M & N are the same
getting all of the elements from N
see for any element N != 0
then you need to find the i, j for N use this to get the current
M value for this i &j
add the N value to the M value and set the M value

if you think about the problem the functions you need to achieve this class should be obvious.

However, this introduces another issue if you
call set on the same point then there is a problem that the old value is not replaced
say you have this scheme
[0,0] = 2.3
[1,1] = 5.6
[2,2] = 1.1
now if you set
[1, 1] = 4.4

data looks like:
0,
0,
2.3,
1,
1,
5.6,
2,
2,
1.1,
1,
1,
4.4
so you cannot use Set without changing the function to match get
so you might want a function to find the index of data that matches
an r c value int find_data_index(int r, int c); return -1 if not found and double get_value(int data_index); then get_value returns 0.0 if not found void set_value(int index, double value); then you can use set_value if find_data_index != -1

@tetron
Some additional material for this thread can be found here as well

#include <iostream>
using namespace std;

class sMatrix
{
public:
	sMatrix(int,int);
	sMatrix (sMatrix&);
	int getR();
	int getC();
	bool rValid(double);
	bool cValid(double);
	void setEl(double,double,double);
	double getEl(int i,int j);
	double getVal(int, int);
	void print();
	void add(sMatrix&);
	void sub(sMatrix&);
private:
	int nr, nc;	//number of row and cols
	int nent;	//number of entries
	int nmax;	//the max number of entries
	double *data;	//store the data, the size of the storage is nmax*3
};

sMatrix::sMatrix(int rr,int cc)
{
	nr=rr;
	nc=cc;
	nent=0;
	nmax=(nr*nc)/2;
	data=new double [3*nmax];
	for (int i=0; i<3*nmax; i++)
		data [i]=0.0;
}

int sMatrix::getR()
{
	return nr;
}

int sMatrix::getC()
{
	return nc;
}

bool sMatrix::rValid(double r)
{
	if (r<0 || r>=nr)
		return false;
	return true;
}

bool sMatrix::cValid(double r)
{
	if (r<0 || r>=nc)
		return false;
	return true;
}

void sMatrix::setEl(double r,double c, double val)
{
	int i;
	if (rValid(r) && cValid(c))
	{
		// when adding a new value
		i=3*nent;
		data[i]=r;
		data[i+1]=c;
		data[i+2]=val;
		nent++;
		//spots already exists so update value
	}
}

void sMatrix::print()
{
	int i;
	for (i=0;i<3*nent;i+=3)
	{
		cout<<"<"<<data[i]<<",";
		cout<<""<<data[i+1]<<",";
		cout<<""<<data[i+2]<<">"<<endl;
	}
}


double sMatrix::getVal(int i, int j)
{
	// search through data for a give i,j
	// and if it finds (i,j) return value
	// otherwise return 0
	for(int c=0;c<3*nent;c+=3)
	{
		if(data[c]==i && data[c+1]==j)
			return data[c+2];
	}
	return 0;
}


void sMatrix::add(sMatrix &N)
{
	int i,j;
	for (i=0;i<=nr;i++)
	{	
		for (j=0;j<=nc;j++)
		{
			double Val1=getVal(i,j);
			double Val2=N.getVal(i,j);
			double Val=Val1+ Val2;
			if(Val!=0)
			{
			setEl(i,j,Val1+Val2);
			}
		}
	}
}

void sMatrix::sub(sMatrix &N)
{
	int i,j;
	for (i=0;i<=nr;i++)
	{	
		for (j=0;j<=nc;j++)
		{
			double Val1 =getVal(i,j);
			double Val2 =N.getVal(i,j);
			double Val =Val1-Val2;
			if(Val!=0)
			{
			setEl(i,j,Val1-Val2);
			}
		}
	}
}

int main ()
{
	sMatrix M(3,3);
	M.setEl(0,0,3);
	M.setEl(1,1,4);
	M.setEl(2,0,2.4);
	cout<<"Matrix M is: "<<endl;
	M.print();

	sMatrix N(3,3);
	N.setEl(1,0,-3);
	N.setEl(1,0,0);
	N.setEl(2,0,2.4);
	cout<<"Matrix N is: "<<endl;
	N.print();
	
	cout<<"The sum of the matrix is: "<<endl;
	M.add(N);
	M.print();
	
	cout<<"The difference of the matrix is: "<<endl;
	M.sub(N);
	M.print();
}

So I've worked on it some more and what I get is for it to print M and N, and then it crashes, the part is red is all i need to figure out and hopefully it'll work.

If you want to leave setEl intact what you could do is have your methods return an object of type matrix that you create and put your summed values into (same idea for subtraction). That way your counts are right and it might even be a bit cleaner than overwriting.

Otherwise, decouple setEl and the nent counter and have a "shell" method to use from main() that calls setEl and then increments the counter when it's necessary (so in your add method you would call the plain setEl without the counter).

#include <iostream>
using namespace std;

class sMatrix
{
public:
	sMatrix(int,int);
	sMatrix (sMatrix&);
	int getR();
	int getC();
	bool rValid(double);
	bool cValid(double);
	void setEl(double,double,double);
	double getEl(int i,int j);
	double getVal(int, int);
	void print();
	void add(sMatrix&);
	void sub(sMatrix&);
private:
	int nr, nc;	//number of row and cols
	int nent;	//number of entries
	int nmax;	//the max number of entries
	double *data;	//store the data, the size of the storage is nmax*3
};

sMatrix::sMatrix(int rr,int cc)
{
	nr=rr;
	nc=cc;
	nent=0;
	nmax=(nr*nc)/2;
	data=new double [3*nmax];
	for (int i=0; i<3*nmax; i++)
		data [i]=0.0;
}

int sMatrix::getR()
{
	return nr;
}

int sMatrix::getC()
{
	return nc;
}

bool sMatrix::rValid(double r)
{
	if (r<0 || r>=nr)
		return false;
	return true;
}

bool sMatrix::cValid(double r)
{
	if (r<0 || r>=nc)
		return false;
	return true;
}

void sMatrix::setEl(double r,double c, double val)
{
	int i;
	if (rValid(r) && cValid(c))
	{
		// when adding a new value
		i=3*nent;
		data[i]=r;
		data[i+1]=c;
		data[i+2]=val;
		nent++;
		//spots alreayd exists so update value
	}
}

void sMatrix::print()
{
	int i;
	for (i=0;i<3*nent;i+=3)
	{
		cout<<"<"<<data[i]<<",";
		cout<<""<<data[i+1]<<",";
		cout<<""<<data[i+2]<<">"<<endl;
	}
}


double sMatrix::getVal(int i, int j)
{
	// search through data for a give i,j
	// and if it finds (i,j) return value
	// otherwise return 0
	for(int c=0;c<3*nent;c+=3)
	{
		if(data[c]==i && data[c+1]==j)
			return data[c+2];
	}
	return 0;
}


void sMatrix::add(sMatrix &N)
{
	int i,j;
	for (i=0;i<=nr;i++)
	{	
		for (j=0;j<=nc;j++)
		{
			double Val1=getVal(i,j);
			double Val2=N.getVal(i,j);
			double Val=Val1+ Val2;
			if(Val!=0)
			{
			setEl(i,j,Val1+Val2);
			}
		}
	}
}

void sMatrix::sub(sMatrix &N)
{
	int i,j;
	for (i=0;i<=nr;i++)
	{	
		for (j=0;j<=nc;j++)
		{
			double Val1 =getVal(i,j);
			double Val2 =N.getVal(i,j);
			double Val =Val1-Val2;
			if(Val!=0)
			{
			setEl(i,j,Val1-Val2);
			}
		}
	}
}

int main ()
{
	sMatrix M(3,3);
	M.setEl(0,0,3);
	M.setEl(1,1,4);
	M.setEl(2,0,2.4);
	cout<<"Matrix M is: "<<endl;
	M.print();

	sMatrix N(3,3);
	N.setEl(1,0,-3);
	N.setEl(1,0,0);
	N.setEl(2,0,2.4);
	cout<<"Matrix N is: "<<endl;
	N.print();
	
	cout<<"The sum of the matrix is: "<<endl;
	M.add(N);
	M.print();
	
	cout<<"The difference of the matrix is: "<<endl;
	M.sub(N);
	M.print();
}

can someone just help me with the green part specifically the red part

commented: No code tags! -5

Now the main problem with this function is that your nmax should be at least the size of of the elements in your matrix but ignoring
this problem

to see if an element exists simply means to check if getVal == 0;
this has an overhead so why no just reuse your code

//needs a bool to let you know
bool SetVal(int i, int j, double Val)
{
  bool ret(false);
if(rValid(i) == true && cValid(j) == true)
{
//valid coordinate so
ret = true;
  for(int c=0;c<3*nent;c+=3)
  {
     if(data[c]==i && data[c+1]==j)
     {
         //must be ok to set
         data[c + 2] = Val;
        return ret;
      }
   }
//we have a new coord
++nent;
 if(nent < nmax)
 { 
//original code for SetVAl
    int ind =3*nent;
   data[ind]=i;
   data[ind+1]=j;
   data[ind+2]=Val;
 }
 else
 {
  //overflow why you need a bigger max
  }
}
else
{
//coordinate out of range
}

return ret;
}

you should check that both matrices have same width and height before adding and subtracting


for multiplying you will have to change nmax = nr*nc /2; lose the /2
so

nmax = nr *nc;

the only thing that I have not covered is that if setVal takes a
Val of 0
that you will wnat to remove the entry from the list
and you might sort the list for a real application

void sMatrix::setEl(double r,double c, double val)
{
	int i;
	if (rValid(r) && cValid(c))
	{
		// when adding a new value
		i=3*nent;
		data[i]=r;
		data[i+1]=c;
		data[i+2]=val;
		nent++;
		//spots alreayd exists so update value

can someone just help me with the green part specifically the red part

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.