how to concatenate Vectors in Eigen? - c++

I have two vectorXd in my program and I like to concatenate them into one vector, so that the second one's values goes after the first one, I found this for matrix but it doesn't seem to work on Vectors:
Eigen how to concatenate matrix along a specific dimension?

Like so, assuming you have vec1 and vec2 already:
VectorXd vec_joined(vec1.size() + vec2.size());
vec_joined << vec1, vec2;
(Note that the vector types are simply typedefs of matrix types constrained to have only one column.)
Further reading: Advanced initialization

Related

How to convert std::vector<std::pair<double, double>> dataVector to Eigen::MatrixXd rtData(dataVector.size(), 2)

Is there a fast way to make conversion below?
use "std::vector<std::pair<double, double>> dataVector" to initialize "Eigen::MatrixXd rtData(dataVector.size(), 2)"
Assuming sizeof(std::pair<int,int>) == 2*sizeof(int) (i.e., std::pair is not adding any padding) you can use an Eigen::Map of a row-major integer matrix, then cast it to double. Something like this:
typedef Eigen::Matrix<int, Eigen::Dynamic, 2, Eigen::RowMajor> MatrixX2i_r;
Eigen::MatrixXd rtData
= Eigen::Map<MatrixX2i_r const>(&(dataVector[0].first), dataVector.size(), 2).cast<double>();
You can also use that expression directly without storing it into a MatrixXd (conversion will happen on the fly, every time the expression is used -- so if you use rtData multiple times, it could still be better to store it once).
I am assuming you wish to create a two column matrix from bunch of pairs stacked in a vector.
As far I can see in the documentation MatrixXd is typedef of Matrix<double,dynamic,dynamic> so first potential issue is that you wish to fill matrix of double by int values.
Since MatrixXd is merely a typedef I don't think there is a suitable constructor in Eigen library for you to do quick conversion.
Simply write a code or a function that iterates through your vector and populates the matrix. In C++14:
int itt=0;
for (const auto& [first, second] : dataVector)
{
rtData(itt,0) = first;
rtData(itt,1) = second;
itt++;
}
That is a neat for loop that can go through vector of pairs, you still need the index of the elements, as Eigen matrices do not have push_back methods as STL.
Note again that I would advise MatrixXi if you are populating it with integers and not doubles.

Multiply two Eigen vectors by corresponding elements

I have two Eigen vectors (vectorOne and vectorTwo) of my defined type( see below for my type).
typedef Matrix<double, 50, 1> myVector;
I want a third vector vectorThree that will have multiplication of vectorOne and vectorTwo. But I want to multiply each element by corresponding element - i.e. vectorOne(i, 0) by vectorTwo (i, 0) so that I have something like below for all i.
vectorThree (i, 0) = vectorOne(i, 0) * vectorTwo(i, 0)
I saw this and tried vectorOne.array() * vectorTwo.array() but it did not work.
I know I can do that using a for loop and iterating over all elements. But is there a more efficient or built in Eigen function for that?
You should be able to cast matrices to arrays via .array() and multiply it here. It would return an array expression though, so maybe it is not what you want.
From Eigen documentation:
First of all, of course you can multiply an array by a scalar, this works in the same way as matrices. Where arrays are fundamentally different from matrices, is when you multiply two together. Matrices interpret multiplication as matrix product and arrays interpret multiplication as coefficient-wise product. Thus, two arrays can be multiplied if and only if they have the same dimensions.
Otherwise you can use .cwiseProduct of matrix to get matrix as result.
https://eigen.tuxfamily.org/dox/group__QuickRefPage.html#matrixonly

How to get dimensions of a multidimensional vector in C++

all
I am using multidimensional STL vector to store my data in C++. What I have is a 3D vector
vector<vector<vector<double>>> vec;
What I want to retrieve from it is :
&vec[][1][]; // I need a pointer that points to a 2D matrix located at column 1 in vec
Anyone has any idea to do so? I would be extremly appreciate any help!
Regards
Long
It is best to consider vec just as a vector whose elements happen to be
vectors-of-vectors-of-double, rather than as a multi-dimensional structure.
You probably know, but just in case you don't I'll mention it,
that this datatype does not necessarily represent a rectangular cuboid.
vec will only have that "shape" if you ensure that all the vectors are
the same size at each level. The datatype is quite happy for the vector vec[j]
to be a different size from the one at vec[k] and likewise for vec[j][n]
to be a vector of different size from vec[j][m], so that your structure is "jagged".
So you want to get a pointer to the vector<vector<double>> that is at
index 1 in vec. You can do that by:
vector<vector<double>> * pmatrix = &vec[1];
However this pointer will be an unnecessarily awkward means of accessing that
vector<vector<double>>. You certainly won't be able to write the
like of:
double d = pmatrix[j][k];
and expect to get a double at coordinates (j,k) in the "matrix addressed
by a pmatrix". Because pmatrix is a pointer-to-a-vector-of-vector-of-double;
so what pmatrix[j] refers to is the vector-of-vector-of-double (not vector-of-double)
at index j from pmatrix, where the index goes in steps of
sizeof(vector<vector<double>>). The statement will reference who-knows-what
memory and very likely crash your program.
Instead, you must write the like of:
double d = (*pmatrix)[j][k];
where (*pmatrix) gives you the vector-of-vector-of-double addressed by pmatrix,
or equivalently but more confusingly:
double d = pmatrix[0][j][k];
Much simpler - and therefore, the natural C++ way - is to take a reference,
rather than pointer, to the vector<vector<double>> at index 1 in vec. You
do that simply by:
vector<vector<double>> & matrix = vec[1];
Now matrix is simply another name for the vector<vector<double>> at index 1 in vec,
and you can handle it matrix-wise just as you'd expect (always assuming
you have made sure it is a matrix, and not a jagged array).
Another thing to consider was raised in a comment by manu343726. Do you
want the code that receives this reference to vec[1] to be able to
use it to modify the contents of vec[1] - which would include changing its
size or the size of any of the vector<double>s within it?
If you allow modification, that's fine. If you don't then you want to get
a const reference. You can do that by:
vector<vector<double> > const & matrix = vec[1];
Possibly, you want the receiving code to be able to modify the doubles
but not the sizes of the vectors that contain them? In that case, std::vector
is the wrong container type for your application. If that's your position I
can update this answer to offer alternative containers.
Consider using matrix from some linear algebra library. There are some directions here

Scalar multiply of 2 vectors Eigen

I've got some serious problem with basic scalar multiplication of 2 vectors in Eigen lib.
When I have two vectors....both are the rows of matrix..so... I must second .transpose();, I must to get one number..so how its possible that I can access to result of this vectors in 1 iterator 2,3,4,5...??????!!!!!
q_c=matVk.row(ks);
lk=(matVk.row(i).transpose());
vectors multiply :
hore= q_c * lk;
the result is totally different than have to be.....and the values in vectors are ok,,i checked it,,I try everything to solve this....I try more specific init.: of vectors: same result
VectorXd hore(1);
VectorXd lk(k);
VectorXd q_c(k);
The following are the typedefs defined in the documentation:
typedef Matrix< double , 1, Dynamic > RowVectorXd
typedef Matrix< double , Dynamic , 1> VectorXd
If you multiply a column vector to a column vector, you will get the result what you are getting as question details are not much clear. But I guess this is the mistake you are making. Try this instead:
VectorXd hore(1);
VectorXd lk(k);
RowVectorXd q_c(k);
hore = q_c*lk

Extract element from 2 vectors?

I have 2 vector of with one has vec1{e1,e2,e3,e4} and the other one with vec2 {e2,e4,e5,e7}
How to effectively get three vector from above vectors such that 1.has elements that is available only in vec1 similarly 2 has only vec2 elements and 3.with common elements
std::set_intersection should do the trick, if both vectors are sorted:
http://msdn.microsoft.com/en-us/library/zfd331yx.aspx
std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), std::back_inserter(vec3));
A custom predicate can be used for the comparison too:
std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), std::back_inserter(vec3), my_equal_functor());
If they are not sorted, you may of course sort them first, or alternatively, you can iterate through vec1, and for each element, use std::find to see if it exists in vec2.
What you're asking for is that vec3 be the intersection of the other two. Jalf demonstrates how to populate vec3 using the std::set_intersection function from the <algorithm> header. But remember that for the set functions to work, the vectors must be sorted.
Then you want vec1 and vec2 to be the difference between themselves and vec3. In set notation:
vec1 := vec1 \ vec3;
vec2 := vec2 \ vec3;
You can use the std::set_difference function for that, but you can't use it to modify the vectors in-place. You'd have to compute another vector to hold the difference:
std::vector<foo> temp;
std::set_difference(vec1.begin(), vec1.end(),
vec3.begin(), vec3.end(),
std::back_inserter(temp));
vec1 = temp;
temp.clear();
std::set_difference(vec2.begin(), vec2.end(),
vec3.begin(), vec3.end(),
std::back_inserter(temp));
vec2 = temp;
If the element count is low, you can use the naive approach which is easy to implement and has O(n2) running time.
If you have a large number of elements, you can build a hash table from one of them and look up other vector's elements in it. Alternatively, you could sort one of them and binary search through it.
The problem you describe is vector intersection. This depends on the size of the input vectors.
If the sizes of both vectors are close to each other a merge (like in merge-sort) is best. If one vector is much smaller than the other do the following: For each element of the smaller vector search for that element in the larger vector using binary search.
This is a common problem in information retrieval, where you have to intersect inverted indices. There are some research papers on this.