2015-11-20 1 views
4

J'ai un Eigen::MatrixXd et j'ai besoin de modifier la valeur des éléments dans sa diagonale. En particulier j'ai un autre Eigen::MatrixXd avec une seule colonne et le même nombre de lignes de la première matrice.Modifier Eigen matrice diagonale

J'ai besoin de soustraire à la diagonale de la première matrice la valeur des éléments de la seconde matrice.

Exemple:

A 
1 2 3 
4 5 6 
7 8 9 

B 
1 
1 
1 


A' 
0 2 3 
4 4 6 
7 8 8 

Comment puis-je faire?

+0

Soustraire une diagonale arbitraire? Ou est-ce toujours des 1 (en d'autres termes, vous êtes toujours en soustrayant la [matrice d'identité] (http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html#a0650b65c6ae6c3d19a138b72a6d68568)) – CoryKramer

+0

@CoryKramer arbitraire diagonale – Nick

Répondre

5

Cela fonctionne pour moi:

A_2=A-B.asDiagonal(); 
0
for(int i = 0; i < matrix1.rows(); ++i) 
    matrix1(i, i) -= matrix2(i, 0); 

Ce code effectue une itération sur chaque rangée de la matrice (matrix1.rows()) et soustrait la valeur correspondante de matrix2 (matrix2(i, 0)) à partir des diagonales dans matrix1 (matrix1(i, i)).

+0

Alors que ce code peut répondre à la question, fournissant un contexte supplémentaire concernant pourquoi et/ou comment ce code répond à la question améliore sa valeur à long terme. – Bono

0

manipulation de la matrice dans Eigen fonctionne très similaire à celle des tableaux. L'indexation commence à partir de zéro et c'est la ligne principale. La documentation (Eigen: The Matrix Class est bien écrit et peut vous aider à résoudre les problèmes futurs.

Pour votre problème posé la solution est donnée ci-dessous.

#include <iostream> 
#include <eigen3/Eigen/Dense> 
using Eigen::MatrixXd; 
int main() 
{ 
    MatrixXd matA(3,3), matB(3,1); 
    matA<<1,2,3, 
    4,5,6, 
    7,8,9; 
    matB<<1,1,1; 
    for(int i=0; i<3;i++) 
    matA(i,i) -= matB(i); 
    std::cout<<matA<<std::endl; 
    return 0; 
} 

Cependant, je voudrais utiliser matrix3D et Vector3D pour la première et la deuxième . matrice, respectivement

+0

Il est probablement préférable d'utiliser 'matB.rows()' au lieu du nombre codé en dur '3', comme cela a été fait dans la réponse par @ otah007 – Saurav

3

le plus simple et plus rapide pour ne parvenir est:

Eigen::MatrixXd A1(3,3), B(3,1), A2; 
... 
A2 = A1; 
A2.diagonal() -= B; 

bien sûr, mieux utiliser le VectorXd type pour les vecteurs (ici pour B), et enfin si B est constante, vous pouvez utiliser les installations de tableau:

A2.diagonal().array() -= 1; 
+2

Comment cela est-il plus simple et plus rapide que' A - B.asDiagonal() '? –

+0

Peut-être parce qu'il évite de créer B comme une matrice diagonale et n'a qu'à faire des calculs A2.rows() plutôt que A2.size? Bien que je suppose qu'Eigen soit assez intelligent quand il sait que B.asDiagonal() est diagonal. –