Расширенный конструктор для несмежных матриц - PullRequest
4 голосов
/ 31 мая 2019

В моих реализациях я много работаю с подматрицами и блоками матриц. Мне интересно, есть ли способ в броненосце, который позволил бы мне извлечь блок большей матрицы и использовать ту же память для этой подматрицы, что и для блока в исходной матрице. Моя проблема в том, что я не знаю, как это сделать, поскольку позиции в исходной матрице не являются смежными.

Вот один простой пример, который иллюстрирует, что я хочу делать, когда моя исходная матрица имеет вид A = [A1 A2]:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat foo(arma::mat A, arma::uword block_start, arma::uword block_length) {
  arma::uword rows = A.n_rows;
  arma::mat B = arma::mat(A.begin_col(block_start), rows, block_length, false);
// fill B here for illustration; 
// in the real piece of code I do various manipulations, multiplications, etc using B
  B.fill(1.0);
  return A;
}

/*** R
A <- matrix(0, 4, 4)
foo(A, 0, 2)
> A <- matrix(0, 4, 4)
> foo(A, 0, 2)
     [,1] [,2] [,3] [,4]
[1,]    1    1    0    0
[2,]    1    1    0    0
[3,]    1    1    0    0
[4,]    1    1    0    0
*/

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

Предположим теперь, что я хочу, чтобы подматрица была A[1:2, 1:2]. Могу ли я получить копию B в броненосце, которая использует ту же память, что и исходные элементы в A? (В идеале решение этого вопроса также должно обобщаться на случай, когда столбцы также не являются смежными, например A[c(1, 3), c(1, 3)].)

Изменить: Чтобы уточнить, мне действительно нужно, чтобы матрица B в функции выше существовала сама по себе. Я не fill это в моем реальном коде, но использую его (и несколько других подматриц) в различных матричных умножениях и т. Д. Итак, что я хочу, это способ создать B как несмежную подматрицу из A, убедившись, что они используют одну и ту же память.

1 Ответ

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

Вы можете использовать представления подматрицы для записи в непрерывную или несмежную память:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat foo(arma::mat A) {
    A.submat(0, 0, 1, 1).fill(1.0);
    return A;
}

// [[Rcpp::export]]
arma::mat bar(arma::mat A) {
    arma::uvec rows;
    rows << 0 << 2;
    arma::uvec cols;
    cols << 0 << 2;
    A.submat(rows, cols).fill(2.0);
    return A;
}

/*** R
A <- matrix(0, 4, 4)
foo(A)
bar(A)
*/

Вывод:

> A <- matrix(0, 4, 4)

> foo(A)
     [,1] [,2] [,3] [,4]
[1,]    1    1    0    0
[2,]    1    1    0    0
[3,]    0    0    0    0
[4,]    0    0    0    0

> bar(A)
     [,1] [,2] [,3] [,4]
[1,]    2    0    2    0
[2,]    0    0    0    0
[3,]    2    0    2    0
[4,]    0    0    0    0
...