将行附加到矩阵的最佳方法是什么?
What is the best way to append a row to matrix?
我正在尝试向预先存在的矩阵追加一行。我写了一些代码(如下所示)来解决这个问题,但我忍不住觉得有更好的方法来做到这一点(或者也许已经有一个 Apache Commons 函数可以做到这一点???)。
代码
private RealMatrix appendRow(RealMatrix m) {
double[][] mData = m.getData();
double[][] newData = new double[m.getRowDimension()+1][m.getColumnDimension()];
for (int i = 0; i < m.getRowDimension(); i++) {
newData[i] = mData[i];
}
newData[m.getRowDimension()] = new double[m.getColumnDimension()];
return MatrixUtils.createRealMatrix(newData);
}
示例用法和输出
RealMatrix m = MatrixUtils.createRealMatrix(new double[][]{{1,2,3}, {4,5,6}});
Log.i("m", m.toString());
// Array2DRowRealMatrix{{1.0,2.0,3.0},{4.0,5.0,6.0}}
m = appendRow(m);
Log.i("m", m.toString());
// Array2DRowRealMatrix{{1.0,2.0,3.0},{4.0,5.0,6.0},{0.0,0.0,0.0}}
如有任何提示,我们将不胜感激!
你走对了。我唯一可以添加的是替换这个循环:
for (int i = 0; i < m.getRowDimension(); i++) {
newData[i] = mData[i];
}
与:
for (int i = 0; i < m.getRowDimension(); i++) {
System.arraycopy(mData[i], 0, newData[i], 0, mData[i].length);
}
假设 RealMatrix
是您的自定义 class 您无论如何都需要编写一些代码。有像 Apache Commons Lang 这样的库,它有一个方法 ArrayUtils.add(array, new element)
(实际上是一堆重载),但你的代码并不复杂,不足以证明为此添加额外的依赖项是合理的。
注意事项:
double[][] newData = new double[m.getRowDimension()+1][m.getColumnDimension()];
已经创建了 "inner" 数组,即行,因此不需要 newData[m.getRowDimension()] = new double[m.getColumnDimension()];
。
另请注意,newData[i] = mData[i];
存在使用相同行的多个矩阵的风险,因此更改其中一个也会更改其他矩阵。因此,我建议您使用 System.arrayCopy(mData[i], 0, newData[i], 0, mData[i].length )
而不是 newData[i] = mData[i]
来制作副本。
为了说明最后一点,请尝试 RealMatrix m2 = appendRow(m);
,然后更改其中一个复制的元素(例如,将 [0][0] 更改为 7)并打印 m
和 m2
.
假设重用行数组不是问题(您在当前代码中这样做),最简单的方法是将 for 循环替换为:
double[][] newData = Arrays.copyOf(data, 0, data.length + 1);
我正在尝试向预先存在的矩阵追加一行。我写了一些代码(如下所示)来解决这个问题,但我忍不住觉得有更好的方法来做到这一点(或者也许已经有一个 Apache Commons 函数可以做到这一点???)。
代码
private RealMatrix appendRow(RealMatrix m) {
double[][] mData = m.getData();
double[][] newData = new double[m.getRowDimension()+1][m.getColumnDimension()];
for (int i = 0; i < m.getRowDimension(); i++) {
newData[i] = mData[i];
}
newData[m.getRowDimension()] = new double[m.getColumnDimension()];
return MatrixUtils.createRealMatrix(newData);
}
示例用法和输出
RealMatrix m = MatrixUtils.createRealMatrix(new double[][]{{1,2,3}, {4,5,6}});
Log.i("m", m.toString());
// Array2DRowRealMatrix{{1.0,2.0,3.0},{4.0,5.0,6.0}}
m = appendRow(m);
Log.i("m", m.toString());
// Array2DRowRealMatrix{{1.0,2.0,3.0},{4.0,5.0,6.0},{0.0,0.0,0.0}}
如有任何提示,我们将不胜感激!
你走对了。我唯一可以添加的是替换这个循环:
for (int i = 0; i < m.getRowDimension(); i++) {
newData[i] = mData[i];
}
与:
for (int i = 0; i < m.getRowDimension(); i++) {
System.arraycopy(mData[i], 0, newData[i], 0, mData[i].length);
}
假设 RealMatrix
是您的自定义 class 您无论如何都需要编写一些代码。有像 Apache Commons Lang 这样的库,它有一个方法 ArrayUtils.add(array, new element)
(实际上是一堆重载),但你的代码并不复杂,不足以证明为此添加额外的依赖项是合理的。
注意事项:
double[][] newData = new double[m.getRowDimension()+1][m.getColumnDimension()];
已经创建了 "inner" 数组,即行,因此不需要 newData[m.getRowDimension()] = new double[m.getColumnDimension()];
。
另请注意,newData[i] = mData[i];
存在使用相同行的多个矩阵的风险,因此更改其中一个也会更改其他矩阵。因此,我建议您使用 System.arrayCopy(mData[i], 0, newData[i], 0, mData[i].length )
而不是 newData[i] = mData[i]
来制作副本。
为了说明最后一点,请尝试 RealMatrix m2 = appendRow(m);
,然后更改其中一个复制的元素(例如,将 [0][0] 更改为 7)并打印 m
和 m2
.
假设重用行数组不是问题(您在当前代码中这样做),最简单的方法是将 for 循环替换为:
double[][] newData = Arrays.copyOf(data, 0, data.length + 1);