Каков наилучший способ добавить строку в матрицу? - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь добавить строку в уже существующую матрицу. Я написал некоторый код (показанный ниже), который делает свое дело, но я не могу не почувствовать, что есть лучший способ сделать это (или, возможно, уже есть функция 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}}

Любые советы приветствуются!

Ответы [ 3 ]

2 голосов
/ 10 мая 2019

Предполагая, что RealMatrix - ваш пользовательский класс, вам все равно придется написать часть кода. Есть такие библиотеки, как Apache Commons Lang, у которого есть метод ArrayUtils.add(array, new element) (на самом деле это куча перегрузок), но ваш код не настолько сложен, чтобы оправдать добавление дополнительной зависимости только для этого.

Несколько замечаний:

double[][] newData = new double[m.getRowDimension()+1][m.getColumnDimension()]; уже создает «внутренние» массивы, то есть строки, поэтому 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.

0 голосов
/ 10 мая 2019

Предполагая, что повторное использование массивов строк не является проблемой (что вы делаете в текущем коде), было бы проще всего заменить цикл for на:

double[][] newData = Arrays.copyOf(data, 0, data.length + 1);
0 голосов
/ 10 мая 2019

Вы идете правильным путем. Единственное, что я могу добавить, это заменить этот цикл:

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