Constructing a diagonal matrix from vector of integers: function eigen
Asked Answered
N

3

7

I have a vector of integers and I want to construct a diagonal matrix with vectos's element as diagonal entries of the matrix. For example: if vector is 1 2 3 the diagonal matrix would be:

1 0 0
0 2 0
0 0 3

The naive way to do it would be just iterate over it and set elements one by one. Is there no other direct way to do this in eigen. Also after constructing the diagonal I want to calculate the inverse(which is just reversing the diagonal entries) but there does not seem to be a way to do this too(directly, which would be optimized way too) in the library itself.

I have looked up the documentation of diagonal matrices in eigen library but it seems like that there is no way .If I have missed something obvious while reading the documentation please point out.

Any help appreciated.

Nealy answered 28/6, 2013 at 9:48 Comment(4)
If you find a way to quickly generate the matrix from the vector, inverting it is rather simple: Invert the vector's elements and create the matrix from scratch.Bahr
@Bahr I did not want to get into floating point errors, if they may arise(I am not sure). So want eigen to handle everything. I guessed that would be easy.Nealy
The page you linked gives a 3D DiagonaMatrix constructor taking the 3 relevant coefficients as arguments. There's also a method to extract the diagonal vector out of such a matrix, which you could use to compute "by hand" the inverted vector and construct a new matrix with.Bignoniaceous
@AmanDeepGautam: It probably is, I just don't know anything about eigen.Bahr
R
13

According to this part of the documentation you have quite a few options, the easiest one being

auto mat = vec.asDiagonal();
Rustproof answered 28/6, 2013 at 10:22 Comment(5)
Correct documentation can be tricky to find sometimes. I did google search but this didn't show up. It may sound weird but any tricks/tips?Nealy
I used the query diagonal matrix from vector eigen, so no real tricks here :)Rustproof
Documentation link is dead.Marigolde
Seems to be because of a newer version of doxygen, I corrected the link.Rustproof
for completeless: It is also possible to get a dense matrix out of the diagonal matrix: auto mat = vec.asDiagonal().toDenseMatrix();Pneumato
H
3

You should use proper types with Eigen, unless you really know what you're doing

//Create a 4x4 diagonal matrix from the vector [ 5 6 7 8 ]
Eigen::Vector4d vec;
vec << 5, 6, 7, 8;
Eigen::DiagonalMatrix<double, 4> mat = vec.asDiagonal();

Using auto is a really slippery slope where you typically have no idea what the compiler uses as the type, and coupled with Eigen, this is one of the common sources of tricky-to-find errors (see https://eigen.tuxfamily.org/dox/TopicPitfalls.html)

Hashish answered 3/1, 2017 at 14:42 Comment(0)
B
1

You can also do it the other way around, which allows you to set super/subdiagonals as well.

MatrixXd A = ...;
A.diagonal(0) = values_vector; //for 'main' diagonal
A.diagonal(1) = other_values; //for 1st super-diagonal

See Eigen Matrix Diagonal() reference (also has an example)

Brandonbrandt answered 24/8, 2019 at 20:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.