So I wrote this:
Matrix.h:
#pragma once
class Matrix
{
private:
int m, n;
double** M = nullptr;
public:
Matrix();
Matrix(int,int);
Matrix(const Matrix&);
~Matrix();
void set_m(int);
void set_n(int);
int get_m() const;
int get_n() const;
void setM(double**,int,int);
double** getM() const;
void show();
Matrix operator*(Matrix&) const;
};
Matrix.cpp:
#include "Matrix.h"
#include<iostream>
using namespace std;
/*
*/
Matrix::Matrix()
{
set_n(1);
set_m(1);
delete[] M;
M = new double*[get_m()];
for (int i = 0; i < m; i++) {
M[i] = new double[get_n()];
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) M[i][j] = 1.0;
}
Matrix::Matrix(int m_,int n_)
{
set_n(n_);
set_m(m_);
delete[] M;
M = new double *[get_m()];
for (int i = 0; i < m; i++) {
M[i] = new double[get_n()];
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) M[i][j] = 1.0;
}
Matrix::Matrix(const Matrix& M_)
{
set_n(M_.get_n());
set_m(M_.get_m());
delete[] M;
M = new double*[get_m()];
for (int i = 0; i < m; i++) {
M[i] = new double[get_n()];
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) M[i][j] = M_.getM()[i][j];
}
void Matrix::set_m(int m_) {
if (m_ > 0)
m = m_;
else
m = 1;
}
void Matrix::set_n(int n_) {
if (n_ > 0)
n = n_;
else
n = 1;
}
double** Matrix::getM() const {
return M;
}
Matrix Matrix::operator*(Matrix &M_) const
{
if (get_n() != M_.get_m()) {
if (get_m() != M_.get_n()) return Matrix();
else {
Matrix T(*this);
return M_*T;
}
}
else {
//n = m
Matrix R(get_m(), M_.get_n());
for (int i = 0; i < get_m(); i++) {
for (int j = 0; j < M_.get_n(); j++) {
double res = 0;
for (int k = 0; k < get_n(); k++) {
res += getM()[i][k] * M_.getM()[k][j];
}
R.getM()[i][j] = res;
}
}
return R;
}
}
int Matrix::get_m() const {
return m;
}
int Matrix::get_n() const {
return n;
}
void Matrix::setM(double** M_, int m_, int n_) {
set_m(m_);
set_n(n_);
for (int i = 0; i < get_m(); i++) {
delete M[i];
}
delete[] M;
M = new double*[m_];
for (int i = 0; i < m; i++) {
M[i] = new double[n_];
}
for (int i = 0; i < m_; i++)
for (int j = 0; j < n_; j++) M[i][j] = M_[i][j];
}
void Matrix::show() {
for (int i = 0; i < get_m(); i++) {
for (int j = 0; j < get_n(); j++) {
cout << getM()[i][j]<<" ";
}
cout << endl;
}
}
Matrix::~Matrix()
{
for (int i = 0; i < get_m(); i++) {
delete M[i];
}
delete[] M;
}
It crashes at void Matrix::setM(...) when I try to delete M[i] for i = 1; it doe perfectly fine for i=0; but crashes later and I do not have a rational explanation why does it do that. I can see the debugger showing me that the memory cannot be read even before it actually crashing but I do not understand how to fix it. Thanks in advance!
You are setting your m before deleting your array based on the old value of m and end up deleting your old array using the new value of m. You should first delete your array, then set mm, and then create your new array.
Related
Here's the error message:
main.cpp|119|error: no matching function for call to 'Matrix2D::Matrix2D()'|
My guess is that when declaring Matrix2D first_hidden_weights in class NeuralNewtork it required 2 parameters beacuse of the class Matrix2D-s constructor. But I cannot give it the parameters because I don't know them yet.
#include <stdlib.h>
#include <time.h>
#include <vector>
using namespace std;
float RandomNumber()
{
return ((((double) rand() / (RAND_MAX))*2)-1);
}
class Matrix2D{
public:
int rows;
int columns;
vector<vector<float> > matrix;
Matrix2D(int x, int y){
rows = x;
columns = y;
for (int i = 0; i < rows; i++) {
vector<float> v1;
for (int j = 0; j < columns; j++) {
v1.push_back(0);
}
matrix.push_back(v1);
}
}
Matrix2D randomizeMatrix(){
Matrix2D result(rows, columns);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
matrix[i][j] = RandomNumber();
}
}
return result;
}
static Matrix2D scalarMultiply(Matrix2D x, float y){
Matrix2D result(x.rows, x.columns);
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.columns; j++) {
result.matrix[i][j] = x.matrix[i][j] * y;
}
}
return result;
}
static Matrix2D scalarAddition(Matrix2D x, float y){
Matrix2D result(x.rows, x.columns);
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.columns; j++) {
result.matrix[i][j] = x.matrix[i][j] + y;
}
}
return result;
}
static Matrix2D scalarSubstraction(Matrix2D x, float y){
Matrix2D result(x.rows, x.columns);
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.columns; j++) {
result.matrix[i][j] = x.matrix[i][j] - y;
}
}
return result;
}
static Matrix2D matrixAddition(Matrix2D x, Matrix2D y){
Matrix2D result(x.rows, x.columns);
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.columns; j++) {
result.matrix[i][j] = x.matrix[i][j] + y.matrix[i][j];
}
}
return result;
}
static Matrix2D matrixTranspose(Matrix2D x){
Matrix2D result(x.columns, x.rows);
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.columns; j++) {
result.matrix[j][i] = x.matrix[i][j];
}
}
return result;
}
static Matrix2D matrixMultiplication(Matrix2D x, Matrix2D y){
Matrix2D result(x.rows, y.columns);
for (int i = 0; i < result.rows; i++) {
for (int j = 0; j < result.columns; j++) {
float sum = 0;
for (int k = 0; k < x.columns; i++) {
sum += x.matrix[i][k] * y.matrix[k][j];
}
result.matrix[i][j] = sum;
}
}
return result;
}
void printMatrix(){
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
};
class NeuralNewtork{
public:
int numberof_input_nodes;
int numberof_hidden_layers;
int numberof_hidden_nodes;
int numberof_output_nodes;
Matrix2D first_hidden_weights;
vector<Matrix2D> hidden_weights;
Matrix2D output_weights;
vector<Matrix2D> hidden_biases;
Matrix2D output_biases;
NeuralNewtork(int input_nodes, int hidden_layers, int hidden_nodes, int output_nodes){ // This line
//gives 3 errors, all of them the same.
numberof_input_nodes = input_nodes;
numberof_hidden_layers = hidden_layers;
numberof_hidden_nodes = hidden_nodes;
numberof_output_nodes = output_nodes;
first_hidden_weights = Matrix2D(numberof_hidden_nodes, numberof_input_nodes);
first_hidden_weights.randomizeMatrix();
hidden_weights.reserve(numberof_hidden_layers-1);
for (int i=0; i<numberof_hidden_layers-1; i++){
hidden_weights.push_back(Matrix2D(numberof_hidden_nodes, numberof_hidden_nodes));
hidden_weights.back().randomizeMatrix();
}
output_weights = Matrix2D(numberof_output_nodes, numberof_hidden_nodes);
output_weights.randomizeMatrix();
hidden_biases.reserve(numberof_hidden_layers);
for (int i=0; i<numberof_hidden_layers; i++){
hidden_biases.push_back(Matrix2D(numberof_hidden_nodes, 1));
hidden_biases.back().randomizeMatrix();
}
output_biases = Matrix2D(numberof_output_nodes, 1);
output_biases.randomizeMatrix();
}
Matrix2D feedForward(Matrix2D input){
}
};
The problem is that when you define other constructors(other than default constructor) for your class then the default constructor is not automatically generated by the compiler.
To solve the mentioned error just add any one of the below shown constructor:
Matrix2D() = default;
or
Matrix2D()
{
std::cout<<"default constructor"<<std::endl;
}
into your Matrix2D class definition. Both of the above will work.
Mistake 2
Your feedForward function doesn't return anything. You should add a return statement inside its body.
Matrix2D feedForward(Matrix2D input)
{
return Matrix2D(); //added this return
}
For my midterm assignment I am required to code a matrix with all details (like identify any size matrix, add (etc.) a number to matrix, add (etc.) two matrices together, transpose, determinant, print...).
I made a class called Matrix and wrote bunch of constructors and functions and overloaded operators.
#include <iostream>
#include <string>
#include <ctime>
#include<fstream>
#include<cstdlib>
#include<iomanip>
#include <cmath>
using namespace std;
class Matrix {
private:
int row;
int column;
int value;
int** matrix;
public:
Matrix(int ro, int col, int val);
Matrix(int ro, int col, char type);
~Matrix();
void print();
void resize(int ro , int col);
void operator=(const Matrix& other);
Matrix operator+(int num)const;
};
Matrix::Matrix(int ro=10, int col=10, int val=0)
:row(ro), column(col), value(val)
{
if (row <= 0 || column <= 0) {
cout << "invalid row or column value";
}
else{
matrix = new int* [row];
for (int i = 0; i < row; i++) {
matrix[i] = new int[column];
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
matrix[i][j] = value;
}
}
}
}
Matrix::Matrix(int ro, int col, char type)
:row(ro), column(col)
{
if (row <= 0 || column <= 0) {
cout << "invalid row or column value";
}
else {
matrix = new int* [row];
for (int i = 0; i < row; i++) {
matrix[i] = new int[column];
}
if (type == 'e'){
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (i == j) {
value = 1;
matrix[i][j] = value;
}
else {
value = 0;
matrix[i][j] = value;
}
}
}
}
srand(time(NULL));
if (type == 'r') {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
value = rand() % 256;
matrix[i][j] =value;
}
}
}
}
}
void Matrix::operator=(const Matrix& other) {
this->resize(other.row, other.column);
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
matrix[i][j] = other.matrix[i][j]; // this line throw exception:Exception thrown at 0x00A7BCF2 in matrix.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD.
}
}
}
Matrix Matrix::operator+(int num) const {
Matrix model(row, column);
for (int i = 0; i < model.row; i++) {
for (int j = 0; j < model.column; j++) {
model.matrix[i][j] = matrix[i][j] + num;
}
}
return model;
}
void Matrix::print() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
cout<< setw(6) << matrix[i][j]<< " " ;
}
cout << endl;
}
}
Matrix::~Matrix() {
for (int i = 0; i < row; i++) {
delete[] matrix[i];
}
delete[] matrix;
}
void Matrix::resize(int ro, int col){
int** copymatrix;
copymatrix = matrix;
matrix = new int* [ro];
for (int i = 0; i < ro; i++) {
matrix[i] = new int[col];
}
for (int i = 0; i < ro; i++) {
for (int j = 0; j < col; j++) {
if (i >= row || j >= column) {
matrix[i][j] = 0;
}
else {
matrix[i][j] = copymatrix[i][j];
}
}
}
row = ro;
column = col;
}
int main() {
Matrix mat1(3, 6, 2);
cout << endl;
mat1 = mat1 + 5;
mat1.print();
}
I also tried this but gives me the same error
Matrix Matrix::operator=(const Matrix& other) {
Matrix model(other.row, other.column);
for (int i = 0; i < model.row; i++) {
for (int j = 0; j < model.column; j++) {
model.matrix[i][j] = other.matrix[i][j]; //exception
}
}
return model;
}
I actually have problems with operators overloading. As I write in the main function when I use operator+ overloading it returns a matrix and after that it comes to operator= overloading and there is the problem as it returns the matrix and comes to operator= it gives me the error Exception thrown at 0x00CEBCDB in matrix.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD. I think I know why but I don't know how to solve it.
This code works in CodeBlocks 17.12. It throws the error in Visual Studio 2019 (v142).
Your assignment operator doesn't assign new memory for the matrix:
void Matrix::operator=(const Matrix& other)
{
this->resize(other.row, other.column);
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++)
{
matrix[i][j] = other.matrix[i][j];
}
}
So, after it, you'll be accessing memory through an uninitialized pointer.
You need assignment operators, constructors that correctly allocate memory for your matrices. You need matching destructors, too. Look up "rule of 3".
Matrix& Matrix::operator=(const Matrix& other) {
if (this == &other) {
return *this;
}
this->resize(other.row, other.column);
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
matrix[i][j] = other.matrix[i][j];
}
}
return *this;
}
Matrix Matrix::operator+(int num) const {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
this->matrix[i][j] += num;
}
}
return *this;
}
When Function return a matrix by finishing the scope Destructor get called and after we call assignment operator overloading on it, it can't reach the member of that matrix because it already get deleted by Destructor so it throws a exception.
I wrote this before but it did not work until i realize that we should put (&) for (=) operator if we want use this operators overloading one after the other. so now it's working well
This is supposed to be my HW in OOP course. SO i asked to create matrix class. Code works fine - all methods and new operands works fine BUT when my D`tor is empty and when i write there code to free memory i get this error. Thanks for help
int main()
{
MyMatrix m1(3, 3);
MyMatrix m2(3, 3);
MyMatrix res(3, 3);
m1.Set();
m2.Set();
cout << m1;
cout << m2;
res = m1 + m2;
cout << res;
}
CPP
MyMatrix::MyMatrix(int row, int col) // C`tor with specific data
{
n = row;
m = col;
matrix = new int* [n]; // Memory allocation for rows
for (int i = 0; i < n; i++)
{
matrix[i] = new int[m]; // Memory Allocation for columns
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = 0;
}
}
}
MyMatrix::~MyMatrix() // Default d`tor
{
for (int i = 0; i < n; i++)
{
delete[] matrix[i];
}
delete[] matrix;
}
void MyMatrix::Set()
{
cout << "Enter new row" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> matrix[i][j];
}
if (i != (n - 1))
{
cout << "Enter new row" << endl;
}
}
}
ostream& operator<<(ostream& out, const MyMatrix& matrix)
{
for (int i = 0; i < matrix.n; i++)
{
//run in loop on every column.
for (int j = 0; j < matrix.m; j++)
//print value with a space.
out << matrix.matrix[i][j] << "t";
//at the end of every row jump line.
out << endl;
}
out << endl;
return out;
}
MyMatrix& MyMatrix::operator= (const MyMatrix& mat1)
{
n = mat1.n;
m = mat1.m;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = mat1.matrix[i][j];
}
}
return *this;
}
const MyMatrix MyMatrix::operator+(const MyMatrix& mat1) const
{
MyMatrix temp(n, m);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
temp.matrix[i][j] = matrix[i][j] + mat1.matrix[i][j];
}
}
return temp;
}
H file
class MyMatrix
{
private:
int **matrix;
int n, m;
public:
MyMatrix(int a, int b);
~MyMatrix();
void Set();
const MyMatrix operator+ (const MyMatrix& mat1) const;
MyMatrix& operator= (const MyMatrix& mat1);
friend ostream& operator<<(ostream& out, const MyMatrix& matrix);
};
i am working on multiplication of matrix
it is something like
m5 = m2 * m3;
cout << "m2 * m3 is : " << endl<< m5 << endl;
and this is my code
const Matrix Matrix::operator*(const Matrix &a)
{
Matrix temp(a.row,a.col);
for (int i = 0; i<row; i++)
{
for (int j = 0; j<col; j++)
{
for (int k = 0; k<a.row; k++)
{
temp.data[i][j] = temp.data[i][j] + data[i][k] * a.data[k][j];
}
}
}
return temp;
}
However, there is an error always showing at my printing function
ostream& operator<<(ostream &output, const Matrix &a)
{
for (int i = 0; i < a.row; i++)
{
for (int j = 0; j < a.col; j++)
{
output << a.data[i][j] << "\t";
}
output << "" << endl;
}
return output;
}
seems there has a problem on a.data[i][j] which i dont know what's the problem
it works fine on addition.
it is showing an error {data0x005fba90{0xfeeefeee{???}}
can anybody give any advice or suggestions or help on this situation
this is my copy constructor
Matrix::Matrix(const Matrix&m2)
{
row = m2.row;
col = m2.col;
setUp(row, col);
for (int i = 0; i<row; i++)
{
for (int j = 0; j<col; j++)
{
data[i][j] = 0;
}
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
data[i][j] = m2.data[i][j];
}
}
}
this is the set up and default
Matrix::Matrix()
{
row =0;
col = 0;
for (int i = 0; i<row; i++)
{
for (int j = 0; j<col; j++)
{
data[i][j] = 0;
}
}
}
Matrix::Matrix(int a, int b, double d[], int c)
{
row = a;
col = b;
setUp(row, col);
int counter = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
data[i][j] = d[counter];
counter++;
}
}
}
and the set up
void Matrix::setUp(int a, int b)
{
row = a;
col = b;
data = new double*[row];
for (int i = 0; i < row; i++) data[i] = new double[col];
}
Without seeing your Matrix constructor, or the class definition, it's hard to say for certain, but if you look at this expression
temp.data[i][j] + data[i][k] * a.data[k][j]
Depending on what data is, if you don't explicitly initialize the data member in the constructor when you create temp then its contents will not automatically be initialized, and the contents will be indeterminate and using it will lead to undefined behavior.
Another possible source of problems might be the lack of a copy-constructor, or a faulty copy-constructor. This is a problem since you return temp by value which invokes the copy-constructor.
I'm trying to implement a matrix class and overloading the + and = operators.
The problem is I'm getting weird output when I add two matrices as in this picture.
adding two matrices output console
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
int **p, m, n;
public:
Matrix(int row, int col)
{
m = row;
n = col;
p = new int*[m];
for (int i = 0; i < m; i++)
p[i] = new int[n];
}
Matrix (Matrix & x)
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
p[i][j]=x.p[i][j];
}
}
}
~Matrix()
{
for (int i = 0; i < m; i++)
delete [] p[i];
delete [] p;
}
void accept()
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
}
void display()
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
cout << setw(10)<<left <<p[i][j] <<" | ";
}
cout << "\n--------------------------------------"<<endl;
}
}
Matrix& operator +(const Matrix & m2)
{
Matrix r(m, n);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
r.p[i][j] = p[i][j] + m2.p[i][j];
}
}
return r;
}
Matrix& operator= (const Matrix & eq)
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
p[i][j]=eq.p[i][j];
}
}
return *this;
}
friend Matrix operator * (Matrix, Matrix);
};
Matrix operator* (Matrix a , Matrix b)
{
Matrix B(1,1);
if(a.n == b.m)
{
Matrix T(a.m, b.n);
for(int i = 0; i < a.m; i++)
{
for(int k = 0; k < b.n; k++)
{
T.p[i][k] = 0;
for(int j = 0; j < a.n; j++)
{
T.p[i][k]+= a.p[i][j] * b.p[j][k];
}
}
}
B = T;
}
return B;
}
int main()
{
cout << "Enter Matrix 1 (3x2):"<<endl;
Matrix m1(3,2);
m1.accept();
m1.display();
cout << "Enter Matrix 2 (3x2):"<<endl;
Matrix m2(3,2);
m2.accept();
m2.display();
Matrix m3(3,2);
m3=m1+m2;
cout <<endl<< "matrix1 + matix2 is:\n "<<endl;
m3.display();
}
Any ideas how to fix that? I would be grateful for your help and advices with improving it because probably there will be some mistakes.
I use CodeBlocks IDE.
The problem is that your operator + returns a local variable Matrix as a reference; this is undefined behavior. It should be returned by value, not by reference.
Make sure that your Matrix class has a copy constructor that takes a const input, i.e.
Matrix (const Matrix & x)
and that it initializes the array before writing into it. Move the initialization code (the two loops with allocation) into a separate private function, and call it from the default constructor and from the copy constructor.