How to create an Eigen::Ref to a fixed-sized matrix row? - eigen3

I would like to write something like foo4 similar to foo3 in the Eigen::Ref doc here :
#include <Eigen/Dense>
using namespace Eigen;
void foo3(Ref<VectorXf, 0, Eigen::InnerStride<> >){};
void foo4(Ref<Vector3f, 0, Eigen::InnerStride<> >){};
int main()
{
Eigen::Matrix3f fmat = Eigen::Matrix3f::Identity();
Eigen::MatrixXf dmat = Eigen::Matrix3f::Identity();
foo3(dmat.row(1)); // OK
foo3(fmat.row(1)); // Error : YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
foo4(fmat.row(1)); // Error : YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
}
I'm using Eigen version 3.3.7

You are getting size-mismatch errors, because you are trying to pass row-vectors where column vectors are expected.
There are two solutions:
Change the function to accept row-vectors:
void foo3(Ref<RowVectorXf, 0, Eigen::InnerStride<> >){};
void foo4(Ref<RowVector3f, 0, Eigen::InnerStride<> >){};
Explicitly transpose the vector you pass to the function:
foo3(fmat.row(1).transpose());
foo4(fmat.row(1).transpose());
Note that there are some cases where Eigen implicitly transposes row-vectors to column-vectors (like the following example). But generally, I would not rely on that and always explicitly transpose vectors to match the orientation:
Eigen::MatrixXd A(rows,cols);
Eigen::VectorXd v1 = A.row(0); // this works
Eigen::VectorXd v2 = A.row(0).transpose(); // more verbose, but what actually happens

Related

Create EigenSolver from MatrixWrapper

How to construct an EigenSolver from a MaxtrixWrapper?
test (also at godbolt.org)
#include <Eigen/Eigen>
using namespace Eigen;
template<typename D>
void f(const Eigen::DenseBase<D>& a) {
const Eigen::MatrixWrapper<const D> a2(a.derived());
Eigen::EigenSolver<typename Eigen::MatrixWrapper<const D>>
es(a2);
}
int main() {
ArrayXXf a(3, 3);
a = 1.0f;
f(a);
}
1st Error:
<...>/eigen3/Eigen/src/Eigenvalues/EigenSolver.h:71:10: error:
‘Options’ is not a member of
‘Eigen::EigenSolver<
Eigen::MatrixWrapper<
const Eigen::Array<float, -1, -1>
>
>::MatrixType {
aka Eigen::MatrixWrapper<const Eigen::Array<float, -1, -1> >}’
enum {
You don't. The solvers all want a plain Matrix<...> (or a Ref<Matrix<...> >) as template parameter. You can get the correct Matrix type using:
template<typename D>
void f(const Eigen::DenseBase<D>& a) {
Eigen::EigenSolver<typename D::PlainMatrix> es(a.derived().matrix());
}
The .derived().matrix() is actually optional here, since ArrayXXf gets converted to MatrixXf implicitly. (godbolt times out on this -- the EigenSolver is quite heavy for the compiler).

Conduct AngleAxisToRotationMatirx on part of a double arrray in Ceres?

Nowadays I'm working with Ceres and Eigen. And I have a 6x3 = 18-d double array, let's call it xs, which is defined as:
double xs[6*3];
Basically xs contains the 6 rotations expressed in angle-axis format. And I need to turn each rotation of all 6 into rotation matrix format, then matrix multiplication will be conducted.
struct F1 {
template <typename T> bool operator()(const T* const xs,
T* residual) const {
Eigen::Map<const Eigen::Matrix<T,3,1> > m0(xs, 3);
T m[9], res[3];
ceres::AngleAxisToRotationMatrix(m0, m);
residual[0] = res[0];
residual[1] = res[1];
residual[2] = res[2];
}
Here in the example code I extract first 3 elements of xs via Eigen::Map, then I applied AngleAxisToRotationMatrix on it. But I keep receiving such errors:
error: no matching function for call to ‘AngleAxisToRotationMatrix(Eigen::Map<const Eigen::Matrix<ceres::Jet<double, 18>, 3, 1, 0, 3, 1>, 0, Eigen::Stride<0, 0> >&, ceres::Jet<double, 1> [9])’
Can somebody lend me a hand here? I'm pretty new to Ceres and Eigen, it really drove me almost to crazy.
Thanks!
ceres::AngleAxisToRotationMatrix expects raw pointers:
AngleAxisToRotationMatrix(xs, m);

making 3d array with arma::cube in Rcpp shows cube error

I am making a Rcpp code for Gibbs sampling. Inside the code, I first want to make a 3 dimensional array with row number= number of iteration (500), column number=number of parameter(4) and slice number= number of chain(3). I wrote it in this way:
#include <RcppArmadillo.h>
#include <math.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace std;
using namespace arma;
//Gibbs sampling code starts here
Rcpp::List mcmc(const int iter,const int chains, const NumericVector data){
arma::cube posteriorC = arma::zeros(iter, 5, chains);
\\ rest of the codes
List out(Rcpp::List::create(Rcpp::Named("posteriorC") =posteriorC));
return out;
}
. While compelling it does not show any error. But when I want to run the code with:
res<- mcmc(iter=500,chains=2,data)
it shows the error:
Error: Cube::operator(): index out of bounds
. I want to know if there any mistake while making the 3D array. Please note that I want to get estimates of 5 parameters of my model.
You need to specify the template for arma::zeros to correctly fill an arma::cube, c.f. arma::zeros<template>
Generate a vector, matrix or cube with the elements set to zero
Usage:
vector_type v = zeros<vector_type>( n_elem )
matrix_type X = zeros<matrix_type>( n_rows, n_cols )
matrix_type Y = zeros<matrix_type>( size(X) )
cube_type Q = zeros<cube_type>( n_rows, n_cols, n_slices )
cube_type R = zeros<cube_type>( size(Q) )
Thus, in your case it would be:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
Rcpp::List mcmc(const int iter, const int chains,
const Rcpp::NumericVector data){
arma::cube posteriorC = arma::zeros<arma::cube>(iter, 5, chains);
// --------------------------------- ^^^^^^^^
// Not Shown
Rcpp::List out = Rcpp::List::create(Rcpp::Named("posteriorC") =posteriorC);
return out;
}
Two final notes:
You explicitly state that the code as it stands now will create 4 columns to store 4 variables. However, you explicitly mention that you needed to estimate 5 parameters. You may need to increase this to prevent an out of bounds when saving into the arma::cube slices.
The way the Rcpp::List out is being created isn't quite correct. In general, the best way to create the list is to do: Rcpp::List out = Rcpp::List::create(Rcpp::Named("Blah"), Blah);

a simpler way to get variables from structs within structs

It's been over a year since I last used C, so I'm pretty much back to basics.
I have this code as part of a larger file:
typedef struct
{
float ix;
float iy;
float iz;
} InitialPosition;
typedef struct
{
InitialPosition init;
} Particle;
void particle()
{
Particle p1 =
{
.init = { .ix = 10, .iy = 10, .iz = 10 },
};
glPointSize(10);
glBegin(GL_POINTS);
glVertex3f(p1.init.ix,p1.init.iy,p1.init.iz);
//glVertex3f( 0, 0, 0 );
glEnd();
}
It works/appears correctly with my particle being plotted onto an axis, but it seems like there must be a quicker way to feed the variables from the struct into the glVertex3f method.
On the off-chance it makes any difference I'm using openGL & glut.
Should I also be using pointers? (If so an example of use would be great.) Like I said it has been a while so any help appreciated.
Functions that take three separate parameters require that you break each value out. If you're going to be using these calls a lot, you have two ways to make it more convenient.
1) make a helper function:
void myglVertexParticle(Particle * apoint) { glVertex3f(init->ix, init->iy, init->iz) ; }
myglVertexParticle( & (p1.init)) ;
2) use an expansion macro:
#define PARTICLE3f(uuu) uuu.ix, uuu.iy, uuu.iz
glVertex3f( PARTICLE3f( p1.init)) ;
Most people are probably going to frown on the second choice from a style point of view, and a good optimizing compiler should make the first case run nearly as quickly as the second.

Value passed from one function to another changes... Can't figure out why?

I have a very weird problem that I can't understand.
This is C code:
//below are the values being passed
//long numTreePeriods = 80
//double length = 0.23013698630136986
TTimeLineInfo* tlInfo = GtoTimeLineInfoNew( (long)ceil(numTreePeriods/length), /*ppy*/
0L,
1,
FALSE);
Now here's the signature of the GtoTimeLineInfoNew function called above:
__declspec(dllexport) TTimeLineInfo* GtoTimeLineInfoNew
(long minPPY, /* (I) Min # ppy before switchDate */
TDate switchDate, /* (I) If 0, ignore ppy2; only use minPPY*/
long minPPY2, /* (I) Min # ppy after switchDate */
TBoolean wholeDayTPs);
When I debug my code and step into the function with the values specified above I get:
minPPY = -1636178017
????? What could cause this type of behaviour?
Just to precise the C code is a dll I am wrapping up in C++/CLI. Nevertheless the problem seems independent from that....
I'm not certain; but my guess would be a difference between how parameters are passed to a C function vs. a C++ function. Try:
extern "C" __declspec(dllexport) TTimeLineInfo* GtoTimeLineInfoNew ...
For some reason ceil(numTreePeriods/length) was giving something very weird. So I wrote a ceil function myself to solve this problem...
UPDATE:
Like highlighted in comment by glglgl, the appropriate header was missing, hence ceil was interpreted to return an int which led to funny values...

Resources