I'm trying to write a test for a program that adds the product of matrices A and X to the matrix Y.
But I got the error:
"Identifier is required"
I couldn't solve or find a solution to this problem, so I ask for help here.
At first, I thought that the problem is that I compare it with the wrong array. Then I tried to pass other arguments. Dismembered my code into several functions. But still, nothing happened.
#include<iostream>
#include<cassert>
using namespace std;
void axpy(int n, int m, int k, int **A, int **X, int **Y)
{
int i, j, q;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
for (q = 0; q < k; q++)
{
Y[i][j] += A[i][q] * X[q][j];
}
}
}
cout << "Product of matrices\n";
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
cout << Y[i][j] << " ";
cout << "\n";
}
}
void TestAxpy()
{
int P[2][2] = { {13,11},{27,21} };
assert(axpy(2,2,2,[1,2][3,4],[4,3][2,1],[5,6][7,8]) == P);
}
int main()
{
int n, m, k, i, j, q;
cout << "Enter number of rows of matrix X and columns of matrix A: ";
cin >> k;
cout << "Enter number of rows of matrix A and Y: ";
cin >> n;
cout << "Enter number of columns of matrix X and Y: ";
cin >> m;
int **A = new int *[k];
for (i = 0; i < k; i++)
A[i] = new int[n];
int **X = new int *[m];
for (i = 0; i < m; i++)
X[i] = new int[k];
int **Y = new int *[m];
for (i = 0; i < m; i++)
Y[i] = new int[n];
cout << "Enter elements of matrix A: ";
for (i = 0; i < n; i++)
for (j = 0; j < k; j++)
cin >> A[i][j];
cout << "Enter elements of matrix X: ";
for (i = 0; i < k; i++)
for (j = 0; j < m; j++)
cin >> X[i][j];
cout << "Enter elements of matrix Y: ";
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
cin >> Y[i][j];
axpy(n, m, k, A, X, Y);
TestAxpy();
system("pause");
return 0;
}
I wanted to get a 2x2 matrix with the results of [13, 11] [27 21]. The input I used such as:
Enter number of rows of matrix X and columns of matrix A: 2
Enter number of rows of matrix A and Y: 2
Enter number of columns of matrix X and Y: 2
Enter elements of matrix A: 1 2 3 4
Enter elements of matrix X: 4 3 2 1
Enter elements of matrix Y: 5 6 7 8
This seems like a mix of C and C++. In C++ it is rare you need to use raw "C" arrays, almost always std::vector<> or std::array<> will be a better choice. There is also matrix in the boost library which will store exactly what you need.
In terms of your specific code there are two issues:
Pointers to pointers (**) are no the same thing as two dimension arrays. They are a two-layer indirection. The first are pointers to locations in memory that store the second layer in memory. See below for how it would need to work to be able to call axpy. Again would strongly recommend looking at std::vector or boost libraries.
The "==" operator won't work that way for C arrays. You need to specify how you want the comparison to happen. As written it will at best just compare memory address, but more likely will produce an error.
void TestAxpy()
{
int P[2][2] = { {13,11},{27,21} };
int A1[2] = {1,2};
int A2[2] = {3,4};
int* A[2] = { A1, A2 };
int X1[2] = {4,3};
int X2[2] = {2,1};
int *X[2] = { X1, X2 };
int Y1[2];
int Y2[2];
int *Y[2] = {Y1, Y2 };
axpy(2,2,2,A,X,Y);
//assert(Y == P); //C++ doesn't know how to do this.
}
Related
This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 2 years ago.
I am trying to write a matrice class in c++ with a overloaded + operator that is a friend function for summing a matrix with a number, ie sum every element of the matrice with the number.
for example:-
2+ |1|2| = |3|4|
|2|1| |4|3|
main.cpp :-
#include <iostream>
using namespace std;
class matrice {
int** a;
int rows, columns, i, j;
public:
matrice() {}
matrice(matrice& A) { //copy constructor for deep copying the result of 2+A into C
rows = A.rows;
columns = A.columns;
a = new int* [rows];
for (i = 0; i < rows; i++) {
a[i] = new int[columns];
*a[i] = 0;
}
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
a[i][j] = A.a[i][j];
}
}
}
matrice(int m, int n) {
rows = m;
columns = n;
a = new int* [rows];
for (i = 0; i < rows; i++) {
a[i] = new int[columns];
*a[i] = 0;
}
}
~matrice() {
delete[] a;
}
void insert(int p, int q, int value) {
a[p][q] = value;
}
void print() {
for (i = 0; i < rows; i++) {
cout << "\n";
for (j = 0; j < columns; j++) {
cout << a[i][j] << " ";
}
}
}
friend matrice operator+(int k, matrice& A);
friend matrice operator+(matrice& A, int k);
};
matrice operator+(int k, matrice& A) { //for performing 2+A
matrice temp(A.rows, A.columns);
for (int i = 0; i < A.rows; i++) {
for (int j = 0; j < A.columns; j++) {
temp.a[i][j] = A.a[i][j] + k;
}
}
return temp;
}
matrice operator+(matrice& A, int k) { //for performing A+2
matrice temp(A.rows, A.columns);
for (int i = 0; i < A.rows; i++) {
for (int j = 0; j < A.columns; j++) {
temp.a[i][j] = A.a[i][j] + k;
}
}
return temp;
}
int main() {
int i, j, m, n, value;
cout << "\nEnter order of A matrice:";
cin >> m >> n;
matrice A(m, n);
cout << "\nEnter the matrice:";
for (i = 0; i < m; i++) {
cout << "\nEnter row " << i + 1 << " : ";
for (j = 0; j < n; j++) {
cin >> value;
A.insert(i, j, value);
}
}
cout << "\nThe entered matrice is :";
A.print();
cout << "\n\n";
cout << "\nEnter order of B matrice:";
cin >> m >> n;
matrice B(m, n);
cout << "\nEnter the matrice:";
for (i = 0; i < m; i++) {
cout << "\nEnter row " << i + 1 << " : ";
for (j = 0; j < n; j++) {
cin >> value;
B.insert(i, j, value);
}
}
cout << "\nThe entered matrice is :";
B.print();
cout << "\n\ntesting 2+A";
matrice C; //Everything upto here is fine
C = A + 2; // C.a is pointing to unreadable memory because of destruction after doing A+2
C.print(); // so access violation error
}
The problem is that the destructor of C is called after invoking the copy constructor which causes the double pointer a in C to be deleted. So when C.print() is called An Access violation reading location 0xDDDDDDDD exception is thrown.
I can't find out why C's destructor is called.
The rule of 5 says that if you manually handle allocations, you should have an explicit (or explicitely deleted):
copy constructor
copy assignment operator
move constructor
move assignement operator
destructor
You might omit the ones that you are sure that you code will never use, but it is highly dangerous.
Anyway correct allocation/de-allocation handling is complex and requires very cautious code. For example the correct declaration for a copy ctor should be matrice(const matrice& A), and comments already warned you of memory leaks.
So my advice is:
if you want to learn about manual allocation management, follow best practices: rule of 5 an copy/swap idiom to avoid caveats
if you just want working code, replace 1D dynamic arrays with vectors and let the standard library handle the corner cases
i dont know whats wrong with my code but im getting same value of "sum" on the
screen..
assume that m and n are entered equal ....enter image description here
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
int n,m;
int *ptr1, *ptr2, *sum;
cout<<" enter the size of 1st and 2nd array : "<<endl;
cin>>n>>m;
ptr1=(int*)malloc(n*sizeof(int));
ptr2=(int*)malloc(m*sizeof(int));
sum=(int*)malloc((n)*sizeof(int));
cout<<"enter 1st array element :";
for(int i=0;i<n;i++)
{
cin>>*(ptr1+i) ;
}
cout<<"enter 2st array element :";
for(int i=0;i<m;i++)
{
cin>>*(ptr2+i);
}
for(int j=0;j<m||j<n;j++)
{
*(sum+j) = (*(ptr1) + *(ptr2)) ;
}
cout<<" the sum is "<<endl;
for(int j=0;j<m||j<n;j++)
{
cout<<*(sum+j)<<endl;
}
}
First, the reason you get the same number springs from where you form the sums.
In this loop
for (int j = 0; j<m || j<n; j++)
{
*(sum + j) = (*(ptr1)+*(ptr2));
}
you find the sum of the contents of ptr1 and ptr2 over and over which never change - this is always the first two numbers.
So, we could iterate over the arrays by indexing in j along as follows
for (int j = 0; j<m || j<n; j++)
{
*(sum + j) = (*(ptr1 + j) + *(ptr2 + j));
}
BUT what happens if m!=n? You'll walk off the end of the array.
If you change the loop to
for (int j = 0; j<m && j<n; j++)
{
*(sum + j) = (*(ptr1 + j) + *(ptr2 + j));
}
then you find the sum for pairs of numbers up to the smaller of m and n.
You will have to do likewise with the display of the results
for (int j = 0; j<m && j<n; j++)
{
cout << *(sum + j) << endl;
}
However, I believe you wanted to either display n numbers, regardless of which is bigger, or perhaps assume a 0 if there is no element. Also, I notice you have malloced and not freed - perhaps using a C++ array rather than C-style arrays is better? I'll come to that in a moment.
Let's do the C appraoch and have a 0 if we go beyond the end of an array.
This will work, but can be tidied up - comments inline about some important things
#include<stdlib.h>
#include <algorithm> //for std::max
#include <iostream>
using namespace std;
int main()
{
int n, m;
int *ptr1, *ptr2, *sum;
cout << " enter the size of 1st and 2nd array : " << endl;
cin >> n >> m;
ptr1 = (int*)malloc(n * sizeof(int));
ptr2 = (int*)malloc(m * sizeof(int));
sum = (int*)malloc((std::max(n, m)) * sizeof(int));
// ^--- sum big enough for biggest "array"
// data entry as before - omitted for brevity
for (int j = 0; j<m || j<n; j++)
{
*(sum + j) = 0;
if (j < n)
*(sum + j) += *(ptr1 + j);
if (j < m)
*(sum + j) += *(ptr2 + j);
}
cout << " the sum is " << endl;
for (int j = 0; std::max(n, m); j++)//however big it is
{
cout << *(sum + j) << endl;
}
free(ptr1); //tidy up
free(ptr2);
free(sum);
}
I know you said you wanted to use malloc and perhaps this is a practise with pointers, but consider using C++ idioms (at least you won't forget to free things you have maoolced this way).
Let's nudge your code towards using a std::vector:
First the include and the input:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, m;
vector<int> data1, data2, sum;
cout << " enter the size of 1st and 2nd array : " << endl;
cin >> n >> m;
cout << "enter 1st array element :";
for (int i = 0; i<n; i++)
{
int number;
cin >> number;
data1.push_back(number); //there is a neater way, but start simple
}
cout << "enter 2st array element :";
for (int i = 0; i<m; i++)
{
int number;
cin >> number;
data2.push_back(number);
}
This post shows a way to neaten up the data entry. However, let's do something simple and get the sum:
for (int j = 0; j < std::max(m, n); j++)
{
int number = 0;
if (j < n)
number += data1[j];
if (j < m)
number += data2[j];
sum.push_back(number);
}
And now for a C++ way to do output
cout << " the sum is " << endl;
for (auto item : sum)
{
cout << item << '\n';
}
}
Finally, let's have a brief think about the sum.
If you now #include <iterator> you can use an algorithm to put your sum into sum
std::transform(data1.begin(), data1.end(),
data2.begin(), std::back_inserter(sum), std::plus<int>());
However, note this won't fill with zeros. You could either make the vectors the same size, filled with zeros first, or lookup/discover ways to zip vectors of different sizes. Or stick with ifs in a loop as I demonstrated above.
Avoid malloc in C++. Just saying.
I highly encourage you to use a modern cpp data structure like a vector for storing your data. Thus, you don't have to worry about malloc and can access them far more easyly.
But now to your question: Your summation for loop is broken. Use
for(int j=0;j<m||j<n;j++)
{
*(sum+j) = (*(ptr1+j) + *(ptr2+j)) ;
}
Best regrads, Georg
I am trying to create MxN matrix using 2D-arrays in C++.
The createMatrix() function asks for user input for matrix items and the printMatrix() function has to print the matrix.
But the printing task is not working (I can't access the array created, I don't understand why)
I receive the error :
matrix.cpp:35:20: error: invalid types ‘int[int]’ for array subscript
cout << matrix[i][j];
The code I'm working with is:
#include "iostream"
using namespace std;
// user input matrix
int createMatrix(int m, int n){
int arr[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr[m][n];
}
/*
void printMatrix(int matrix[][2], int m, int n){
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
}
*/
int main(){
int m = 2, n = 2; // m = rows, n = columns
int matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
matrix is an int not an int[][]. Since it is an int there is no subscript operator and that is why you are getting the error you are getting. You are also using veriable length arrays which is not standard C++. I would suggest you change your code to use a std::vector like
std::vector<std::vector<int>> createMatrix(int m, int n)
{
std::vector<std::vector<int>> arr(m, std::vector<int>(n));
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr;
}
And then main() would be:
int main(){
int m = 2, n = 2; // m = rows, n = columns
std::vector<std::vector<int>> matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
Your matrix is not array. it is int.
You need to work with the pointers.
Yes, createMatrix works but you won't be able to do anything with what it created. Because:
arr[n][m] is local (and out of boundaries by the way). It is not a matrix as you probably thought but an item of arr at position [n][m].
It is not well defined to declare array of fixed sizes with vary sizes that depend on function input.
You need to pass to createMatrix array from the main() as pointer (like you did in printMatrix) and createMatrix should work with it and not something local.
Now regarding your original question:
But the printing task is not working (I can't access the array
created, I don't understand why)
matrix was defined as int, not as array.
int matrix = createMatrix(m,n);
first off sorry for the slightly messy code as I was fiddling with different things to try to get it to work. As of now, my code can multiply Square Matrices just fine; however, it has difficulties computing Non Square Matrices. My best guess after debugging is how i re-size my vectors, and that there is an out of bounds error which causes the program to crash. Any help would be appreciated, my code should be able to Multiply any Vectors sizes withing Matrix Multiplication Rules.
I also would like to note this is a HW assignment so I am limited to how I can build my code, basically ONLY using vectors, cannot write your own class etc....
#include <iostream>
#include <vector>
using namespace std;
void multiply_matrices(vector <vector<int> > matrix1,vector <vector<int> > matrix2, int cols, int rows2);
void setMatrix(vector <vector<int> > &matrix, int rows, int cols);
int main()
{
int rows, cols, rows2, cols2;
vector< vector<int> > matrix, matrix2;
cout<<"Please enter the number of Rows and Columns for your first Matrix."<<endl;
cout<<"Rows: ";
cin>>rows;
cout<<"Columns: ";
cin>>cols;
matrix.resize(cols, vector<int>(rows,0)); //Saw this online so not sure how it works but it works, if i take out one i cant do row<column and vice versa
matrix.resize(rows, vector<int>(cols,0));
cout<<"Size has been declared, please enter data for your matrix"<<endl;
setMatrix(matrix,rows,cols);
cout<<"Second Matrix Automatically Set by Matrix Multiplication Rule"<<endl; //Just automatically sets second matrix as per Matrix Multiplication Rule
rows2=cols;
cols2=rows;
cout<<"Second Matrix Size is: " << rows2 << " by " << cols2 << endl;
matrix2.resize(cols2, vector<int>(rows2,0));
matrix2.resize(rows2, vector<int>(cols2,0));
setMatrix(matrix2,rows2,cols2);
cout<<"Multiplied Matrix is:"<<endl;
multiply_matrices(matrix,matrix2,cols,rows2);
system("PAUSE");
return 0;
}
void setMatrix(vector <vector<int> > &matrix, int rows,int cols){
int num;
for(int i = 0; i < rows; i ++)
{
for (int j = 0; j < cols; j++)
{
cout << "Enter Value for Row " << (i+1) << " Column " << (j+1) << ": ";
cin>>num;
matrix[i][j]=num;
}
cout << endl;
}
/*for(int i = 0; i < rows; i ++)
{
for (int j = 0; j < cols; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
*/
}
void multiply_matrices(vector <vector<int> > matrix1,vector <vector<int> > matrix2, int cols, int rows2){
vector< vector<int> > tempMatrix;
int newrows=rows2;
int newcols=cols;
int sum;
tempMatrix.resize(newcols, vector<int>(newrows,0)); //Resizing new matrix to proper size, so if it was (2x3)(3x2), new matrix is (3x3)
for (int i = 0; i < newrows; i++) //This Works Fine for Square Matrixes but not for others, i have no clue how to fix it?
{
for (int j = 0; j < newcols; j++){
//sum=0;
for (int u = 0; u < newcols; u++)
{
//sum+=matrix1[i][u] * matrix2[u][j];
//tempMatrix[i][j]=sum;
tempMatrix[i][j] += matrix1[i][u] * matrix2[u][j];
}
}
}
for(int i = 0; i < newrows; i ++)
{
for (int j = 0; j < newcols; j++)
{
cout << tempMatrix[i][j] << " ";
}
cout << endl;
}
}
Initialize your first matrix like this:
matrix.resize(rows, vector<int>(cols,0));
and your second like this:
matrix2.resize(rows2, vector<int>(cols2,0));
where rows2 = cols. Note that there is no "multiplication rule" that implies cols2 == rows.
The problem is in your multiply_matrices function where the loops should be
for (int i = 0; i < rows; i++) // or matrix1.size()
for (int j = 0; j < cols2; j++) // or tempMatrix[i].size()
for (int u = 0; u < cols; u++) // or rows2 or matrix1[i].size()
but as already stated in the comments, it would be better to use vector::size() instead of passing the sizes as additional parameters.
Also, if you multiply (2x3)(3x2), the result is (2x2):
tempMatrix.resize(rows, vector<int>(cols2,0));
There is nothing wrong with the resize() function. What may be wrong is that you ignore the maximum size and rely solely on variables that are passed to your functions.
For example, your setMatrix function is passed rows and cols, but this is not necessary.
The function should be rewritten using only the matrix to provide the sizes to the loops:
void setMatrix(vector<vector<int> > &matrix)
{
int num;
for(int i = 0; i < matrix.size(); ++i)
{
for (int j = 0; j < matrix[i].size(); ++j)
{
cout << "Enter Value for Row " << (i+1) << " Column " << (j+1) << ": ";
cin>>num;
matrix[i][j] = num;
}
cout << endl;
}
}
You have the same issue with multiply_matrix. What you should be doing is ensure that you're loops use the return value of vector::size(), which you do not do. The problem is here:
for (int i = 0; i < newrows; i++)
{
for (int j = 0; j < newcols; j++)
{
for (int u = 0; u < newcols; u++)
{
tempMatrix[i][j] += matrix1[i][u] * matrix2[u][j];
You sized the tempMatrix to newrows rows and newcols columns. But how do you know that matrix1 and matrix2 have at least newrows rows and newcols columns? You don't know, but you just assume they do.
So you either need to ensure that the size of matrix1 and matrix2 can accommodate the number of rows/columns, or you throttle those loops to use the minimum rows/columns.
Overall, the issue is that nowhere do you use vector::size() in your code that I see. So start to use size() to your advantage -- don't create superfluous (and possibly erroneously set) variables that supposedly denote the sizes of the rows and columns.
I have to create a program that allows a user to fill in a (partial) Latin Square of order 4. You can use 0's to represent empty cells. The user will give the number to place, the row and column. The number should only be placed if it does not violate the properties of a partial Latin square and it shouldn't rewrite numbers that have already been placed.
I have an matrix that is outputting all zeroes now. So next I have to replace each of these values by what the user is inputting. The problem is I don't know how to do this.
Here is my code:
#include <iostream>
using namespace std;
const int ORDER = 4;
void fill (int m[], int order);
void outputMatrix (int m[], int order);
void replaceValue (int m[], int order, int n, int row, int column);
int main(){
int matrix[ORDER];
int row;
int column;
int n;
fill (matrix, ORDER);
outputMatrix (matrix, ORDER);
do {
cout << "Enter the number to place, the row and the column, each seperated by a space: ";
cin >> n;
cin >> row;
cin >> column;
}while (n > 0 || n <= ORDER);
if (n <= 0 || n >= ORDER){
cout << "Thank you";
cout << endl;
}
return 0;
}
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
void outputMatrix (int m[], int order){
int c = 0;
for (int i = 0; i < order*order; i++){
c++;
cout << m[i] << ' ';
if (c == order){
cout << endl;
c = 0;
}
}
cout << endl;
}
void replaceValue (int m[], int order, int n, int row, int column){
for (int i = 0; i < order; i++){
m[order] = m[row][column];
m[row][column] = n;
}
}
How do I replace values in a Matrix in C++?
If you have a matrix, matrix[row][col] = value; would do the trick. However, I see that you allocate a single array. Make sure you look at this.
EDIT:
I looked closer at you code and you are doing some things wrong.
First:
matrix[ORDER]
will create a single array of ORDER values. If you want and ORDER by ORDER matrix try:
matrix[ORDER][ORDER]
Second:
You are calling:
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
with an of size 4 and order == 4. This will loop outside the array and give you problems.
Try something like:
matrix[ORDER][ORDER];
for (int row = 0; row != ORDER; ++row)
{
for (int col = 0; col != ORDER; ++col)
{
matrix[row][col] = 0;
}
}
Hope this helps.
You can't really write arr[i][j] if arr is defined as arr[]. There's no information about the length of the row (how many columns there are).
You could use arrays of type arr[][4], and write your functions like so:
// The & is to pass by reference.
void print(int (&arr)[][4], int length)
{
for(int i = 0; i < length; i++) {
for(int j = 0; j < 4; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
But in my opinion for a low-order multidimensional array like this one, using a typedef for a vector of vectors is the better option:
typedef vector<vector<int> > Matrix;
void print(Matrix& arr)
{
for(int i = 0; i < arr.size(); i++) {
for(int j = 0; j < arr[i].size(); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
In either case, writing arr[i][j] = k will behave as you expect.
The easiest way to clear/zero your matrix is that:
memset( &matrix, 0, sizeof(matrix));
;-)