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

时间:2015-12-01 19:51:16

标签: c++ arrays pointers matrix

我有一个大学任务,我有一个1D数组,包含262144个值。我创建了一个矩阵类,它将这些值放入一个对象中,数据源是262144值的double *列表。

我需要能够从另一组262144值(我也将它放入矩阵对象)中获得一个子矩阵(我能够做到)。

但是,我遇到了严重的麻烦,过去3天我一直在努力尝试从子矩阵中替换原始矩阵值。我试过通过引用传递,创建了Matrix *' s。我已经尝试过我们所教过的所有内容,甚至还研究了一些我不了解的方法。我会在这里抛出我的代码,看看是否有人可以向我解释一个能够做到这一点的方法。

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

如果看到main()有帮助我也可以提供它,但它真正包含的是使用重载构造函数创建矩阵对象。

explanation

1 个答案:

答案 0 :(得分:0)

答案仅晚了4年。 。

无论如何。也许会帮助别人。秘诀是使用std::valarray。这样一来,在矩阵上进行操作就非常简单。而且,许多功能都可用。

您要实现的所有功能已经可用。

并且您的子矩阵sub可以是一个内衬。 。

请参见示例代码:

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