2017-01-16 15 views
0

У меня есть (плотные и большие) векторы строк v_1, ..., v_D, и мне нужна матрица X, которая будет блочной диагональю (чей i-й блок равен v_i) для выполнения матричных продуктов, таких какC++ Собственная блочная диагональная матрица из плотных векторов без копии

X.transpose() * H.selfadjointView<Lower>() * X 

то есть, X должны быть редкими и ее я-я строка v_i:

(pseudo code) 
RowVectorXd v1(1,2,3), v2(4,5), v3(6,7,8,9); 
SparseMatrix<double> X(3,9); 

// I need X to be 
X = 1 2 3 . . . . . . 
    . . . 4 5 . . . . 
    . . . . . 6 7 8 9 

// where . means 0 

EDIT: Мой вопрос: возможно ли это сделать этот продукт, фактически не образуя X и не копируя v_i, а просто используя ссылки на них? Меня беспокоит производительность и объем памяти.

Я думаю, что решение имеет какое-то отношение к Eigen :: Map < ... Stride ...> но я не могу это получить.

Большое спасибо.

+0

Ваш вопрос будет проще для людей ответить, если вы включили «минимальный пример» в тип матрицы, которую вы хотите сформировать, и код, который вы пытались использовать, используя копию. Удачи! – kcrisman

+0

Спасибо за ваш комментарий. Я добавил соответствующий псевдо-код. – itQ

+0

Вы не можете скопировать векторы в 'SparseMatrix', не копируя их (очевидно ...). Если ваша 'SparseMatrix' имеет чистую плотную структуру блока (т. Е. Структурных нулей внутри блоков), вы можете получить доступ к этим блокам с помощью' Eigen :: Map', не копируя их. Независимо от того, действительно ли вам нужно построить свою матрицу 'X', зависит от того, что вы собираетесь с ней делать. – chtz

ответ

0

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

B = X^T * H * X 

, где Х представляет собой, как и в вопросе и Н является симметричным, без явного формирования X. Как Х^ТНХ является симметричным, нам нужно только, чтобы сформировать ниже диагонали и использовать

B.selfadjointView<Lower>() 

называть B.

Заметим, что Х^ТНХ эквивалентно Н ** Вт, где W является следующая нижняя треугольная матрица с блоками будучи

W = v_1^T * v_1 
    v_2^T * v_1 v_2^T * v_2 
    .    .    v_3^T * v_3 
    .    .    .    ... 
    .    .    .    ... 
    v_D^T * v_1 v_D^T * v_2 v_D^T * v_3  ... v_D^T * v_D 

и ** является перегруженный оператор, который вычисляет покомпонентное произведение между (I, J) скаляр H и блок (I, J) в W. Так

B = H ** (v^T * v)