简体   繁体   中英

C++ replacing matrix values with sub-matrix values

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM