As the title says, I am trying to convert an Eigen::VectorXd to an std::vector. The vector is obtained by diagonalizing a matrix and then taking the first eigenvector of the process.
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
using namespace std;
int main()
{
vector<double> vec;
MatrixXd ones = MatrixXd::Ones(3,3);
VectorXd firstEvector;
SelfAdjointEigenSolver<MatrixXd> es(ones);
firstEvector = es.eigenvectors().col(1);
cout << "The first eigenvector of the 3x3 matrix of ones is:" << endl << firstEvector << endl;
vec(&firstEvector[0], firstEvector.data() + firstEvector.cols()*firstEvector.rows());
return 0;
}
I thought this was the way to do it, however, it doesn't work. I get the following error.
C:\CBProjects\eigenVectors\main.cpp|20|error: no match for call to '(std::vector<double>) (Eigen::DenseCoeffsBase<Eigen::Matrix<double, -1, 1>, 1>::Scalar*, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1> >::Scalar*)'|
I can't see what I am doing wrong. Any help would be greatly appreciated.
You are using a constructor syntax for the std::vector vec although the vector was already declared. That doesn't work.
There are two efficient possibilities to copy the content of an Eigen::VectorXd into a std::vector<double>. You can either construct a new std::vector vec2, like this:
vector<double> vec2(firstEvector.data(), firstEvector.data() + firstEvector.size());
or use the previously declared vector vec and transfer the data from the Eigen::VectorXd by using Eigen::Map. But in that case the std::vector first needs to be resized:
vec.resize(firstEvector.size());
Map<VectorXd>(vec.data(), vec.size()) = firstEvector;
Related
Is this the only solution when there is a pointer that points to a vector and we would like to use accumulate to sum up numbers?
Is there any simpler solution rather than writing a lambda function and using a four argument type of accumulating?
Also, for using std::sort, will the situation be the same?
Here is the code:
#include <random>
#include <vector>
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main() {
const int N=3;
auto p=make_unique<array<int,N>> ();
(*p)[0]=3;
(*p)[1]=4;
(*p)[2]=5;
sum=accumulate(p,?,0);
return 0;
}
To answer your immediate question:
std::accumulate(p->begin(), p->end(), 0);
The same syntax will work for other STL algorithms as well.
Other improvements to your code snippet:
Avoid using #include<bits/stdc++.h>, see this post. Similarly for using namespace std, it's considered bad practise.
const N=3 -> const auto N=3
std::array is not a vector and you can initialise it directly using initializer-list syntax:
const auto* obj = new std::array<int,3>{3,4,5};
the following codes pushed back an std::array to a std::vector N times. Is there a more elegant and shorter way of doing this?
#include <iostream>
#include <vector>
#include <array>
#include <iomanip>
#include <complex>
#include <cmath>
int main () {
int N=10;
std::vector< std::array<std::complex<double>,3> > v;
v.reserve(N);
for(int i=0;i<N;i++){
std::array<std::complex<double>,3> el { {0.0,3.0,0.0} };
v.push_back(el);
}
}
Yes but you have to use parentheses when constructing vector
std::vector< std::array<std::complex<double>,3> > v(n, {0.0,3.0,0.0});
If braces are used than initialization list is preferred and in this case you could have unexpected errors.
You can use the std::vector::insert (#3 in the overload set) member function:
int N=10;
std::vector< std::array<std::complex<double>,3> > v;
v.reserve(N);
v.insert(v.end(), N, { {0.0,3.0,0.0} });
Note that #MarekR's answer is preferable for initializing the vector, as it circumvents the call to reserve, and setting up an object during initialization is usually better than subsequent member function calls. The above call to std::vector::insert instead is suitable for adding additional elements later on.
How do pointers work for an array and a vector object
For array_1
#include <iostream>
#include <array>
using namespace std;
int main(){
int a[3][4]={0,1,3,3,4,5,6,7,8,9,10,11};
//int (*pi)[4]=a;
for( auto *pi=a; pi!=a+3; ++pi ){
for( auto p=*pi; p!=*pi + 4; ++p){
cout << *p << "\n";
}
}
}
For array_2
#include <iostream>
#include <array>
using namespace std;
int main(){
int a[3][4]={0,1,3,3,4,5,6,7,8,9,10,11};
//int (*pi)[4]=a;
for( auto pi=a; pi!=a+3; ++pi ){
for( auto p=*pi; p!=*pi + 4; ++p){
cout << *p << "\n";
}
}
}
For vector_1
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> a{0,1,3,3,4,5,6,7,8,9,10,11};
for(auto i=a.begin(); i!=a.end(); ++i ){
// we can also use begin(a) and end(a)
cout << *i << "\n";
}
}
For vector_2
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> a{0,1,3,3,4,5,6,7,8,9,10,11};
for(auto *i=a.begin(); i!=a.end(); ++i ){
// we can also use begin(a) and end(a)
cout << *i << "\n";
}
}
Both codes (for array_1 and for array_2) give the same output i.e (0-11)
you can see that there is a difference in the first for loop of both pieces of code.
In the For vector_1 ,as far as I understood, I think, I am creating a pointer i to the beginning of the vector and then dereferencing it to fetch the value of that corresponding position. Now my doubt is, how come in the For array_1 and For array_2 when I use the *pi in the 2nd for loop, instead of getting dereferenced(like in the case of vector), it is fetching me the iterative values?
And why does the For vector_2 not work the same way as For vector_1?
And what is the return type of the size() and begin()/end() function for vector?
Cause when I use for(decltype(a.size()) i=0; i!=end(); ++i), it is giving me a type conversion error.
The code for array_1, for array_2 and for vector_1 gives the same output(0-10). It is the for vector_2 that is giving an error.
Thanks.
In case of vector_1 you are not creating a pointer, but an iterator - in most basic use cases, like printing vector results, iterator works and is used like a pointer, but it is not the same and shouldn't be handled the same way you handle a pointer. In case of vector_2 you do something nasty since this is the job of the auto keyword to determine whether the variable is to be a pointer or not.
The last example causes an error, because you are trying to create a pointer to iterator, and the type returned by the begin() function is an iterator (a value), not the address of the iterator object.
If you want to know the return types of functions like size(), begin(), etc. you can always refer to one of the several large C++ reference websites, for example:
www.cplusplus.com
www.cppreference.com
I want to know how I can assign multiple values to a vector at once:
#include <iostream>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
using namespace boost::numeric::ublas;
int main()
{
vector<double> v1(3);
v1(0)=0;
v1(1)=0.1;
v1(2)=0.05;
v1(3)=0.25;
return 0;
}
I want to assign all the values at once.
something like:
v1 << 0,0.1,0.05,0.25;
I tried operator += and there is an error, but I think operator += works for std::vector not boost::....vector
Take a look at documentation examples http://svn.boost.org/svn/boost/trunk/libs/numeric/ublas/doc/samples/assignment_examples.cpp
Basically, you need v1 <<= 0, 1, 2;, see more examples in the docs. Unfortunately this library doesn't support initializer_list's yet: http://boost.2283326.n4.nabble.com/Initializing-from-an-initializer-list-td4647029.html
I'm a very noob at Boost::uBLAS.
I have a function which take a ublas::matrix_expression<double> as input:
namespace ublas = boost::numeric::ublas;
void Func(const ublas::matrix_expression<double>& in,
ublas::matrix_expression<double>& out);
A caller is holding a row vector as ublas::vector<double>, and I want it to be passed to Func.
Until now I have not found any way to do this.
What is the best way, preferably without any temporary allocation?
Thanks.
Well, there is an option to create a read-only adapter of a contiguous area of memory into a read-only matrix. Have a look at example 3. It is pretty straightforward to use:
#include "storage_adaptors.hpp"
#include <boost/numeric/ublas/assignment.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
ublas::vector<double> v(6);
v <<= 1, 2, 3, 4, 5, 6;
ublas::matrix<double> m = ublas::make_matrix_from_pointer(2, 3, &v(0));
std::cout << m << std::endl;
Possibly you could tweak that further to fit your needs/example.
You can avoid allocating if you're ready to sacrifice some multiplication, use
outer_prod(scalar_vector<double>(1, 1), vec)
to transform vector into matrix expression. Also, your function probably should be
template<class C>
void Func(const matrix_expression<C>& in...
matrix_expression itself doesn't model matrix expression concept, it's just the base class.