I am trying to speed up some of my methods and can't figure out, why two of my methods calculate correctly but fail to run several times.
The Setting:
I am getting a (possibly huge) set of vectors (columns) in p
and v
, let's assume for simplicity just 3D unit vectors. For each pair of columns I would like to compute the corresponding q = p*cos(||v||) + v/||v|| * sin(||v||)
. For convenience (and my larger example) I would like to use Eigen
and its MatrixXd
class.
#include "mex.h"
#include "math.h"
#include <stdlib.h>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
const mxArray *IpA, *IvA; //Just names
double *Ip, *Iv, *Oq;
mwSize i,j;
size_t ItemSize,N;
// Inputs
IpA = prhs[0];
IvA = prhs[1];
Ip = mxGetPr(IpA); // Base Points
Iv = mxGetPr(IvA); // Directions
ItemSize = mxGetM(IpA);
N = mxGetN(IpA);
if ( (ItemSize != mxGetM(IvA)) || (N != mxGetN(IvA)) )
mexErrMsgTxt("p and v have to be of same size.");
plhs[0] = mxCreateDoubleMatrix((mwSize)ItemSize,(mwSize)N,mxREAL);
Oq = mxGetPr(plhs[0]);
// Norm directional vectors V
MatrixXd normV(ItemSize,1);
for (i=0; i<N; i++) {
normV(i) = 0;
for (j=0; j<ItemSize; j++) {
normV(i) += Iv[j + ItemSize*i]*Iv[j + ItemSize*i];
}
}
//Compute result
normV = normV.array().sqrt();
for (i=0; i<N; i++) {
for (j=0; j<ItemSize; j++) {
if (normV(i)==0)
Oq[j + ItemSize*i] = 0;
else {
Oq[j + ItemSize*i] = Ip[j + ItemSize*i]*cos(normV(i)) + Iv[j + ItemSize*i]*sin(normV(i))/normV(i);
}
}
}
}
I'm following the tutorial by Pascal Getreuer.
The Problem: Nevertheless, if I am calling this compiled function (Let's name it SnExp
I'm getting the correct result for single vectors or a few ones. If I am using a large number (3x8000
which is not that large) or call the functions a few times (let's take SnExp(repmat([1;0;0],1,1000),repmat([1;0;0],1,1000))
which should return a matrix containing 1000 columns [1.3818;0;0]
.
Matlab just freezes or crashes and I can't figure out why. Can you confirm that crash and help me fix it? That would be awesome.