Help calling functions from matlab command line


fleece
06-22-2010, 09:36 AM
This is probably an extremely elementary question, but I'm not a C++ coder, just trying to get the NR functions running from matlab. From the helpful tutorial on matlab and NR, I've successfully gotten the functions to compile, and I have the helloworld example working (I can call it from the matlab command prompt, and it returns the appropriate answer). Now I'm trying to call savgol, but can't figure out the appropriate way to call it from the matlab command prompt. From the way the function is declared, it looks like its expecting a reference to the output array, then 5 integer inputs. But when I try to call it that way, something like
savgol(c,25,12,12,0,2), where I've defined c to be an array of the appropriate length, it trips on the "bad args in savgol". From the little bit of debugging I was able to do, I don't think its assigning the values I intend to np, nl, nr, etc, and thus tripping the error. This is why I think there's a gap in my understanding related to arguments in C++. Can anyone help me out?

William Handler
07-22-2010, 10:59 AM
Hi Fleece

would you be able to post your code. It could be a million things based on what you said, but your code would make it easy to debug.

Will

fleece
07-29-2010, 12:59 PM
thanks, Will. here's the savgol code (copied directly from the download, plus adding the appropriate includes, and changing the name from savgol to mexFunction, which I found I needed to make it compile successfully)

/*savgol.cpp*/

#include "nr3matlab.h"
#include "ludcmp.h"

void mexFunction(VecDoub_O &c, const Int np, const Int nl, const Int nr,
const Int ld, const Int m)
{
Int j,k,imj,ipj,kk,mm;
Doub fac,sum;
if (np < nl+nr+1 || nl < 0 || nr < 0 || ld > m || nl+nr < m)
throw("bad args in savgol");
MatDoub a(m+1,m+1);
VecDoub b(m+1);
for (ipj=0;ipj<=(m << 1);ipj++) {
sum=(ipj ? 0.0 : 1.0);
for (k=1;k<=nr;k++) sum += pow(Doub(k),Doub(ipj));
for (k=1;k<=nl;k++) sum += pow(Doub(-k),Doub(ipj));
mm=MIN(ipj,2*m-ipj);
for (imj = -mm;imj<=mm;imj+=2) a[(ipj+imj)/2][(ipj-imj)/2]=sum;
}
LUdcmp alud(a);
for (j=0;j<m+1;j++) b[j]=0.0;
b[ld]=1.0;
alud.solve(b,b);
for (kk=0;kk<np;kk++) c[kk]=0.0;
for (k = -nl;k<=nr;k++) {
sum=b[0];
fac=1.0;
for (mm=1;mm<=m;mm++) sum += b[mm]*(fac *= k);
kk=(np-k) % np;
c[kk]=sum;
}
}

William Handler
08-03-2010, 09:40 AM
Hi Fleece

you must be using a different version of matlab to the current one, as your mexfunction inputs are not the same as the ones needed for the current release. Which looks like this......

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

Basically, the mexFunction args are the lefthandside and the righthandside of the matlab function call.

[out1 out2] = testmex(in1 in2 in3)

would have nlhs =2, nrhs = 3, and the array plhs would be an array of two pointers to the mxArrays out1 out2 and prhs would be an array of three pointers to in1 in2 in3.

Most of the work in making your code work in matlab is in coding the interface. Generally using the NR code is straightforward from that point.

The hello world example mexfunction uses the same format as mine, so you might want to start from scratch and try and implement your problem with the same interface design.
I am not sure if this is at all helpful, sorry if not.