【发布时间】:2021-12-31 16:26:36
【问题描述】:
我有一个简单的 2D(行、列)矩阵,我目前根据下面的算法重新排序,使用另一个数组作为最终容器来交换项目。
问题是我需要节省内存(代码在非常低端的设备上运行),因此我需要想办法就地重新排序数组。
算法如下:
for (int iRHS = 0; iRHS < NUM_VARS; iRHS++)
for (int iRow = 0; iRow < _numEquations; iRow++) {
coef[iRHS][iRow] = _matrixCoef(iRow, iRHS);
}
注意:coef 是指向通过下标进行双重访问的指针,_matrixCoef 是一个矩阵辅助类,并使用由 operator(row,col) 访问的双重向量。在这里我想消除coef,以便所有值都在_matrixCoef中重新排序。
编辑:NUM_VARS 是定义设置为 2。
毕竟这可能就地吗?
编辑 2:
这是上面通过运算符重载(行,列)访问的矩阵类:
struct Matrix
{
/// Creates a matrix with zero rows and columns.
Matrix() = default;
/// Creates a matrix with \a rows rows and \a col columns
/// Its elements are initialized to 0.
Matrix(int rows, int cols) : n_rows(rows), n_cols(cols), v(rows * cols, 0.) {}
/// Returns the number or rows of the matrix
inline int getNumRows() const { return n_rows; }
/// Returns the number or columns of the matrix.
inline int getNumCols() const { return n_cols; }
/// Returns the reference to the element at the position \a row, \a col.
inline double & operator()(int row, int col) { return v[row + col * n_rows]; }
/// Returns the element at the position \a row, \a col by value.
inline double operator()(int row, int col) const { return v[row + col * n_rows]; }
/// Returns the values of the matrix in column major order.
double const * data() const { return v.data(); }
/// Returns the values of the matrix in column major order.
double * data() { return v.data(); }
/// Initialize the matrix with given size. All values are set to zero.
void initialize(int iRows, int iCols)
{
n_rows = iRows;
n_cols = iCols;
v.clear();
v.resize(iRows * iCols);
}
void resize(int iRows, int iCols)
{
n_rows = iRows;
n_cols = iCols;
v.resize(iRows * iCols);
}
private:
int n_rows = 0;
int n_cols = 0;
std::vector<double> v;
};
【问题讨论】:
-
这段代码看起来像矩阵转置,你的重新排序算法有什么不同吗?如果是,以什么方式?你能告诉我们 _MatrixCoef 助手在内部做什么吗?
-
见this question。如果矩阵是方形的,这很容易通过交换元素来实现,但如果矩阵不是方形的,你要么需要一个新矩阵,要么需要更改访问现有内存的方式,要么需要更复杂的代码来移动元素不是两个值的简单交换。
-
@trialNerror _matrixCoef 是之前求解的线性系统的两个结果矩阵之一。例如,要更改在这个地方订购商品的方式并不容易。
-
使用 NUM_VARS == 2,您的任务是执行“完美随机播放”的逆操作。您可以在谷歌上搜索很多关于完美洗牌的信息,这些洗牌也适用于逆运算。在线性时间内就地完成这项工作很棘手。