简体   繁体   English

C ++用子矩阵值替换矩阵值

[英]C++ replacing matrix values with sub-matrix values

I have a University assignment whereby I have a 1D array, containing 262144 values. 我有大学作业,因此我有一个一维数组,包含262144个值。 I've created a matrix class which places these values into an object with the datasource being the double* list of 262144 values. 我创建了一个矩阵类,将这些值放入对象中,数据源为262144个值的double *列表。

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). 我需要能够从另一组262144值(也已放入矩阵对象中)中获得一个子矩阵(我能够做到)。

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. 但是,我遇到了严重的麻烦,在过去的3天里,我一直在努力尝试从子矩阵中替换原始矩阵值。 I've tried passing by reference, creating Matrix*'s. 我尝试通过引用传递,创建Matrix *。 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. 如果可以看到main()也会有所帮助,但是它真正包含的只是使用重载构造函数创建矩阵对象。

explanation 说明

Answer is only 4 years late . 答案只迟了四年。 . .

Anyway. 无论如何。 Maybe it will help somebody else. 也许会帮助别人。 The secret is to use a std::valarray . 秘诀是使用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 . 而您的子矩阵co可以是一个班轮。 . .

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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