How to create a dynamic 3d matrix using the Eigen library. and how can slice the particular channel, in that channel slice some height and width?
example:
I want to create a matrix of size 3 * 320 * 240 (here channel width and height known at runtime), and then select a slice of 3 * 3 in each channel.
Perhaps something like this:
#include <iostream>
#include <vector>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
int a = 320;
int b = 240;
// Create as many as you want, probably better in a loop.
MatrixXd m(a, b);
MatrixXd n(a, b);
MatrixXd o(a, b);
std::vector<MatrixXd> v;
v.push_back(m);
v.push_back(n);
v.push_back(o);
std::cout << v.at(0)(0, 1) << std::endl;
}
Related
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>
I need to compute some determinants for a project: I use c++ 14 and Eigen.
So, MatrixXd A is a Eigen matrix with X rows and X cols and contains double values. To compute determinant I use A.determinant(). Let's pretend that A.determinant() is equal to d. Then, the problem apper when I use QR decomposition because R.determinant() is equal to -d, should be equal to d. This happened only for large matrices (with size greater than 5 - I observed this). Only the sign is problem, why?
My code:
#include <iostream>
#include <Eigen>
#include <fstream>
#include <chrono>
using namespace Eigen;
using namespace std;
using namespace std::chrono;
ifstream fin("input.txt");
int main()
{
double aux;
int n = 10;
MatrixXd A;
A.resize(n,n);
// Read A
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
fin>>aux;
A(i,j) = aux;
}
cout<<"Start!"<<endl;
cout<<A.determinant()<<endl;
//Use QR decomposition, get R matrix
HouseholderQR<MatrixXd> qr(A);
qr.compute(A);
MatrixXd R = qr.matrixQR().template triangularView<Upper>();
// R is a triangular matrix, det(A) should be equal to det(R)
cout<<R.determinant()<<endl;
return 0;
}
How can I solve this?
img
I have a MatrixXf variable and a VectorXf variable. I would like to perform a rowwise division using the Vector on my Matrix. Is it possible to do something like this?
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main() {
MatrixXf mat(3, 2);
mat << 1, 2,
3, 4,
5, 6;
VectorXf vec(2);
vec << 2, 3;
mat = mat.rowwise() / vec;
cout << mat << endl;
return 0;
}
I am expecting to get a matrix with value [0.5, 0.667; 1.5, 1.333; 2.5, 2].
Thank you very much!
You need to use the matrix and vector as arrays (and not linear algebra objects, see docs). To do so, you would rewrite the relevant line as:
mat = mat.array().rowwise() / vec.transpose().array();
cout << mat << endl; // Note that in the original this was vec
The transpose is needed as the VectorXf is a column vector by definition, and you wanted a row vector.
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();
I try to use thrust to find the max element from a 2D matrix. However, I always get incorrent results. The codes work well for 1D matrix but behave unpredictably when using 2D matrix.
I use opencv GpuMat for 2D matrix. Here are my codes. I wonder if someone met the same problem?
#include <thrust/device_ptr.h>
#include <thrust/device_vector.h>
#include <thrust/extrema.h>
#include <iostream>
#include <opencv2\opencv.hpp>
#include <opencv2\cuda.hpp>
using namespace std;
using namespace cv;
using namespace cv::cuda;
ushort thrust_find_max_idx(const GpuMat& in_, int* p_r_, int* p_c_){
thrust::device_ptr<ushort> ptr((ushort*)in_.data);
unsigned int N = in_.cols * in_.rows;
thrust::device_vector<ushort>::iterator iter = thrust::max_element(ptr, ptr + N); //find max element
int pos = thrust::device_pointer_cast(&(iter[0])) - ptr;
*p_r_ = pos / in_.cols;
*p_c_ = pos % in_.cols;
return *iter;
}
int main(void)
{
Mat cpu_matrix; cpu_matrix.create(10, 10, CV_16UC1);
randu(cpu_matrix, 1, 256); //generate random sequences
GpuMat matrix; matrix.upload(cpu_matrix);
int r, c;
ushort max = thrust_find_max_idx( matrix, &r, &c);
matrix.download(cpu_matrix);
cout << cpu_matrix << endl; //output testing sequences
cout << max << " r " << r << " c " << c << endl; //output max element and positions
return 0;
}
Thank to Robert's reply, I realize that GpuMat is not continuously allocated as Mat by default, but luckily, the Function cuda::minMaxLoc() can be used for quickly identifying max element in a GpuMat.
double max; cv::Point loc;
cv::cuda::minMaxLoc(matrix, 0, &max, 0, &loc);