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;
}
Related
I need make Pascal Triangle matrix using vectors and then print it.
This algorithm would work with arrays, but somehow it doesn't work with matrix using vectors.
#include <iomanip>
#include <iostream>
#include <vector>
typedef std::vector<std::vector<int>> Matrix;
int NumberOfRows(Matrix m) { return m.size(); }
int NumberOfColumns(Matrix m) {
if (m.size() != 0)
return m[0].size();
return 0;
}
Matrix PascalTriangle(int n) {
Matrix mat;
int a;
for (int i = 1; i <= n; i++) {
a = 1;
for (int j = 1; j <= i; j++) {
if (j == 1)
mat.push_back(j);
else
mat.push_back(a);
a = a * (i - j) / j;
}
}
return mat;
}
void PrintMatrix(Matrix m, int width) {
for (int i = 0; i < NumberOfRows(m); i++) {
for (int j = 0; j < NumberOfColumns(m); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
int main() {
Matrix m = PascalTriangle(7);
PrintMatrix(m, 10);
return 0;
}
I get nothing on screen, and here's the same code just without matrix using vectors program (which works fine).
Could you help me fix this code?
The main problem is that in PascalTriangle, you are starting out with an empty Matrix in both the number of rows and columns.
Since my comments mentioned push_back, here is the way to use it if you did not initialize the Matrix with the number of elements that are passed in.
The other issue is that NumberOfColumns should specify the row, not just the matrix vector.
The final issue is that you should be passing the Matrix by const reference, not by value.
Addressing all of these issues, results in this:
Matrix PascalTriangle(int n)
{
Matrix mat;
for (int i = 0; i < n; i++)
{
mat.push_back({}); // creates a new empty row
std::vector<int>& newRow = mat.back(); // get reference to this row
int a = 1;
for (int j = 0; j < i + 1; j++)
{
if (j == 0)
newRow.push_back(1);
else
newRow.push_back(a);
a = a * (i - j) / (j + 1);
}
}
return mat;
}
And then in NumberOfColumns:
int NumberOfColumns(const Matrix& m, int row)
{
if (!m.empty())
return m[row].size();
return 0;
}
And then, NumberOfRows:
int NumberOfRows(const Matrix& m) { return m.size(); }
And last, PrintMatrix:
void PrintMatrix(const Matrix& m, int width)
{
for (int i = 0; i < NumberOfRows(m); i++)
{
for (int j = 0; j < NumberOfColumns(m, i); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
Here is a live demo
Your code won't compile because you have numerous errors in PascalTriangle.
For one, you initialize a matrix with no elements. Additionally, you use matrix indices starting at 1 rather than 0.
The following prints things for me:
Matrix PascalTriangle(int n) {
Matrix mat(n, std::vector<int>(n, 0)); // Construct Matrix Properly
int a;
for (int i = 0; i < n; i++) { // Start index at 0
a = 1;
for (int j = 0; j < i + 1; j++) { // Start index at 0
if (j == 0) // Changed 1 to 0
mat[i][j] = 1;
else
mat[i][j] = a;
a = a * (i - j) / (j+1); // Changed j to j+1 since j starts at 0
}
}
return mat;
}
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
For an assignment we have been asked to create a program that can unshuffle a jumpled 512x512 gray scale image (it was shuffled by being broken down into 32x32 blocks). The greyscale image is imported into the project via text file and then it uses a predefined function to convert the values into a 1d array. Using this we were tasked with creating a matrix class that can store and ultimately manipulate the image with the intention of restoring the shuffled image.
I am having issues with creating submatrices to use in a comparison fashion (my general idea is selecting the first 32x32 block from the shuffled and the normal image then compare their pixel values to find a match). the function for my getBlock function is as follows:
Matrix Matrix::getBlock(int startRow, int endRow, int startColumn, int endColumn)
{
int Row = endRow - startRow;
int Column = endColumn - startColumn;
double* block = new double[(Row) *(Column)];
int n = endColumn - startColumn;
for (int ii = startRow; ii < endRow; ii++)
{
for (int jj = startColumn; jj < endColumn; jj++)
{
int k = ii*n + jj;
block[k] = data[ii*N + jj];
}
}
Matrix t(Row, Column, block);
return t;
delete[] block;
}
And in my main() i have attempted to implement the function as follows:
for (int x = 0; x < 480; x += 32) // so starts at 0 and continues if x less than 480 as 480 + 32 = 512
{
for (int y = 0; y < 480; y += 32) // same as x but with y
{
Matrix block = ShuffledCode.getBlock(x, (x + 32), y, (y + 32));
cout << block.sum() << endl;
}
}
My issue arises whenever the start column and the start row become anything other than 0, for instance in the above code the value is displayed for the first block (startrow 0, endrow 32, startcolumn 0, endcolumn 32) correctly however when the loop iterates i get a heap corruption error and i can't figure out what is going wrong. Another observation is that if i increase the endrow and endcolumn above 32 (so for instance if i increased them to 64) it seems to function fine and return the correct value.
If anyone has any ideas what could be causing it i would be very grateful, been working on it for days and haven't made any progress. I have also included all my code below in case the problem is related to another part of the program. the source.cpp file:
#include <sstream> // stringstream
#include <iostream> // cout, cerr
#include <fstream> // ifstream
#include <istream>
#include <assert.h>
#include "Matrix.H"
using namespace std;
// Input data are provided in .txt format and can be converted to .pgm files for visualization
// Download (free) ImageJ for plotting images in .pgm format
// http://rsb.info.nih.gov/ij/download.html
// Reads .txt file representing an image of R rows and C Columns stored in filename
// and converts it to a 1D array of doubles of size R*C
// Memory allocation is performed inside readTXT
double* readTXT(char *fileName, int sizeR, int sizeC);
// Converts a 1D array of doubles of size R*C to .pgm image of R rows and C Columns
// and stores .pgm in filename
// Use Q = 255 for greyscale images and Q=1 for binary images.
void WritePGM(char *filename, double *data, int sizeR, int sizeC, int Q);
int main()
{
// This part will show you how to use the two functions.
//M and N represent the number of rows and columns in the image,
//e.g. for task 1: logo_with_noise and logo_shuffled, M = 512, N = 512
//e.g. for task 2, Cluttered_scene, M = 768, N = 1024
//e.g. for task 2, Wally_grey, M = 49, N = 36
int M = 512; int N = 512; int count = 0;
// input_data is a pointer to a 1D array of M*N doubles stored in heap. Memory allocation is performed
// inside readTXT. readTXT will read an image (in .pgm format) of size MxN and will store the result in input_data.
// once you're done with data DO NOT forget to delete the memory as in the end of this main() function
double* input_data = 0;
double* noise_data = 0;
cout << endl;
cout << "Data from text file -------------------------------------------" << endl;
// shuffled image is stored in inputFileName, input_data holds the data in a 1d array
char* inputFileName = "C:\\Users\\Jamie\\SkyDrive\\Documents\\SoftwareDevAss\\ADS_Assignment\\Datafile\\logo_shuffled.txt";
input_data = readTXT(inputFileName, M, N);
// the img with noise is stored in inputFileName2, noise_data holds the data in a 1d array
char* inputFileName2 = "C:\\Users\\Jamie\\SkyDrive\\Documents\\SoftwareDevAss\\ADS_Assignment\\Datafile\\logo_with_noise.txt";
noise_data = readTXT(inputFileName2, M, N);
// this loop reduces the noise on the provided image to make it clear, uses threshold 170 as i found that gives the best results
for (int x = 0; x < 262144; x++)
{
if (noise_data[x] < 170)
{
noise_data[x] = 0;
}
else
{
noise_data[x] = 255;
}
}
/*long int pLength = 262144; // total length in pixels of 1d array holding the image
long int bLength = 1024; // total length in pixels of each block (32x32)
long int cLength = 262144; // current remaning length in pixels of 1d array holding the image
long int sum = 0; // theoretical limit of 262144 (if all pixels are white thus have the value 255)
for (int rBlocks = 0; rBlocks < 254; rBlocks++)
{
sum = 0;
cLength = pLength - ((rBlocks) * 1024);
double *sub = noise_data - cLength;
assert(sub[0] == noise_data[bLength * rBlocks]);
for (int i = 0; i < 1024; i++)
{
sum += sub[i];
}
cout << sum << endl;
}
*/
// at this point noise_data holds the original image.
Matrix ShuffledCode(512, 512, input_data);
Matrix SortedCode(512, 512, noise_data);
bool wedone = false;
int val = 1024;
// issue with increasing the start row and column above 0, end row and column can be increased fine.
for (int x = 0; x < 480; x += 32) // so starts at 0 and continues if x less than 480 as 480 + 32 = 512
{
for (int y = 0; y < 480; y += 32) // same as x but with y
{
Matrix block = ShuffledCode.getBlock(x, (x + 32), y, (y + 32));
cout << block.sum() << endl;
}
}
/*for (int x = 0; x < 262144; x++)
{
input_data[x] = noise_data[x];
}
*/
/*int MAX = 262144;
for (int i=0; i<MAX; i++)
{
for (int j = i + 1; j < MAX; j++)
{
if (input_data[i] == input_data[j] && noise_data[i] == noise_data[j])
{
}
else
{
input_data[i] = noise_data[i];
input_data[j] = noise_data[j];
}
}
}
*/
// writes data back to .pgm file stored in outputFileName
char* outputFileName = "C:\\Users\\Jamie\\SkyDrive\\Documents\\SoftwareDevAss\\ADS_Assignment\\Datafile\\logo_restored.pgm";
char* cleanFile = "C:\\Users\\Jamie\\SkyDrive\\Documents\\SoftwareDevAss\\ADS_Assignment\\Datafile\\logo_clean.pgm";
char* tester = "C:\\Users\\Jamie\\SkyDrive\\Documents\\SoftwareDevAss\\ADS_Assignment\\Datafile\\tester.pgm";
// Use Q = 255 for greyscale images and 1 for binary images.
int Q = 255;
WritePGM(outputFileName, input_data, M, N, Q);
WritePGM(cleanFile, noise_data, M, N, Q);
delete[] noise_data;
delete[] input_data;
return 0;
}
//Consructor
Matrix::Matrix(int sizeR, int sizeC, double* input_data)
{
M = sizeR;
N = sizeC;
data = new double[M*N];
for (int ii = 0; ii < M*N; ii++)
{
data[ii] = input_data[ii];
}
}
Matrix::Matrix(int sizeR, int sizeC)
{
M = sizeR;
N = sizeC;
data = new double[M*N];
for (int ii = 0; ii < M*N; ii++)
{
*(data + ii) = 0;
}
}
//Destructor
Matrix::~Matrix()
{
delete[] data;
}
//Copy Constructor
Matrix::Matrix(const Matrix& existingMatrix)
{
M = existingMatrix.getM();
N = existingMatrix.getN();
data = new double[M*N];
for (int ii = 0; ii < M; ii++)
{
for (int jj = 0; jj < N; jj++)
{
int k = ii*N + jj;
data[k] = existingMatrix.get(ii, jj);
}
}
}
//Pass by constant value
double Matrix::get(int i, int j) const
{
int k = i*N + j;
return data[k];
}
//Pass by Refrence
const void Matrix::set(int i, int j, double& val)
{
int k = i*N + j;
val = data[k];
}
//Return Value of M
int Matrix::getM() const
{
return M;
}
//Return Value of N
int Matrix::getN() const
{
return N;
}
//Returns part of the matrix
Matrix Matrix::getBlock(int startRow, int endRow, int startColumn, int endColumn)
{
int Row = endRow - startRow;
int Column = endColumn - startColumn;
double* block = new double[(Row) *(Column)];
int n = endColumn - startColumn;
for (int ii = startRow; ii < endRow; ii++)
{
for (int jj = startColumn; jj < endColumn; jj++)
{
int k = ii*n + jj;
block[k] = data[ii*N + jj];
}
}
Matrix t(Row, Column, block);
return t;
delete[] block;
}
//Allows for addion of Matricies, Operation Overloading.
Matrix Matrix::operator +(const Matrix& B)
{
Matrix C = Matrix(M, N, 0);
double temp;
for (int ii = 0; ii < M; ii++)
{
for (int jj = 0; jj < N; jj++)
{
temp = data[ii*N + jj] + B.get(ii, jj);
C.set(ii, jj, temp);
}
}
return C;
}
//Makes x and y equal, Opperation Overloading.
Matrix Matrix::operator =(const Matrix& B)
{
if (this == &B)
{
return *this;
}
else
{
M = B.getM();
N = B.getN();
delete[] data;
data = new double[M*N];
for (int ii = 0; ii < M; ii++)
{
for (int jj = 0; jj < N; jj++)
{
data[ii*N + jj] = B.get(ii, jj);
}
}
return *this;
}
}
//Allows for subtraction of matricies, Operation Overloading.
Matrix Matrix::operator -(const Matrix& B)
{
Matrix C = Matrix(M, N);
double temp;
for (int ii = 0; ii < M - 1; ii++)
{
for (int jj = 0; jj < N - 1; jj++)
{
temp = data[ii*N + jj] - B.get(ii, jj);
C.set(ii, jj, temp);
}
}
return C;
}
//Allows for multiplication of Matricies, Operation Overloading.
Matrix Matrix::operator *(const Matrix& B)
{
Matrix C = Matrix(M, B.getN());
double temp;
for (int ii = 0; ii < M; ii++)
{
for (int jj = 0; jj < N; jj++)
{
temp = data[ii*N + jj] * B.get(ii, jj);
C.set(ii, jj, temp);
}
}
return C;
}
//Allows for addition of Matricies, Operation Overloading.
Matrix Matrix::operator /(const Matrix& B)
{
Matrix C = Matrix(M, B.getN(), 0);
double temp;
for (int ii = 0; ii < M; ii++)
{
for (int jj = 0; jj < N; jj++)
{
temp = data[ii*N + jj] / B.get(ii, jj);
C.set(ii, jj, temp);
}
}
return C;
}
//Incrmentation of all values in Matrix by 1, Operation Overloading.
Matrix Matrix::operator ++()
{
for (int ii = 0; ii < M*N; ii++)
{
data[ii] = data[ii]++;
}
return *this;
}
//Allows calling of "get" function indirectly.
double Matrix::operator() (int i, int j)
{
return data[i*N + j];
}
double Matrix::sum()
{
double total = 0.0;
for (int ii = 0; ii < M*N; ii++)
{
total = total + data[ii];
}
return total;
}
void Matrix::out()
{
for (int ii = 0; ii < M*N; ii++)
{
if (data[ii] == 255)
cout << "1 ";
else
cout << data[ii] << " ";
}
}
// Read .txt file with image of size RxC, and convert to an array of doubles
double* readTXT(char *fileName, int sizeR, int sizeC)
{
double* data = new double[sizeR*sizeC];
int i = 0;
ifstream myfile(fileName);
if (myfile.is_open())
{
while (myfile.good())
{
if (i>sizeR*sizeC - 1) break;
myfile >> *(data + i);
// cout << *(data+i) << ' '; // This line display the converted data on the screen, you may comment it out.
i++;
}
myfile.close();
}
else cout << "Unable to open file";
//cout << i;
return data;
}
// convert data from double to .pgm stored in filename
void WritePGM(char *filename, double *data, int sizeR, int sizeC, int Q)
{
int i, j;
unsigned char *image;
ofstream myfile;
image = (unsigned char *) new unsigned char[sizeR*sizeC];
// convert the integer values to unsigned char
for (i = 0; i<sizeR*sizeC; i++)
image[i] = (unsigned char) data[i];
myfile.open(filename, ios::out | ios::binary | ios::trunc);
if (!myfile) {
cout << "Can't open file: " << filename << endl;
exit(1);
}
myfile << "P5" << endl;
myfile << sizeC << " " << sizeR << endl;
myfile << Q << endl;
myfile.write(reinterpret_cast<char *>(image), (sizeR*sizeC)*sizeof(unsigned char));
if (myfile.fail()) {
cout << "Can't write image " << filename << endl;
exit(0);
}
myfile.close();
delete[] image;
}
The Matrix class header file is as follows:
#pragma
#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
protected:
int M;
int N;
double* data;
public:
Matrix(int sizeR, int sizeC, double* input_data); //Constructor
Matrix(int sizeR, int sizeC);
~Matrix(); //Destructor
Matrix(const Matrix& existingMatrix); //Copy Constructor
double get(int i, int j) const; //Returns value at specified location
const void set(int i, int j, double& val);//Changes value at specified location
int getM() const; //Return value of M
int getN() const; //Return value of N
Matrix getBlock(int startRow, int endRow, int startColumn, int endColumn);//Return section of Matrix
Matrix operator + (const Matrix& B); // addition
Matrix operator = (const Matrix& B); // equals
Matrix operator - (const Matrix& B); // subtraction
Matrix operator * (const Matrix& B); // multiplication
Matrix operator / (const Matrix& B); // division
Matrix operator ++ (); // increment by 1
double operator () (int i, int j);
void out();
double sum();
};
class BinaryImage
:public Matrix
{
public:
BinaryImage(int sizeR, int sizeC, double* input_data, double thresh);
~BinaryImage();
BinaryImage(const Matrix& rhs, double thresh);
BinaryImage(const BinaryImage& existingBinIm);
const void set(int i, int j, double& val);
};
#endif
Any help would be much appreciated, thanks.
For starters, look at this in your getBlock method:
return t;
delete[] block;
The delete after the return means heap-memory is leaked since block never gets deleted.
Now why you have heap corruption:
You are always going to allocate a block that is 32*32 (see how you are calculating end - start? its always going to be 32)
// This is how you call, x = startRow, x+32 is endRow.
Matrix block = ShuffledCode.getBlock(x, (x + 32), y, (y + 32));
// This is inside your method: (endRow is startRow + 32) = 32 always
int Row = endRow - startRow;
But inside that method, you are accessing way beyond 32 using the input params. So when the loop gets to i = 1, startRow is 32 and end row is 64. But your matrix only goes to 32!
Alright, I'm implementing a dynamic 2-dimensional matrix class. For a basis, this is what I have so far:
template <typename Type>
class dyMatrix {
private:
Type *mat;
int lines, columns;
int length;
void assimilate (const dyMatrix<Type>& that) {
lines = that.lines;
columns = that.columns;
length = that.length;
}
public:
dyMatrix (int height, int width)
: lines(height), columns(width), mat(0)
{
length = lines * columns;
mat = new Type[length];
};
// ---
int getLines() {
return lines;
};
int getColumns() {
return columns;
};
int getLength() {
return length;
}
// ---
Type& operator() (int i, int j) {
return mat[j * columns + i];
};
Type& operator() (int i) {
return mat[i];
};
// ---
dyMatrix (const dyMatrix<Type>& that) {
this->assimilate(that);
// ---
mat = new Type[length];
for (int i = 0; i < length; i++) {
mat[i] = that.mat[i];
}
};
dyMatrix& operator= (const dyMatrix<Type>& that) {
Type *local_mat = new Type[that.length];
for (int i = 0; i < that.length; i++) {
local_mat[i] = that.mat[i];
}
// ---
this->assimilate(that);
delete[] mat;
mat = local_mat;
// ----
return *this;
};
~dyMatrix() {
delete mat;
};
};
My problem is that I've been having some specific problems when trying to read input into it. For example, I have the following main():
int main() {
int lanes, cols;
cin >> lanes >> cols;
dyMatrix<int> map(lanes, cols);
/* CONTINUE READING */
cout << endl;
for (int i = 0; i < lanes; i++) {
for (int j = 0; j < cols; j++) {
cout << map(i, j) << ' ';
}
cout << endl;
}
}
Where it is a commented section, if I put the following lines of code:
int aux;
for (int i = 0; i < lanes; i++) {
for (int j = 0; j < cols; j++) {
cin >> map(i, j);
}
}
or:
int aux;
for (int i = 0; i < lanes; i++) {
for (int j = 0; j < cols; j++) {
cin >> aux;
map(i, j) = aux;
}
}
or even:
int aux;
for (int i = 0; i < lanes; i++) {
for (int j = 0; j < cols; j++) {
cin >> aux;
map(i, j) = i + j; // !!!
}
}
...It won't work. For some reason, however, the following will:
int aux;
for (int i = 0; i < lanes; i++) {
for (int j = 0; j < cols; j++) {
// cin >> aux;
map(i, j) = i + j; // Still the same thing as before, logically
}
}
I do not understand. What is happening here?
edit: Sorry, forgot to include my debugging procedure.
Input:
3 5
1 2 3 4 5
1 2 3 4 5
The first line has the dimensions of the matrix. The second and third lines are values written into it; After pressing Enter at the end of the third line, however, the program crashes.
It doesn't even work with this input:
3 5
1
2
3
4
5
1
2
3
4
5
It crashes right after the second 5, again.
Your indices appear the wrong way around:
Type& operator() (int i, int j) {
return mat[j * columns + i];
};
Here, i is clearly the column and j is the row. However, in your loops the arguments appear in the opposite order:
for (int i = 0; i < lanes; i++) {
for (int j = 0; j < cols; j++) {
map(i, j) = ...; // row then column
}
}
Also, the destructor should be using delete[] and not delete.