C++ Eigen Library: Mutliplying vector with elements from row vector - c++

I am trying to obtain a matrix consisting of the product between a vector and respective elements from a row vector like this:
Eigen::Vector3f vec;
vec << 1,
2,
3;
Eigen::RowVectorXf val;
val.setLinSpaced(5, 1, 5); //val = [1,2,3,4,5]
//result should be
//1,2,3,4,5
//2,4,6,8,10
//3,6,9,12,15
After seeing this question, I have tried
val.array().colwise()*vec.array()
and
vec.array().rowwise()*val.array()
but they just don't work.
val is a 1xn vector.

You want a standard matrix product:
MatrixXf res = vec * val;

Related

Permute Columns of Matrix in Eigen

I read this answer Randomly permute rows/columns of a matrix with eigen
But they initialize the permutation matrix as the identity matrix and do a random shuffle. I'm wondering how I can initialize the matrix to a specific permutation.
For example, if I have a vector of integers where each (index, value) pair means I want to move column "index" to column "value" how can I do this?
Eigen::MatrixXi M = Eigen::MatrixXi::Random(3,3);
std::vector<int> my_perm = {1,2,0};
some_function to return Matrix [M.col(1), M.col(2), M.col(0)]
EDIT: dtell kindly answered my original question below.
ADDITIONAL INFO:
For anyone else looking at this -- if you want to permute a matrix with a vector of unknown (at compile time) quanties, you can do the following:
Eigen::VectorXi indices(A.cols());
for(long i = 0; i < indices.size(); ++i) {
indices[i] = vector_of_indices[i];
}
Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> perm;
perm.indices() = indices;
Eigen::MatrixXd A_permute = A * perm; \\ permute the columns
If I understand you correctly, the answer to your question is this slight modification of the answer you have linked
Matrix3i A = Matrix3i::Random();
PermutationMatrix<3, 3> perm;
// Your permutation
perm.indices() = { 1, 2, 0 };
// Permutate rows
A = perm * A;

Eigen::Vector; Initialize Vector with Values of Eigen::Matrix3f in a function, bigger than 4 entries

im interested in building up a 1x6 Vector, which i want to concatenate with another 1x6 Vector to a 2x6 Matrix. I know it will be a Row Vector, so therefore i thought about initializing a Eigen::RowVectorXf vec, but maybe a simple Eigen::VectorXf would be enough, idk.
(Further on, this should be concatenated to an even bigger 2Nx6 Matrix, for SVD-Operations)
My Input is a 3x3 Matrix of type Eigen::Matrix3f Mat
I thought of using a function, because i have in total ~20 (number isn't that important) input matrices, for each i do have to build 2 vectors, in this manner ( Yep, this will be a 40x6 Matrix in the end):
Question:
How do i initialize vec with entries of mat, especially if its not only the entries, but the products of entries, or sums of products of entries.
Example:
// Inputvalue Mat, which i have
Eigen::Matrix<float, 3, 3> mat = [ 1 2 3; 4 5 6; 7 8 9];
// Outputvalue vec, which i need
Eigen::RowVectorXf = ( mat(0,0)*mat(1,1), mat(1,2)*mat(2,1)+mat(1,0)*mat(0,1), .... );
My inputs of mat(col,row) are arbitrary, but i have a pattern for col,row, which i want to test, and therefore i want to build up those vectors. I've already done it in MATLAB, but im interested in doing it with Eigen in C++.
RowVectorXf build_Vec(Eigen::Matrix3f Mat)
{
Eigen::RowVectorCf vec = ( ..., ..., ..., ..., ..., ...;);
return vec;
}
Anyone some hints for me?
Thanks in advance
For dynamically filling a big matrix at runtime you can't use the CommaInitializer (without abusing it). Just allocate a matrix large enough and set individual blocks:
Matrix<float, Dynamic, 6> Vges(2*views, 6);
for(int i=0; i<views; ++i) {
Matrix<float, 2, 6> foo;
foo << 1,2,3,4,5,6,7,8,9,10,11,12; // or combine from two Matrix<float, 1, 6>
Vges.middleRows<2>(2*i) = foo;
}
You may also consider computing Vges.transpose() * Vges on-the-fly (i.e., by accumulating foo.transpose()*foo into a 6x6 matrix and do a SelfAdjointEigendecomposition instead of a SVD (perhaps use double instead of single precision then).
Eigen::Matrix<double, 6, 6> VtV; VtV.setZero();
for(int i=0; i<views; ++i) {
foo = ...;
VtV.selfadjointView<Upper>().rankUpdate(foo);
}

SparseMatrix and Vector addition broadcasting in Eigen

I want to add a dense VectorXf to a SparseMatrix, and I know that I could do matrix + vector easily for dense matrix, like this
Eigen::MatrixXf mat(2,4);
Eigen::VectorXf v(2);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
v << 0,
1;
//add v to each column of m
mat.colwise() += v;
but how to do this for sparse matrix?
The simplest way to do this is to iterate over all columns and add a sparse vector to your sparse matrix. And you should keep in mind, that if you need colwise operation, your matrix should be stored as Column-Major.
// allocate dense object
Eigen::MatrixXd M(2,4);
Eigen::VectorXd v(2);
// allocate sparse vector
Eigen::SparseVector<double> spV(2);
// allocate Column-major sparse matrix
Eigen::SparseMatrix<double, Eigen::ColMajor> spM(2, 4);
// initialize dense objects values
M << 1, 0, 0, 2,
4, 5, 0, 0;
v << 1,
3;
// convert dense objects to sparse representation
spM = M2.sparseView();
spV = v2.sparseView();
// iterate over sparse Matrix columns
for(int i = 0; i< spM.cols(); ++i) {
spM.col(i) += spV;
}
It can't be done in such way for dense vector and one of the reason is that this operation does not make any sense, since the resulting matrix will be dense. In this case you will need to create some dense matrix and perform colwise operation with your dense vector like this:
Eigen::MatrixXd(spM).colwise() + v

Matrix and vector multiplication, outputting incorrect product

I've created a Vector and Matrix class and I am trying to perform operations such as the multiplication of a matrix and vector, the multiplication of a matrix and matrix, and the multiplication of a matrix and a float (scalar). I seem to be having problem getting the right product for the matrix * vector and matrix * matrix.
Here is the part of Matrix class meant to handle those operations:
// Matrix * vector, result vector
Vector Matrix::operator*(const Vector & other) const
{
if (other.getDimensions() == 4)
{
float floats[4];
const float* temp = other.getData();
for (int j = 0; j < 4; j++)
{
Vector myCol = column(j);
floats[j] = (temp[0] * myCol.getData(0)) + (temp[1] * myCol.getData(1)) + (temp[2] * myCol.getData(2)) + (temp[3] * myCol.getData(3));
}
return Vector(floats[0], floats[1], floats[2], floats[3]);
}
else
{
return Vector();
}
}
// Matrix * scalar, result matrix
Matrix Matrix::operator*(float c) const
{
Matrix myMatrix;
for (int i = 0; i < 16; i++)
{
myMatrix.data[i] = this->data[i] * c;
}
return myMatrix;
}
In my main.cpp,
Matrix m = Matrix(Vector(1, 0, 0, 1), Vector(0, 1, 0, 2), Vector(0, 0, 1, 3), Vector(0, 0, 0, 1));
Is the value of the matrix and
v = Vector(1, 0, -1, 1);
Is the value of the vector.
When I multiply m * v I get <1, 0, -1, -1>, but the answer is <2, 2, 2, 1>.
And when doing the matrix * scalar with the same m matrix above and vector v with the values
v = Vector(1, 0, -1, 0);
I get m*v to be <1, 0, -1, 2> when it should be <1, 0, -1, 0>.
My Vector class works fine so I'm suspecting I messed up somewhere with the math for implementing the matrix operations.
To expand on #Klaus answer, mathematically in the expression M*V the vector V is a column, and the elements of the result are (dot-)products of matrix rows and V. Replace column(j) with row(j).
I calculated your example by hand now, and if you expect the result to be <2, 2, 2, 1>, then you definitely swapped rows and columns in your matrix. When you multiply a matrix with a vector you want to put the products of the rows of the matrix and the vector in a result vector. Kind of:
Vector Matrix::operator*(const Vector & other) const
{
float floats[4];
const float* temp = other.getData();
for (int j = 0; j < 4; j++)
{
Vector my_row = row(j);
floats[j] = 0;
for(int i=0; i!=4; ++i)
floats[j]+=temp[i] * myCol.getData(i);
}
//(maybe provide a better constructor to take an array)
return Vector(floats[0], floats[1], floats[2], floats[3]);
}
For the example with the scalar, I don't get the point. I don't understand how you expect a multiplication of a matrix with a scalar if you are multiplying a matrix with a vector.
Also you could improve the error handling by only accepting vectors of size 4 (imposing that as a requirement in your vector class), if you just use vectors of size 4.
PS: maybe you should also put your addition code in the loop, into a second loop, so that it is more readable and expandable.

Initialize an Eigen::MatrixXd from a 2d std::vector

This should hopefully be pretty simple but i cannot find a way to do it in the Eigen documentation.
Say i have a 2D vector, ie
std::vector<std::vector<double> > data
Assume it is filled with 10 x 4 data set.
How can I use this data to fill out an Eigen::MatrixXd mat.
The obvious way is to use a for loop like this:
#Pseudo code
Eigen::MatrixXd mat(10, 4);
for i : 1 -> 10
mat(i, 0) = data[i][0];
mat(i, 1) = data[i][1];
...
end
But there should be a better way that is native to Eigen?
Sure thing. You can't do the entire matrix at once, because vector<vector> stores single rows in contiguous memory, but successive rows may not be contiguous. But you don't need to assign all elements of a row:
std::vector<std::vector<double> > data;
MatrixXd mat(10, 4);
for (int i = 0; i < 10; i++)
mat.row(i) = VectorXd::Map(&data[i][0],data[i].size());