I'm trying to multiply 2 matrices together using operator-overloading but I'm getting an error when trying to convert my int array into my matrix class in order to use it. I'm not sure how to fix these errors
#include <iostream>
using namespace std;
struct matrix{
int array[4][4];
public:
void make(int A[][4], int size) {
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
array[x][y] = A[x][y];
}
}
}
void operator*(matrix m) {
int output[4][4];
for (int x = 0; x < 4; x++){
for (int y = 0; y < 4; y++){
array[x][y] = (array[x][y] * m.array[x][y]);
}
}
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
cout << output[x][y] << " ";
}
cout << endl;
}
}
};
int main(){
matrix m1, m2;
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
//int c[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
m1.make(a[4][4], 4);
m2.make(a[4][4], 4);
m1*m2;
return 0;
}
There are two problem with your code:-
m1.make(a[4][4], 4); // should be m1.make(a, 4); make is expecting a 2D array you are passing an integer
In the operator *function
array[x][y] = (array[x][y] * m.array[x][y]); // your should assign to output[x][y] here
You are not using the corect syntax.
int main(){
matrix m1, m2;
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
//int c[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
// these are not good, you try to pass a single int, and it is past the
// end of a.
//m1.make(a[4][4], 4);
//m2.make(a[4][4], 4);
// try this instead:
m1.make(a, 4);
m2.make(a, 4);
m1*m2;
return 0;
}
Multiplying is a binary operator that takes in 2 matrices, and outputs a third one with the result.
class matrix
{
// note the friend modifier, which indicates this fonction is a not a member
// of the class, and can access all of its private members.
friend matrix operator*(const matrix& m, const matrix& n)
{
matrix result;
for (int x = 0; x < 4; x++)
for (int y = 0; y < 4; y++)
result.array[x][y] = (m.array[x][y] * n.array[x][y]);
// your formula does not seem quite right here...
// I'll let you fix it.
return result;
}
Here is the correct syntax for make() to accept an int[4][4] array:
void make(int (&A)[4][4]) {
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
array[x][y] = A[x][y];
}
}
}
Why don't you have a constructor instead of make?
class matrix{
private:
int array[4][4];
public:
// you want to initialize your data, always (well, almost always, but
// this is the kind of data that always applies to)...
matrix()
{
for (int x = 0; x < 4; x++)
for (int y = 0; y < 4; y++)
array[x][y] = 0;
}
explicit matrix(const int(&a)[4][4])
{
for (int x = 0; x < 4; x++)
for (int y = 0; y < 4; y++)
array[x][y] = a[x][y];
}
matrix& operator=(const int(&a)[4][4])
{
return *this = matrix(a);
}
matrix& operator=(const matrix& m)
{
for (int x = 0; x < 4; x++)
for (int y = 0; y < 4; y++)
array[x][y] = m.array[x][y];
return *this;
}
// ...
};
Then main() becomes:
int main(){
matrix m1, m2;
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
matrix m1(a);
matrix m2(a);
matrix product = m1 * m2;
return 0;
}
Related
Can anyone help me out here? When I run the program it runs and everything is right but when I upload it onto the grader (ZyBooks) it is giving me this error: "Unhandled exception: Range error: 2" for the function createMatrix. The file that was read from contains coordinate points in (x, y, z) format and is read into a vector of type Point and then translated into a matrix (2D vector).
The coordinates.txt contains:
(1,2,3) (4,5,6) (7,8,9) (10,11,12) (13,14,15)
Thank you, I have posted my code below.
#include "std_lib_facilities.h"
struct Point {
double x;
double y;
double z;
};
istream& operator>>(istream& is, Point& p) {
char dummy;
is >> dummy;
is >> p.x;
is >> dummy;
is >> p.y;
is >> dummy;
is >> p.z;
is >> dummy;
return is;
}
ostream& operator<<(ostream& os, const Point& p) {
return os << "(" << p.x << "," << p.y << "," << p.z << ")";
}
void createMatrix(const vector<Point>& v1, vector<vector<double> >& v2) {
// Set row for x
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 5; j++) {
v2[i][j] = v1[j].x;
}
}
// Set row for y
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 5; j++) {
v2[i + 1][j] = v1[j].y;
}
}
// Set row for z
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 5; j++) {
v2[i + 2][j] = v1[j].z;
}
}
}
int main() {
// Open the file and read it into a vector of Points
// Declare a 2D vector of doubles with 3 rows and n columns,
// where n is the total number of Points read
// Pass the two vectors into createMatrix
// Output the matrix vector to a file named "coordinateMatrix.txt"
ifstream ifs;
// Open the input file
ifs.open("coordinates.txt");
Point p;
vector<Point> originalPoints;
int n = 0;
// Write from file into vector of type Point
for (int i = 0; i < 5; i++) {
ifs >> p;
originalPoints.push_back(p);
n++;
}
// Declare new 2D vector
vector<vector<double> > matrix(3, vector<double>(n));
// Create matrix with vector of original points
// x x x x x
// y y y y y
// z z z z z
createMatrix(originalPoints, matrix);
// Close the input file
ifs.close();
ofstream ofs;
// Open the output file
ofs.open("coordinateMatrix.txt");
// Write the matrix into output file
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
ofs << matrix[i][j] << " ";
}
ofs << endl;
}
// Close the output file
ofs.close();
}
UPDATE:
Thanks to Thomas, I changed my function to the code below and it worked!
void createMatrix(const vector<Point>& v1, vector<vector<double> >& v2) {
// Set row for x
for (long unsigned int i = 0; i < 1; i++) {
for (long unsigned int j = 0; j < v1.size(); j++) {
v2[i][j] = v1[j].x;
}
}
// Set row for y
for (long unsigned int i = 0; i < 1; i++) {
for (long unsigned int j = 0; j < v1.size(); j++) {
v2[i + 1][j] = v1[j].y;
}
}
// Set row for z
for (long unsigned int i = 0; i < 1; i++) {
for (long unsigned int j = 0; j < v1.size(); j++) {
v2[i + 2][j] = v1[j].z;
}
}
}
The task is as follows: Describe the class "matrix of numbers" with component data: the dimensions of the matrix, a pointer to the elements. Overload operations: << (matrix output to the screen), + (addition of matrices), unary ¬– (change the sign of each element), / = (divide each element by a number). I performed it, and performed it correctly, but you need to set the matrix dimension from the keyboard, and as you can see, it is set in advance for me [3] [3]. It sounds pretty simple, but something I'm really dumb. Thanks in advance for your help. Here is the code:
#include "pch.h"
#include <iostream>
using namespace std;
class Matrix
{
public:
Matrix()
{
int Table[3][3];
}
int Table[3][3];
void Create()
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
Table[i][j] = 10;
}
};
ostream& operator <<(ostream& t, Matrix a)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
t << a.Table[i][j] << " ";
t << "\n";
}
return t;
}
Matrix& operator /=(Matrix& a, int num)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] /= num;
return a;
}
Matrix& operator -(Matrix& a, int empty)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] = -a.Table[i][j];
return a;
}
Matrix& operator +(Matrix& a, Matrix b)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
int main()
{
int u;
setlocale(LC_ALL, "Russian");
Matrix Example;
Example.Create();
Matrix Example1;
Example1.Create();
cout << Example;
cout << Example1;
cout << "Сумма матриц: "<<endl;
cout << Example + Example1;
Example - 1;
Example1 - 1;
cout<< Example + Example1;
cout << "На сколько вы хотите её поделить?\n";
cin >> u;
Example /= u;
Example1 /= u;
cout << Example;
cout << Example1;
}`
You need to dynamically create the matrix.
In order to this you need to use pointers(*). Change int table[3][3]
double table**;
An example of how it could be implemented (note that I use matrix instead of table)
class Matrix {
private:
double** matrix;
int col;
int row;
public:
Matrix(){};
void Create(int row, int col);
};
void Matrix::Create(int row_, int col_){
double val = 0.0;
col = col_; // initalize private members
row = row_;
matrix = new double*[row]; // Create a new array of size row_
for(int i = 0; i < row; i++)
{
matrix[i] = new double[col]; // Create new cols of size col (inside array of row)
}
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
matrix[i][j] = val;
val = val + 1.0;
}
}
}
I tried to reuse your design for simplicity, but I really suggest that you try to specify the dimensions of the matrix in a constructor instead and maybe even construct the matrix in it as well.
Something like this:
Matrix(int row_, int col_) : row(row_), col(col_) {*/ create matrix here /*};
You can skip the "create matrix here" part and use your own Create() if you want to.
You need dynamic memory allocation for that. I won't fiddle around with pointers (new / delete) unless you are explicitly told to. As a beginner you should probably use the standard template library (STL) tools:
#include <vector> and use std::vector<std::vector<int>> Table instead of int Table[3][3]. Then write a constructor like this:
Matrix(std::size_t rows, std::size_t cols)
{
Table.resize(rows);
for (unsigned int i = 0; i < Table.size(); ++i)
Table[i].resize(cols);
}
You can additionally store the dimension of the matrix, but there is no need to do it since you can get the information from the vectors. Replace the hardcoded dimensions in all loops by the corresponding dynamic sizes (stored or extracted from the vectors). For example:
Matrix& operator +(Matrix& a, Matrix b)
{
unsigned int rows = a.Table.size();
unsigned int cols = a.Table[0].size();
for (unsigned int i = 0; i < rows; i++)
for (unsigned int j = 0; j < cols; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
However, this vector of vectors is not really effective. Better would be a single vector but I guess for a beginner it is okay.
Greetings
I have a University assignment whereby I have a 1D array, containing 262144 values. I've created a matrix class which places these values into an object with the datasource being the double* list of 262144 values.
I need to be able to obtain a sub-matrix (which I'm able to do) from ANOTHER set of 262144 values (which I've also placed into a matrix object).
However, I'm having serious trouble and I've been trying so hard for the last 3 days to try and replace original matrix values from a sub-matrix. I've tried passing by reference, creating Matrix*'s. I've tried everything we've been taught and even researched a few more methods, all of which I haven't understood. I'll throw my code in here to see if anyone can explain a method to me which will be able to do this.
Matrix::Matrix()
{
"Matrix::Matrix() is invoked";
}
Matrix::Matrix(const Matrix& m)
{
"Matrix::Matrix(const Matrix&) is invoked";
_M = m._M;
_N = m._N;
_data = new double[_M*_N];
for (int i = 0; i < _M*_N; i++)
{
_data[i] = m._data[i];
}
}
Matrix::Matrix(int sizeR, int sizeC, double *input_data)
{
"Matrix::Matrix(int sizeR, int sizeC, double *input_data is invoked";
_M = sizeR;
_N = sizeC;
_data = new double[_M*_N];
for (int i = 0; i < _M*_N; i++)
{
_data[i] = input_data[i];
}
}
Matrix Matrix::get_Block(int start_row, int end_row, int start_coloumn, int end_coloumn)
{
int rows = (end_row - start_row);
int columns = (end_coloumn - start_coloumn);
int ctr = 0;
double *temp_Data = new double[rows*columns];
for (int x = start_row; x < (rows + start_row); x++)
{
for (int y = start_coloumn; y < (columns + start_coloumn); y++)
{
temp_Data[ctr] = get(x, y);
ctr++;
}
}
Matrix block(rows, columns, temp_Data);
delete[] temp_Data;
return block;
}
Matrix Matrix::operator+(const Matrix & other)
{
Matrix temp;
temp._M = other._M;
temp._N = other._N;
temp._data = new double[temp._M*temp._N];
for (int x = 0; x < (temp._M*temp._N); x++)
{
temp._data[x] = this->_data[x] + other._data[x];
}
return temp;
}
Matrix Matrix::operator*(const Matrix & other)
{
Matrix temp;
temp._M = other._M;
temp._N = other._N;
temp._data = new double[temp._M*temp._N];
for (int x = 0; x < (temp._M*temp._N); x++)
{
temp._data[x] = this->_data[x] * other._data[x];
}
return temp;
}
Matrix Matrix::operator-(const Matrix & other)
{
Matrix temp;
temp._M = other._M;
temp._N = other._N;
temp._data = new double[temp._M*temp._N];
for (int x = 0; x < (temp._M*temp._N); x++)
{
temp._data[x] = this->_data[x] - other._data[x];
}
return temp;
}
void Matrix::replace_Block(Matrix& noisy, Matrix& shuffled,int k, int j, int i)
{
int val_to_replace = 0;
for (int i = 0; i < 3 * 3; i++)
{
val_to_replace = shuffled.get(i, j);
noisy.set(i, j, val_to_replace);
}
}
void Matrix::set_Block(Matrix block, Matrix& Noisy, int start_row, int end_row)
{
int ctr = 0;
int ctr2 = 0;
int ctr3 = 0;
for (int i = 0; i < 3; i++)
{
Noisy._data[(start_row*_M)+i+4] = block.get(i, ctr);
ctr++;
}
for (int j = 0; j < 3; j++)
{
Noisy._data[((start_row + 1)*_M) + j + 3] = block.get(j, ctr2);
ctr2++;
}
for (int j = 0; j < 3; j++)
{
Noisy._data[((start_row + 1)*_M) + j + 2] = block.get(j, ctr3);
ctr3++;
}
}
double Matrix::get_Sum(Matrix m)
{
double total = 0;
short row = m.get_M();
short column = m.get_N();
for (int j = 0; j < row; j++)
{
for (int i = 0; i < column; i++)
{
total += m.get(j,i);
}
}
return total;
}
double Matrix::get_Sum(Matrix* m)
{
double total = 0;
short row = m->get_M();
short column = m->get_N();
for (int j = 0; j < row; j++)
{
for (int i = 0; i < column; i++)
{
total += m->get(i, j);
}
}
return total;
}
double Matrix::get(int i, int j)
{
return _data[(i * _M) + j];
}
void Matrix::write_Block(int i, int j)
{
for (int ctr = 0; ctr < i; ctr++)
{
for (int ctr2 = 0; ctr2 < j; ctr2++)
{
std::cout << " " << this->get(ctr,ctr2);
}
std::cout << std::endl;
}
}
void Matrix::set(int i, int j, double val)
{
this->_data[(i*_M) + j] = val;
}
void Matrix::set_N(int N)
{
_N = N;
}
void Matrix::set_M(int M)
{
_M = M;
}
int Matrix::get_N()
{
return _N;
}
int Matrix::get_M()
{
return _M;
}
Matrix::~Matrix()
{
"Matrix::~Matrix() is invoked";
delete[] _data;
}
If it would be helpful to see main() I can supply that too, however all it really contains is the creation of the matrix objects using overloaded constructors.
explanation
Answer is only 4 years late . . .
Anyway. Maybe it will help somebody else. The secret is to use a std::valarray. With that it is utmost simple to work on a matrix. And, many many functions are available.
All the functions that you want to implement are already available.
And you sub-matrix coy can be a one liner . . .
Please see example code:
#include <iostream>
#include <algorithm>
#include <numeric>
#include <valarray>
#include <iomanip>
constexpr size_t NRows = 6;
constexpr size_t NCols = 8;
constexpr size_t SubNRows = 2;
constexpr size_t SubNCols = 3;
void debugPrint(std::valarray<int> &v, size_t nrows = NRows, size_t ncols = NCols)
{
for (int r = 0; r < nrows; ++r) {
for (int c = 0; c < ncols; ++c)
std::cout << std::setw(3) << v[r*ncols+c] << ' ';
std::cout << '\n';
}
std::cout << '\n';
}
int main()
{
std::valarray<int> v1(NRows * NCols); // Define array with given size
std::iota(std::begin(v1),std::end(v1),0); // Fill the array with consecutive nunbers
debugPrint (v1); // Print the result
std::cout << "\nSum = " << v1.sum() << "\n\n"; // Print the sum of all values in matrix
std::valarray<int> v2(v1); // Create a 2nd matrix as a copy to the first
v2 += 100; // Add 100 to each value in the matrix
debugPrint(v2);
std::valarray<int> v3(NCols); // Get one column
v3 = v1[std::slice(2,NRows,NCols)];
debugPrint(v3,NRows,1);
std::valarray<int> subV2(SubNRows*SubNCols); // So, now the sub array
subV2 = v2[std::gslice(12,{SubNRows, SubNCols},{NCols,1})]; // Slice it out
debugPrint(subV2, SubNRows, SubNCols);
v1[std::gslice(25,{SubNRows, SubNCols},{NCols,1})] = subV2; // And copy to the first array
debugPrint (v1);
return 0;
}
I'm trying to return a sub-image from a 5x7 matrix. I'm trying to retrieve the sub matrix (0,2,0,2). I've created a function get_Block which SHOULD return the values of the matrix to temp, however just getting:
Exception thrown at 0x003B2A96 in Logo_Unscrambler.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.
It's probably super simple but I'm mega tired and I can't see it. Here's the code:
Main:
int main() {
double* A = new double[5*7];
for (int i = 0; i < 5 * 7; i++)
{
A[i] = i;
}
Matrix Ab(5, 7, A);
Matrix temp;
temp = Ab.get_Block(0, 2, 0, 2);
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < 3; i++)
{
cout << " " << temp.get(k,i, 3);
}
cout << endl;
}
system("pause");
return 0;
}
Matrix.cpp:
Matrix::Matrix(int sizeR, int sizeC, double *input_data)
{
"Matrix::Matrix(int sizeR, int sizeC, double *input_data is invoked";
_M = sizeR;
_N = sizeC;
_data = new double[_M*_N];
for (int i = 0; i < _M*_N; i++)
{
_data[i] = input_data[i];
}
}
Matrix Matrix::get_Block(int start_row, int end_row, int start_coloumn, int end_coloumn)
{
int rows = (end_row - start_row) + 1;
int columns = (end_coloumn - start_coloumn) + 1;
int ctr = 0;
double *temp_Data = new double[rows*columns];
for (int x = start_row; x < (rows + start_row); x++)
{
for (int y = start_coloumn; y < (columns + start_coloumn); y++)
{
temp_Data[ctr] = get(x, y,rows);
ctr++;
}
}
Matrix block(rows, columns, temp_Data);
delete[] temp_Data;
return block;
}
double Matrix::get(int i, int j, int row_Count)
{
return _data[(i*_N) + j];
}
#include <iostream>
#include <stdlib.h>
using namespace std;
float **div(float **A, float **B, int row, int column) {
float **D;
D = new float *[row];
// D= ( float **)malloc(sizeof(float *) * row);
for (int x = 0; x < row; x++) {
D[x] = new float[column];
// D[x] = (float (*))malloc(sizeof(float) * column);
for (int y = 0; y < column; y++) {
D[x][y] = (A[x][y] / B[x][y]);
}
}
return D;
}
int main() {
int x = 0, y = 0, row = 20, column = 5;
float **N;
// N =(float **)malloc(sizeof(float *) * row);
N = new float *[row];
for (x = 0; x < row; x++) {
N[x] = new float[column];
// N[x]=(float*)malloc(row*column*sizeof(float));
for (y = 0; y < (column); y++) {
N[x][y] = 1;
}
}
N = div(N, N, row, column);
cout << "Displaying N ..." << endl;
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 5; y++) {
cout << N[x][y] << " ";
}
cout << endl;
}
for (int x = 0; x < 20; x++) {
delete[] N[x];
}
delete[] N;
return 0;
}
I am trying to free the all the memory, but it is freed the memory which I declared in main, but the function div also occupying the same memory of size input array N and it is not freed. Is there any way to delete the memory which is occupied the function.
Please look at here, my example of new and delete a int[m][n], I hope this can help you:
int main()
{
//a[m][n]
const int m = 5, n=6;
int **p = new int*[m];
for(int i=0; i<m; ++i)
p[i] = new int[n];
for(int i=0; i<m; ++i)
delete[] p[i]; //delete array
delete[] p;
p = nullptr;
}
Using std::array would remove memory management:
template <std::size_t ROW, std::size_t COL>
using Matrix = std::array<std::array<float, COL>, ROW>;
template <std::size_t ROW, std::size_t COL>
Matrix<ROW, COL> div(const Matrix<ROW, COL>& A, const Matrix<ROW, COL>& B)
{
Matrix<ROW, COL> res;
for (std::size_t x = 0; x != ROW; ++x) {
for (std::size_t y = 0; y != COL; ++y) {
res[x][y] = (A[x][y]/B[x][y]);
}
}
return res;
}
template <std::size_t ROW, std::size_t COL>
void display(const Matrix<ROW, COL>& m)
{
for (std::size_t x = 0; x != ROW; ++x) {
for (std::size_t y = 0; y != COL; ++y) {
std::cout << m[x][y] << " ";
}
std::cout << std::endl;
}
}
int main()
{
Matrix<20, 5> N;
for (std::size_t x = 0; x != 20; ++x) {
for (std::size_t y = 0; y != 5; ++y) {
N[x][y] = 1;
}
}
N = div(N, N);
std::cout << "Displaying N ..." << std::endl;
display(N);
}
Demo