Passing values of vectors to Eigen library format [duplicate] - c++

This question already has an answer here:
Eigen and std::vector
(1 answer)
Closed 5 years ago.
I am trying to solve a linear equation Ax=b using Eigen's abilities for the A as a square 2D vector. I have the A and b as C++ based 2D vector and 1D vector respectively. However, I could not find a way to pass the values of them to the Eigen format matrix and vectors. Would you please let me how to copy the variable in Eigen format?
Moreover, what should include in the beginning to be able to use the Map class as a possible solvent?!
Here is the code:
#include <iostream>
#include <vector>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
// Let's consider that the A and b are following CPP based vectors:
vector<vector<double>> mainA= { { 10.,11.,12. },{ 13.,14.,15. },{ 16.,17.,18. } };
vector<double> mainB = { 2.,5.,8. };
// ??? Here I need to do something to pass the values to the following Eigen
//format matrix and vector
MatrixXf A;
VectorXf b;
cout << "Here is the matrix A:\n" << A << endl;
cout << "Here is the vector b:\n" << b << endl;
Vector3f x = A.colPivHouseholderQr().solve(b);
cout << "The solution is:\n" << x << endl;
}

As mentioned in the comments, Eigen::Map<> should do the trick.
Usually you'll get away without using the Unaligned, but for correctness/stability, it's best to use it:
auto A = Eigen::Map<Eigen::MatrixXd, Eigen::Unaligned>(mainA.data(), mainA.size(), mainA[0].size())
auto b = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(mainB.data(), mainB.size());
Vector3d x = A.colPivHouseholderQr().solve(b);
To answer the question below about robustness: This can be done using helper functions:
template <typename T, int Align>
Eigen::Map<Eigen::Matrix<T, -1, -1>, Align> CreateMatrix(const std::vector<std::vector<T>>& x)
{
int R = x.size();
assert(!x.empty());
int C = x[0].size();
#ifndef NDEBUG
for(int r=1; r < R; r++)
assert(x[r].size() == x[0].size());
#endif
return auto A = Eigen::Map<Eigen::Matrix<T,-1,-1>, Align>(x.data(), R, C);
}
Although it looks verbose, it does a lot of sanity checks where you then can rely upon in all code for which you have a unit test.

Related

How to get the rows based on condition in eigen?

I need to get the certain rows, when a element is a vector is one.
For an example:
std::vector<bool>index{}; //contains 6000 numbers of elements 0 and 1
Now I have a matrix mat of shape (6000,4)
How can I get the rows in a matrix mat, when the corresponding element is 1 in vector index.
mat = mat[index];
If I understand your question clearly, you may find good answer from this good reply:
Eigen3 select rows out based on column conditions
Using new feature (Eigen 3.4 or 3.3.90 development branch) and take the core code from the previous link:
#include <Eigen/Dense>
#include <iostream>
#include <vector>
using namespace Eigen;
int main() {
MatrixXd mat = MatrixXd::Random(10,5);
std::cout << "original:\n" << mat << std::endl;
std::vector<int> keep_rows;
for (int i = 0; i < mat.rows(); ++i) {
if (mat(i,mat.cols() - 1) > 0.3) {
keep_rows.push_back(i);
}
}
VectorXi keep_cols = VectorXi::LinSpaced(mat.cols(), 0,mat.cols());
MatrixXd mat_sel = mat(keep_rows, keep_cols);
std::cout << "selected:\n" << mat_sel << std::endl;
}
It uses the similar style of the Matlab:
MatrixXd mat_sel = mat(keep_rows, keep_cols);
But the columns and rows that should be kept are stored in an
Eigen::VectorXi
or in a
std::vector<int>

Usage of vector push_back with pair

I was looking at the implementation of Prim's Algorithim on geeksforgeeks.org and tried to implement the function on practice mode. I looked at how the input was received and I saw this:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1e4 + 5;
int spanningTree(vector <pair<int,int> > g[], int n);
int main()
{
int t ;
cin>>t;
while(t--)
{
vector <pair<int,int> > adj[MAX];
int n,e;
int w, mC;
cin >> n>> e;
for(int i = 0;i < e;++i)
{
int x,y;
cin >> x >> y >> w;
adj[x].push_back({w, y});
adj[y].push_back({w, x});
}
mC= spanningTree(adj, MAX);
cout << mC << endl;
}
return 0;
}
I'm having a lot of trouble understanding how they're using vector. I've never seen the passing of a vector in a similar way to an array: vector <pair<int,int> > g[].
I looked at the STD implementation of vector and couldn't find anything about passing a vector this way, or constructing a vector with vector <pair<int,int> > adj[MAX];.
Lastly, I am very confused about what the following code does:
adj[x].push_back({w, y});
adj[y].push_back({w, x});
I tried implementing it myself:
#include <iostream>
#include <vector>
#include <utility>
#include <string>
using namespace std;
int main()
{
vector< pair<string, int> > vec[2];
vec[0].push_back({"One", 1});
vec[1].push_back({"Two", 2});
for(int x = 0; x < 2; ++x){
cout << vec[x].first << ", " << vec[x].second << endl;
}
return 0;
}
But I get an error class 'std::vector< pair<string, int> >' has no member named ‘first’.
If I could have some help understanding how vector is being used here, I would really appreciate it. I looked at multiple StackOverflow posts already, including vector::push_back vs vector::operator[].
The link to the original problem is here
I've never seen the passing of a vector in a similar way to an array: vector <pair<int,int> > g[]
It is an array! An array of vectors.
The problem with your code is that you have two vectors, both with a single element, and your loop only pulls out the vectors... not their single element.
Your version would be:
#include <iostream>
#include <vector>
#include <utility>
#include <string>
using namespace std;
int main()
{
vector< pair<string, int> > vec[2];
vec[0].push_back({"One", 1});
vec[1].push_back({"Two", 2});
for(int x = 0; x < 2; ++x){
cout << vec[x][0].first << ", " << vec[x][0].second << endl;
}
return 0;
}
All I added was [0] (index into each vector).
Of course such an example is of questionable practicality. In such a situation it would seem that you want one vector with two elements, and no arrays in sight.
To be honest, I'm not wild about the original code, either. Mixing arrays and vectors is a recipe for confusion (hyello); they could have used "2D vectors" or, better, a 1D vector with 2D indexes laid on top of it. That would then have much better cache locality as well.
Its' a C-style array of vectors, really nothing magic here.
int spanningTree(vector <pair<int,int> > g[], int n);
Maybe you have seen something like that before:
int foo( int array[], int n);
In their code, the elements of the array are not ints but std::vectors. Why they mix plain arrays and std::vector I cannot tell you.
In your example, you need to first use operator[] to access an element before you can access its .first and .second, or use front to get the first element:
for(int x = 0; x < 2; ++x){
cout << vec[x].front().first << ", " << vec[x].front().second << endl;
}

Inverse of a matrix using eigen

I have learnt how to find inverse of a matrix using Eigen. But when I'm finding inverse of an array that is a output of function I got an error
request for member ‘inverse’ in ‘x’, which is of non-class type
‘double**’
Please help me out, in using c++ library to find inverse of a matrix.
The code I have written is:
#include <iostream>
#include <armadillo>
#include <cmath>
#include <Eigen/Dense>
using namespace std;
using namespace arma;
using namespace Eigen;
int main()
{
vec a;
double ** x;
double ** inv_x;
a <<0 << 1 << 2 << 3 << 4; //input vector to function
double ** f (vec a); //function declaration
x= f(a); // function call
//inv_x=inv(x);
cout << "The inverse of x is:\n" << x.inverse() << endl; // eigen command to find inverse
return 0;
}
// function definition
double ** f(vec a)
{
double ** b = 0;
int h=5;
for(int i1=0;i1<h;i1++)
{
b[i1] = new double[h];
{
b[i1][0]=1;
b[i1][1]=a[i1];
b[i1][2]=a[i1]*a[i1]+1/12;
b[i1][3]=pow(a[i1],3)+a[i1]/4;
b[i1][4]=1/80+pow(a[i1],2)/2+pow(a[i1],4);
}
}
return b;
}
Here user defined function f return an array x. I'm trying to find inverse of x using eigen library.
First, as mentioned by Martin Bonner, don't use double** to store a matrix, but make sure the coefficients are sequentially stored.
Then, you can use the Eigen::Map class to see a raw buffer as an Eigen's object, as documented there. For instance:
double data[2][2];
Eigen::Map<Matrix<double,2,2,RowMajor> > mat(data[0]);
mat = mat.inverse();

Need help to write a function to find max and min value in a N-dimensional array C++

I need to find max and min value of a array in different dimensions(will be 1-d, 2-d and up to N dimension array) in my program.
Can anyone help me to write a function or function template that can take input of an arbitrary dimension array and find the max/min value?
* I'm using vector of vectors
Something like this:
#include <vector>
<template T>
int find_max(T target_array, int dimension);
int main() {
using namespace std;
vector<int> array_1d = {1,3,4};
vector<vector<int> array_2d = {{1,3},{3,5,2},{6,4}};
vector<vector<vector<int>>> array_3d = {{{1,3},{2,4,5}},{{6,7,2,3}}};
cout << "Max in 1d array: " << find_max<vector<int>>(array_1d, 1) << endl;
cout << "Max in 2d array: " << find_max<vector<vector<int>>(array_2d, 2) << endl;
cout << "Max in 3d array: " << find_max<vector<vector<vector<int>>>>(array_3d, 3) << endl;
return 0;
}
OUTPUT:
Max in 1d array: 4
Max in 2d array: 6
Max in 3d array: 7
Program ended with exit code: 0
Thank you
The function you wrote the signature of can be implemented with a simple call to std::max_element.
Then you can overload this function with a template accepting any nested vector, which first recursively applies the function to each element of the vector before computing the maximum value of them.
The following code implements this idea. The second parameter int dimension is not required, since the number of dimensions is given by the type of the first parameter.
If you want both min and max elements simultaneously, you could use something like std::minmax_element for the base case, but the recursive call gets way more complicated then.
Live demo: http://ideone.com/kW0ewz
// Forward-declare
template<class T>
int find_max(std::vector<std::vector<T> > target_array);
// First, define the base case
int find_max(std::vector<int> target_array) {
using namespace std;
return *max_element(
target_array.begin(),
target_array.end());
}
// Then the general case
template<class T>
int find_max(std::vector<std::vector<T> > target_array) {
using namespace std;
// Reserve a vector for the recursive call
vector<int> reduced(target_array.size());
// Recursively apply this function to each nested vector
transform(
target_array.begin(),
target_array.end(),
reduced.begin(),
[](std::vector<T> v){ return find_max(v); });
// Then find the maximum of the reduced vector
return *max_element(
reduced.begin(),
reduced.end());
}
Here's another minimal example of how it can be done:
int find_max(int i) {
return i;
}
template <typename T>
int find_max(const std::vector<T>& v) {
return std::accumulate(std::begin(v), std::end(v),
std::numeric_limits<int>::min(),
[] (const int prev, const T& v) {
int m = find_max(v);
return (m > prev) ? m : prev;
});
}
This will work with an arbitrary level of nested std::vectors.
Live example
Edit:
See the updated code (changed return statement inside the lambda). Previous version did not work correctly with negative numbers.
Be aware that templated functions can derive their argument types. You don't need to specify the types to call the methods; and you can have them drive their call parameters for you (same isn't true for template structures). You can exploit that.
Here's another solution:
int find_max(int a) { return a; } // Just a base case for recursion
template<typename T>
int find_max(const std::vector<T>& v)
{
int r = find_max(v.front());
for (auto i=v.begin()+1, e=end()
; i<e
; ++i)
{
int c = find_max(*i);
if (c>r) r=c;
}
return r;
}
The usage is the same regardless of how many nested vectors you have:
cout << "Max in 1d array: " << find_max(array_1d) << endl;
cout << "Max in 2d array: " << find_max(array_2d) << endl;
cout << "Max in 3d array: " << find_max(array_3d) << endl;
...the STL approach is more focused on giving you the maximum T in a container of T; if we're nesting T's, we have to recurse twice to get the root element's out (one to tell us which T has the max value, and again to extract it). The approach here is simple bottom up recursion (each find_max gives you the largest value of that level structure, and we just trickle out).

Computing the scalar product of two vectors in C++

I am trying to write a program with a function double_product(vector<double> a, vector<double> b) that computes the scalar product of two vectors. The scalar product is
$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$.
Here is what I have. It is a mess, but I am trying!
#include <iostream>
#include <vector>
using namespace std;
class Scalar_product
{
public:
Scalar_product(vector<double> a, vector<double> b);
};
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
int main() {
cout << product << endl;
return 0;
}
Unless you need to do this on your own (e.g., writing it is homework), you should really use the standard algorithm that's already written to do exactly what you want:
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<double> a {1, 2, 3};
std::vector<double> b {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(std::begin(a), std::end(a), std::begin(b), 0.0);
return 0;
}
Note that while begin(a) and end(a) are new in C++11, std::inner_product has been available since C++98. If you are using C++ 98 (or 03), it's pretty easy to write your own equivalent of begin and end to work with arrays though:
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
Using these, a C++ 98 version of the previous code could look something like this:
int main() {
double a[] = {1, 2, 3};
double b[] = {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(begin(a), end(a), begin(b), 0.0);
return 0;
}
Note that the begin and end above will only work for arrays, where the begin and end in C++11 (and later) will also work for normal collection types that define a .begin() and .end() (though it's trivial to add overloads to handle those as well, of course):
template <class Coll>
typename Coll::iterator begin(Coll const& c) { return c.begin(); }
template <class Coll>
typename Coll::iterator end(Coll const& c) { return c.end(); }
You can delete the class you have defined. You don't need it.
In your scalar_product function:
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
It's almost there. You don't need 2 loops. Just one.
double scalar_product(vector<double> a, vector<double> b)
{
if( a.size() != b.size() ) // error check
{
puts( "Error a's size not equal to b's size" ) ;
return -1 ; // not defined
}
// compute
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
product += (a[i])*(b[i]); // += means add to product
return product;
}
Now to call this function, you need to create 2 vector objects in your main(), fill them with values, (the same number of values of course!) and then call scalar_product( first_vector_that_you_create, second_vector_object );
While you have been presented many solutions that work, let me spin up another variation to introduce a couple of concepts that should help you writing better code:
class are only needed to pack data together
a function should check its preconditions as soon as possible, those should be documented
a function should have postconditions, those should be documented
code reuse is the cornerstone of maintenable programs
With that in mind:
// Takes two vectors of the same size and computes their scalar product
// Returns a positive value
double scalar_product(std::vector<double> const& a, std::vector<double> const& b)
{
if (a.size() != b.size()) { throw std::runtime_error("different sizes"); }
return std::inner_product(a.begin(), a.end(), b.begin(), 0.0);
} // scalar_product
You could decide to use the inner_product algorithm directly but let's face it:
it requires four arguments, not two
it does not check for its arguments being of the same size
so it's better to wrap it.
Note: I used const& to indicate to the compiler not to copy the vectors.
You seem to want to make a class specifically for vectors. The class I made in my example is tailored to 3 dimensional vectors, but you can change it to another if desired. The class holds i,j,k but also can conduct a scalar products based on other MathVectors. The other vector is passed in via a C++ reference. It is hard to deduce what the question was, but I think this might answer it.
#include <iostream>
using namespace std;
class MathVector
{
private:
double i,j,k;
public:
MathVector(double i,double j,double k)
{
this->i=i;
this->j=j;
this->k=k;
}
double getI(){return i;}
double getJ(){return j;}
double getK(){return k;}
double scalar(MathVector &other)
{
return (i*other.getI())+(j*other.getJ())+(k*other.getK());
}
};
int main(int argc, char **argv)
{
MathVector a(1,2,5), b(2,4,1);
cout << a.scalar(b) << endl;
return 0;
}
Here is the code that you should have. I see you have used class in your code, which you do not really need here. Let me know if the question required you to use class.
As you are new and this code might scare you. So, I will try to explain this as I go. Look for comments in the code to understand what is being done and ask if you do not understand.
//Scalar.cpp
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
/**
This function returns the scalar product of two vectors "a" and "b"
*/
double scalar_product(vector<double> a, vector<double> b)
{
//In C++, you should declare every variable before you use it. So, you declare product and initialize it to 0.
double product = 0;
//Here you check whether the two vectors are of equal size. If they are not then the vectors cannot be multiplied for scalar product.
if(a.size()!=b.size()){
cout << "Vectors are not of the same size and hence the scalar product cannot be calculated" << endl;
return -1; //Note: This -1 is not the answer, but just a number indicating that the product is not possible. Some pair of vectors might actually have a -1, but in that case you will not see the error above.
}
//you loop through the vectors. As bobo also pointed you do not need two loops.
for (int i = 0; i < a.size(); i++)
{
product = product + a[i]*b[i];
}
//finally you return the product
return product;
}
//This is your main function that will be executed before anything else.
int main() {
//you declare two vectors "veca" and "vecb" of length 2 each
vector<double> veca(2);
vector<double> vecb(2);
//put some random values into the vectors
veca[0] = 1.5;
veca[1] = .7;
vecb[0] = 1.0;
vecb[1] = .7;
//This is important! You called the function you just defined above with the two parameters as "veca" and "vecb". I hope this cout is simple!
cout << scalar_product(veca,vecb) << endl;
}
If you are using an IDE then just compile and run. If you are using command-line on a Unix-based system with g++ compiler, this is what you will do (where Scalar.cpp is the file containing code):
g++ Scalar.cpp -o scalar
To run it simply type
./scalar
You should get 1.99 as the output of the above program.