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

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)

Related

Sizes of the dimensions of a multidimensional array

I knew it but now can't remember the function template std::??? that returns the sizes used for declaring a multidimensional arrays. Could you remind me this function? It works like in the below example, if I remember it right.
#include <iostream>
int main() {
int a[][2] = {{}, {}, {}};
std::cout << std::size(a) << std::endl; // outputs 3
std::cout << std::???<0>(a) << std::endl; // outputs 3, same as std::size(a)
std::cout << std::???<1>(a) << std::endl; // outputs 2, same as std::size(a[0])
}
I do not need its implementations, I want to use the existing function.
Thank #sklott the answer:
#include <iostream>
#include <type_traits>
int main() {
int a[][2] = {{}, {}, {}};
std::cout << std::size(a) << std::endl; // outputs 3
std::cout << std::extent<decltype(a), 0>::value << std::endl; // outputs 3, same as std::size(a)
std::cout << std::extent<decltype(a), 1>::value << std::endl; // outputs 2, same as std::size(a[0])
}
Thank #sklott the answer:
#include <iostream>
#include <type_traits>
int main() {
int a[][2] = {{}, {}, {}};
std::cout << std::size(a) << std::endl; // outputs 3
std::cout << std::extent<decltype(a), 0>() << std::endl; // outputs 3, same as std::size(a)
std::cout << std::extent<decltype(a), 1>() << std::endl; // outputs 2, same as std::size(a[0])
}

Which operations on what type of classes invalidates an Eigen:Ref?

I came across the following behavior with Eigen::Ref :
#include <iostream>
#include <Eigen/Dense>
int main()
{
Eigen::VectorXf a = Eigen::Vector2f{1,2};
Eigen::Ref<Eigen::VectorXf> ref{a};
std::cout << a.transpose() << "\n"; // prints: 1, 2
std::cout << ref.transpose() << "\n"; // prints: 1, 2
a = Eigen::Vector3f{3,4,5};
std::cout << a.transpose() << "\n"; // prints: 3, 4, 5
std::cout << ref.transpose() << "\n"; // prints: 3, 4
return 0;
}
The invalidation of Eigen references does not seem to be documented as far as I can tell. When does it occur?

Shortest solution to permute the elements of a std::vector using stl

Assume that you have an std::vector<T> of some type T and a selection of indices std::vector<int> of this vector. Now I'm looking for a function permute(const std::vector<T>& vector, const std::vector<int>& indices), that returns the permuted vector with respect to the given indices.
The problem is easily solved by writing a short function like depicted below:
template<typename T>
std::vector<T> permute(const std::vector<T>& matrix, const std::vector<int>& indices) {
std::vector<T> ret;
for (auto p : indices) {
ret.push_back(matrix[p]);
}
return ret;
}
int main(int, char**) {
std::vector<int> perm{ 1,2,0 };
std::vector<std::vector<double>> matrix = { {1.,2.,3.},{4.,5.,6.},{7.,8.,9.} };
auto matrixPerm=permute(matrix, perm);
std::cout << matrixPerm[0][0] << " == " << matrix[1][0] << std::endl;
std::cout << matrixPerm[1][0] << " == " << matrix[2][0] << std::endl;
std::cout << matrixPerm[2][0] << " == " << matrix[0][0] << std::endl;
}
I'm now wondering what might be most elegant version of this program, if we can use STL or even the Boost libraries. In STL for example we have shuffle(), but we cannot say in what way to shuffle.
Does anyone now, how to shorten the function?
Solution using std::transform()
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
int main(int, char**) {
std::vector<int> perm{ 1,2,0 };
std::vector<std::vector<double>> matrix = { {1.,2.,3.},{4.,5.,6.},{7.,8.,9.} };
std::vector<std::vector<double>> output;
std::transform(perm.begin(), perm.end(), std::back_inserter(output), [&](int i) { return matrix[i]; });
std::cout << output[0][0] << " == " << matrix[1][0] << std::endl;
std::cout << output[1][0] << " == " << matrix[2][0] << std::endl;
std::cout << output[2][0] << " == " << matrix[0][0] << std::endl;
}
You can transform the indices into iterators and then create an indirect range with Boost.Range.
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/range/adaptor/indirected.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
int main(int, char**) {
using namespace boost::adaptors;
std::vector<int> perm{ 1,2,0 };
std::vector<std::vector<double>> matrix = { {1.,2.,3.},{4.,5.,6.},{7.,8.,9.} };
std::vector<std::vector<double>> output;
auto permutation = perm | transformed( [&matrix](int x) { return matrix.begin() + x; }) | indirected;
boost::copy(
permutation,
std::back_inserter(output));
std::cout << output[0][0] << " == " << matrix[1][0] << std::endl;
std::cout << output[1][0] << " == " << matrix[2][0] << std::endl;
std::cout << output[2][0] << " == " << matrix[0][0] << std::endl;
}
You could skip copying the elements and just process the range if you don't need a real vector.
The range adaptor uses the permutation iterator from the Boost.Iterator library. You can also use this directly, but you have to manually define begin and end:
auto begin = make_permutation_iterator( matrix.begin(), perm.begin() );
auto end = make_permutation_iterator( matrix.end(), perm.end() );
std::copy(begin, end, std::back_inserter(output) );

retrieving values from Vector in Eigen Solver

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';
}

Eigen Increment Column by One

How to increment a column of a dynamic matrix by one, as an in place operation (without creating copies/intermediates) ?
Attempt:
#include <Eigen/Dense>
#include <iostream>
#include <stdint.h>
int main(void){
Eigen::MatrixXf A;
A = Eigen::MatrixXf::Random(3, 5);
std::cout << A << std::endl << std::endl;
A.col(1) = A.col(1)*2; //this works.
A.col(1) = A.col(1) + 1; //this doesn't work.
std::cout << A << std::endl;
}
I found a way to do this. But I don't know if the operation is in place.
This is similar to eigen: Subtracting a scalar from a vector
#include <Eigen/Dense>
#include <iostream>
int main(void){
Eigen::MatrixXf A;
A = Eigen::MatrixXf::Random(3, 5);
std::cout << A << std::endl << std::endl;
A.col(1) = A.col(1)*2;
A.col(1) = A.col(1) + Eigen::VectorXf::Ones(3);
std::cout << A << std::endl;
}
Another way is to use array operation. This way seem better (I guess).
https://eigen.tuxfamily.org/dox/group__TutorialArrayClass.html
#include <Eigen/Dense>
#include <iostream>
int main(void){
Eigen::MatrixXf A;
A = Eigen::MatrixXf::Random(3, 5);
std::cout << A << std::endl << std::endl;
A.array() += 1;
A.col(1).array() += 100;
std::cout << A << std::endl;
}