retrieving values from Vector in Eigen Solver - c++

I am using Eigen Solver. I am having trouble retrieving the values from Vectors/Matrix that I create. For example in the following code, I don't have an error but get a run time error.
#include <iostream>
#include <math.h>
#include <vector>
#include <Eigen\Dense>
using namespace std;
using namespace Eigen;
int main()
{
Matrix3f A;
Vector3f b;
vector<float> c;
A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
b << 3, 3, 4;
cout << "Here is the matrix A:\n" << A << endl;
cout << "Here is the vector b:\n" << b << endl;
Vector3f x = A.colPivHouseholderQr().solve(b);
for (int i = 0; i < 3; i++)
{
c[i] = x[i];
cout << c[i] << " ";
}
//cout << "The solution is:\n" << x << endl;
return 0;
}
How do I retrieve the value in x to a variable of my choice (I need this as this will be a parameter in another function I wrote).

Use
vector<float> c(3);
Or
for (int i = 0; i < 3; i++)
{
c.push_back(x[i]);
cout << c[i] << " ";
}

As stated in the comment, the problem was that c was not resized before assigning values to it. Additionally, you actually don't need the Eigen::Vector3f x, but you can assign the result of the .solve() operation directly to a Map which points to the data of the vector:
#include <iostream>
#include <vector>
#include <Eigen/QR>
using namespace Eigen;
using namespace std;
int main()
{
Matrix3f A;
Vector3f b;
vector<float> c(A.cols());
A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
b << 3, 3, 4;
cout << "Here is the matrix A:\n" << A << endl;
cout << "Here is the vector b:\n" << b << endl;
Vector3f::Map(c.data()) = A.colPivHouseholderQr().solve(b);
for(int i=0; i<3; ++i) std::cout << "c[" << i << "]=" << c[i] << '\n';
}

Related

How do I fill matrices created in c++ using boost uBLAS?

Im new to C++ in general. I have an assignment where I need to create a 5x5 matrix with set constant values using the boost uBLAS library. I then have to multiply those matrices using boost uBLAS.
So far I have:
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
using namespace boost::numeric::ublas;
int main()
{
matrix<double> m1 (5, 5);
vector<double> v1 (5);
std::cout << m1;
std::cout << v1;
}
So basically I created 5x5 matrix and a vector which are both filled with zeroes. How do I fill the matrix and vector with my desired numbers, so that (for example):
m1 = [2,1,4,6,3;
8,2,0,1,4;
7,3,2,4,7;
1,2,0,9,3;
2,6,4,3,1]
and
v1 = [2;
3;
1;
7;
6]
You can use the uBlas assignment operator <<=:
#include <boost/numeric/ublas/assignment.hpp>
Then e.g.
m1 <<= 2,1,4,6,3,
8,2,0,1,4,
7,3,2,4,7,
1,2,0,9,3,
2,6,4,3,1;
v1 <<= 2,
3,
1,
7,
6;
std::cout << "m1: " << m1 << "\n";
std::cout << "v1: " << v1 << "\n";
See it Live On Coliru
#include <boost/numeric/ublas/assignment.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
using namespace boost::numeric::ublas;
int main() {
matrix<double> m1(5, 5);
vector<double> v1(5);
std::cout << "m1: " << m1 << "\n";
std::cout << "v1: " << v1 << "\n";
m1 <<= 2,1,4,6,3,
8,2,0,1,4,
7,3,2,4,7,
1,2,0,9,3,
2,6,4,3,1;
v1 <<= 2,
3,
1,
7,
6;
std::cout << "m1: " << m1 << "\n";
std::cout << "v1: " << v1 << "\n";
}
Prints
m1: [5,5]((0,0,0,0,0),(0,0,0,0,0),(0,0,0,0,0),(0,0,0,0,0),(0,0,0,0,0))
v1: [5](0,0,0,0,0)
m1: [5,5]((2,1,4,6,3),(8,2,0,1,4),(7,3,2,4,7),(1,2,0,9,3),(2,6,4,3,1))
v1: [5](2,3,1,7,6)

Is it possible to assign to an array from an initializer list?

I am trying to make it possible to assign to an array from an initializer list in C++, if this is possible how to do it? may be the new versions of C++ needs to achieve it or not?
Code:
#include <iostream>
#include <array>
using namespace std;
int main()
{
int arrayName_A[5];
arrayName_A = {1,2,3,4,5};
for (int i=0;i<5;i++)
{
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
}
}
No, it's not possible. You either have to intialize the array directly:
int arrayName_A[5] = {1,2,3,4,5};
or use std::array instead:
std::array<int, 5> arrayName_A;
arrayName_A = {1, 2, 3, 4, 5};
Arrays do not have the assignment operator. Arrays are non-modifiable lvalues.
That is you may not write for example
int a[3] = { 1, 2, 3 };
int b[3] = a;
or
int a[3] = { 1, 2, 3 };
int b[3];
b = a;
You may set each element of an array with a value from an initializer list using the range-based for loop as it is shown in the demonstrative program below.
#include <iostream>
int main()
{
int arrayName_A[5];
size_t i = 0;
for ( const auto &item : { 1, 2, 3, 4, 5 } ) arrayName_A[i++] = item;
for ( const auto &item : arrayName_A ) std::cout << item << ' ';
std::cout << '\n';
return 0;
}
The program output is
1 2 3 4 5
Otherwise use the standard class std::array that has the assignment operator. For example
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> arrayName_A;
arrayName_A = { 1, 2, 3, 4, 5 };
// or
arrayName_A = { { 1, 2, 3, 4, 5 } };
for ( const auto &item : arrayName_A ) std::cout << item << ' ';
std::cout << '\n';
return 0;
}
The program output is the same as shown above that is
1 2 3 4 5
You need to initialize the array as soon as you declare it, like this :
#include <iostream>
#include <array>
using namespace std;
int main()
{
int arrayName_A[5] = {1,2,3,4,5};
for (int i=0;i<5;i++)
{
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
cout << "\n Starting checker" << '\n';
cout << "checked: " << arrayName_A[i] << '\n';
}
}

terminate called after throwing an instance of 'std::out_of_range' in C++

I am new to C++ and learning data structures. In the below code I am getting an "out of range warning", and do not understand what I am doing wrong.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers{100,-1,2,4,55,78,3};
int temp {};
int pass {};
pass = numbers.size();
for(int i {0} ;i<pass-1;i++){
for(int j {0} ; j<pass-1-i ; j++){
if(numbers.at(j) > numbers.at(j+1)){
temp = numbers.at(j);
numbers.at(j)=numbers.at(j+1);
numbers.at(j+1)=temp;
}
}
}
cout << numbers.at(0) << endl;
cout << numbers.at(1) << endl;
cout << numbers.at(2) << endl;
cout << numbers.at(3) << endl;
cout << numbers.at(4) << endl;
cout << numbers.at(5) << endl;
cout << numbers.at(6) << endl;
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
return 0;
}
It seems like you may not understand how std::vectors work.
You have only declared 7 elements in your vector which means you can only go up to the index 6. This is because std::vector's indices start at 0. This is true for std::array as well.
vector<int> numbers{100,-1,2,4,55,78,3};
However, in your code you have put these two statements:
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
which doesn't work because like I mentioned you can only go up to index 6.
You should also consider using a for loop like the comments mention above. It is more simple to use and is less work.
For example eith a for loop:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> numbers{ 100,-1,2,4,55,78,3 };
int temp{};
int pass{};
pass = numbers.size();
for (int i{ 0 }; i < pass - 1; i++) {
for (int j{ 0 }; j < pass - 1 - i; j++) {
if (numbers.at(j) > numbers.at(j + 1)) {
temp = numbers.at(j);
numbers.at(j) = numbers.at(j + 1);
numbers.at(j + 1) = temp;
}
}
}
std::cout << "v = { ";
for (int i = 0; i < numbers.size(); i++) {
std::cout << numbers.at(i) << ", ";
}
std::cout << "}; \n";
return 0;
}
Output:
v = { -1, 2, 3, 4, 55, 78, 100, };

Printing set using the copy function

The problem I am having is that I need to print the resulting set from the union_set function using the copy function. (So I am not allowed to just put output as the last term of the set_union function). I cannot seem to get the copy function to work correctly for the lastAunionB pointer (i have to to a few more times as well). What I have currently is just my last attempt at an answer, although I tried many more things. What am I doing incorrectly with the copy function? Here is the code.
#include <iostream>
#include <iterator>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int setA[5] = {2, 4, 5, 7, 8};
int setB[7] = {1, 2, 3, 4, 5, 6, 7};
int setC[5] = {2, 5, 8, 8, 15};
int setD[6] = {1, 4, 4, 6, 7, 12};
set<int> set2A(setA,setA+5);
set<int> set2B(setB,setB+7);
set<int> set2C(setC,setC+5);
set<int> set2D(setD,setD+6);
int AunionB[12];
int AunionC[10];
int BunionD[13];
int AintersectB[12];
int AintersectC[10];
set<int> finalUnion;
set<int> finalIntersection;
set<int> final2Union;
set<int> final2Intersection;
set<int> final2Difference;
ostream_iterator< int > output( cout, " " );
int *lastAunionB;
int *lastAunionC;
int *lastBunionD;
int *lastAintersectB;
int *lastAintersectC;
cout << "setA = ";
copy(set2A.begin(), set2A.end(), output);
cout << endl;
cout << "setB = ";
copy(set2B.begin(), set2B.end(), output);
cout << endl;
cout << "setC = ";
copy(set2C.begin(), set2C.end(), output);
cout << endl;
cout << "setD = ";
copy(set2D.begin(), set2D.end(), output);
cout << endl;
//here is where the problem lies
cout << "AunionB = ";
lastAunionB = set_union(setA, setA+5, setB, setB+7, AunionB);
copy(lastAunionB, lastAunionB, output);
cout << endl;
/*
cout << "AunionC = ";
set_union(setA, setA+5, setC, setC+5, AunionC);
cout << endl;
cout << "BunionD = ";
set_union(setB, setB+7, setD, setD+6, BunionD);
cout << endl;
cout << "AintercectB = ";
set_intersection(setA, setA+5, setB, setB+7, AintersectB);
cout << endl;
cout << "AintercectC = ";
set_intersection(setA, setA+5, setC, setC+7, AintersectC);
cout << endl;
*/
return 0;
}
lastAunionB = set_union(setA, setA+5, setB, setB+7, AunionB);
copy(lastAunionB, lastAunionB, output);
The last argument you pass to set_union will correspond to the beginning of the range of the new set constructed. The return value of set_union will be the end of this range.
You'd want lastAunionB and the other raw pointers and pretty much everything you're passing as an iterator here to be defined with the type std::set<int>::iterator and you'd want to copy over the range like this:
std::copy(AunionB, lastAunionB, output);
You're trying to copy from an empty range.
copy(ptr,ptr,output);
will always not print anything.

How to return boolean value from a template function?

In the following C++ code, I want to use a template function to determine if two vectors are exactly the same, but, I always get false from the template function. Would you give me suggestion about how to return boolean values from a template function? (My C++ compiler is g++ 4.6)
Edit: after pop_back both p1 p2 p3 p4, the results are now matched with what I expected.
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
template<class T> bool areTheyMatched(shared_ptr<vector<T>> p1, shared_ptr<vector<T>> p2) {
if ((*p1).size() == (*p2).size()) {
cout << (*p1).size() << endl;
for (unsigned int i = 0; i < (*p1).size(); i++) {
if ((*p1)[i] != (*p2)[i]) {
cout << (*p1)[i] << " " << (*p2)[i] << endl;
return false;
}
}
} else {
return false;
}
cout << "All elements are exactly the same" << endl;
return true;
}
int main(int argc, char *argv[]) {
shared_ptr<vector<int>> p1(new vector<int>);
shared_ptr<vector<int>> p2(new vector<int>);
shared_ptr<vector<double>> p3(new vector<double>);
shared_ptr<vector<double>> p4(new vector<double>);
for (int i = 0; i < 10; i++)
(*p1).push_back(i);
for (int i = 0; i < 9; i++)
(*p2).push_back(i);
(*p2).push_back(11);
for (double i = 0.0; i < 9.9; i += 1.1)
(*p3).push_back(i);
for (double i = 0.0; i < 8.8; i += 1.1)
(*p4).push_back(i);
(*p4).push_back(11.0);
cout << "Case 1: " << areTheyMatched(p1, p2) << endl;
(*p1).pop_back();
(*p2).pop_back();
cout << "Case 2: " << areTheyMatched(p1, p2) << endl;
cout << "Case 3: " << areTheyMatched(p3, p4) << endl;
(*p3).pop_back();
(*p4).pop_back();
cout << "Case 4: " << areTheyMatched(p3, p4) << endl;
p1.reset();
p2.reset();
p3.reset();
p4.reset();
return 0;
}
The template code seems fine, but the test vectors just never are the same, are they.
First they differ in one of them having the element 11, and when removing that they have different sizes.
Your vectors are realy different.
for (int i = 0; i < 10; i++)
(*p1).push_back(i);
for (int i = 0; i < 9; i++)
(*p2).push_back(i);
(*p2).push_back(11);
p1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
p2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 11}
Case 1: false
(*p2).pop_back();
p1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
p2 = {0, 1, 2, 3, 4, 5, 6, 7, 8}
Case 2: false
Your template function is totally fine...
The reason you're getting false is because your inputs really are different, initially in content, and after the pop even the size doesn't match.
Is there a reason why you're using shared_ptr? You could pass vector& and unless you need shared pointers for a good reason, you shouldn't use them. Although they are the best way to pass pointers around when you need to share data across many entities, they have an overhead.
If you instrument the code, you'll see that it works correctly. I needed to use std::tr1 and <tr1/memory> and > > instead of >> to get it to compile with G++ 4.6.1, but this shows it working:
#include <iostream>
#include <tr1/memory>
#include <vector>
using namespace std;
using namespace std::tr1;
template<class T> bool areTheyMatched(shared_ptr< vector<T> > p1, shared_ptr< vector<T> > p2)
{
cout << "p1.size: " << (*p1).size() << ", p2.size: " << (*p2).size() << endl;
if ((*p1).size() != (*p2).size())
return false;
for (unsigned int i = 0; i < (*p1).size(); i++)
{
if ((*p1)[i] != (*p2)[i])
{
cout << "i = " << i << ": " << (*p1)[i] << " " << (*p2)[i] << endl;
return false;
}
}
cout << "All elements are exactly the same" << endl;
return true;
}
int main()
{
shared_ptr< vector<int> > p1(new vector<int>);
shared_ptr< vector<int> > p2(new vector<int>);
shared_ptr< vector<double> > p3(new vector<double>);
shared_ptr< vector<double> > p4(new vector<double>);
for (int i = 0; i < 10; i++)
(*p1).push_back(i);
for (int i = 0; i < 9; i++)
(*p2).push_back(i);
(*p2).push_back(11);
for (double i = 0.0; i < 9.9; i += 1.1)
(*p3).push_back(i);
for (double i = 0.0; i < 8.8; i += 1.1)
(*p4).push_back(i);
(*p4).push_back(11.0);
cout << "Case 1: " << areTheyMatched(p1, p2) << endl;
(*p2).pop_back();
cout << "Case 2: " << areTheyMatched(p1, p2) << endl;
(*p1).pop_back();
cout << "Case 2a: " << areTheyMatched(p1, p2) << endl;
cout << "Case 3: " << areTheyMatched(p3, p4) << endl;
(*p3).pop_back();
cout << "Case 4: " << areTheyMatched(p3, p4) << endl;
(*p4).pop_back();
cout << "Case 4a: " << areTheyMatched(p3, p4) << endl;
p1.reset();
p2.reset();
p3.reset();
p4.reset();
return 0;
}
Output
p1.size: 10, p2.size: 10
i = 9: 9 11
Case 1: 0
p1.size: 10, p2.size: 9
Case 2: 0
p1.size: 9, p2.size: 9
All elements are exactly the same
Case 2a: 1
p1.size: 10, p2.size: 10
i = 9: 9.9 11
Case 3: 0
p1.size: 9, p2.size: 10
Case 4: 0
p1.size: 9, p2.size: 9
All elements are exactly the same
Case 4a: 1