From: blaž on
Hello to you all,

i've been struggling for a while with my first mex file. Basically it is a simlpe program with 2 for loops, one along i and one along j. If some condition is satisfied i need to remember the specific i,j pair. So in the end i want to have a [? x 2] matrix. The complete code is written bellow. I am positive that the problem is with mxRealloc function, but i just can't make it work properly.

Any comments on how to make this programm work ??

thank you
blaz

#include <matrix.h>
#include <mex.h>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//declare variables
mxArray *ts, *g;
double *x, *y;
mwSize l1, l2;
mwIndex i, j, jj, k, *indi, *indj, numalloc;
void *tmpi, *tmpj;
const mwSize *dim;

//associate inputs
ts = mxDuplicateArray(prhs[0]);

//figure out dimensions
l1 = mxGetM(prhs[0]); //number of rows
l2 = mxGetN(prhs[0]); //number of columns

//checking whether the input really is a scalar time series
if ((l1 != 1) & (l2 != 1))
mexErrMsgTxt("Input must be a scalar time series");

//set the length of time series to l2
if (l1 < l2){
l2 = l2;
}
else{
l2 = l1;
}

//associate pointers
x = mxGetPr(ts);

//do something
//mexPrintf("The length of time series is %d\n",l2);

k = 0;
numalloc = 1; //allocated memory
indi = mxCalloc(numalloc,sizeof(mwIndex)); //array for indices i
indj = mxCalloc(numalloc,sizeof(mwIndex));

for(i=0;i<l2-1;i++)
{
indi[k] = i+1;
indj[k] = i+2;
k++;
if(k == numalloc){
numalloc *=2;
indi = mxRealloc(indi,numalloc*sizeof(mwIndex));
indj = mxRealloc(indj,numalloc*sizeof(mwIndex));
//indi = (mwIndex*)tmpi;
//indj = (mwIndex*)tmpj;
mxFree(tmpi);
mxFree(tmpj);
}

if(i<l2-2)
{
for(j=i+2;j<l2;j++)
{
jj = i+1;
while ((jj<j) & (x[jj] < (x[j]+(x[i]-x[j])*(j-jj)/(j-i))))
{
jj++;
}
if (jj == j)
{
indi[k] = i+1;
indj[k] = j+1;
k++;
if(k == numalloc){
numalloc *=2;
indi = mxRealloc(indi,numalloc*sizeof(mwIndex));
indj = mxRealloc(indj,numalloc*sizeof(mwIndex));
//mxSetPr(indi,tmpi);
//mxSetPr(indj,tmpj);
mxFree(tmpi);
mxFree(tmpj);
}
}
}
}
}

//associate outputs
g = plhs[0] = mxCreateDoubleMatrix(k,2,mxREAL);
y = mxGetPr(g);
for(i=0;i<k;i++)
{
y[i] = indi[i];
y[k+i] = indj[i];
}

return;
}
From: Jan Simon on
Dear bla&#382;!

> I am positive that the problem is with mxRealloc function, but i just can't make it work properly.

Do not reallocate the memory inside a loop. It is much more efficient to allocate the maximal needed memory at the beginning and reallocate at the end once.

Good luck, Jan
From: bla&#382; on
Hi Jan,

thanks for the answer. Before i forgot to mention, that my matlab gives me ms visual c++ runtime error when i call this mex function, or it says to save the workspace and exit. So yes i will put the allocation of the memory before the loop but i still need to know how to do this since my way is obviously wrong. So how do i alocate the memory and set all the pointers right according to my example

thanks

"Jan Simon" <matlab.THIS_YEAR(a)nMINUSsimon.de> wrote in message <hke4pa$ecf$1(a)fred.mathworks.com>...
> Dear bla&#382;!
>
> > I am positive that the problem is with mxRealloc function, but i just can't make it work properly.
>
> Do not reallocate the memory inside a loop. It is much more efficient to allocate the maximal needed memory at the beginning and reallocate at the end once.
>
> Good luck, Jan
From: Jan Simon on
Dear bla&#382;!

Allocate the memory at once:
numalloc = l2; //allocated memory
indi = mxCalloc(numalloc,sizeof(mwIndex));
indj = mxCalloc(numalloc,sizeof(mwIndex));

Do not free undefined pointers!
> mxFree(tmpi);
> mxFree(tmpj);

Good luck, Jan
From: Rune Allnor on
On 4 Feb, 09:34, "bla&#382; " <blaz.kr...(a)siol.net> wrote:
> Hello to you all,
>
> i've been struggling for a while with my first mex file. Basically it is a simlpe program with 2 for loops, one along i and one along j. If some condition is satisfied i need to remember the specific i,j pair. So in the end i want to have a [? x 2] matrix. The complete code is written bellow. I am positive that the problem is with mxRealloc function, but i just can't make it work properly.

Is this C or C++? If C++, use the std::stack<> container to store
intermediate results, and then allocate the necessary space for
the return variable at the very end, when you know how many
elements will be returned.

Apart from that, *never* base variable names on the single letters
'l' (lowercase 'L'), 'I' (uppercase 'i') or 'O' (uppercase 'o'),
alone or in conjunction with only numbers. At some point you will
inevitably confuse them with the digits 1 or 0. *Only* use those
letters in textual labels, where it is obvious that they are letters
and not numbers.

Depending on the font settings in your code editor, you might not
be able to see the difference between the letters and numbers,
making for bugs that are extremely hard to track down, unless
it is obvious from the context what they are.

Rune