Thread Subject: Nested loop in a mex-file

Subject: Nested loop in a mex-file

From: Borys Golik

Date: 24 Sep, 2009 15:35:19

Message: 1 of 5

Hi guys!

I have a grayscale picture and I want to plot pixels intensity for each row like in a oscilloscope so that they are all ovarlapping. I've got it running in Matlab, but I'd like to speed up the loop and so I decided to try to write a MEX-file. But something seems to be wrong in my nested loop and I don't know what it is. Please give me a hint (or a solution ;)) for my problem.
 ________________________________________________________________
My working MATLAB code is:

I = rgb2gray(imread('peppers.png'));
I = double(I);
[imHeight imWidth] = size(I);

dots = zeros(255, imWidth);

for i = 1:imWidth
    for j = 1:imHeight
        val = I(j,i);
     dots(val, i) = dots(val, i) + val;
    end
end

dots = flipud(dots);

dots = uint8(round((dots./max(max(dots)).*255)));
dots = imadjust(dots);
imshow(dots);
colormap('bone');
 ________________________________________________________________

And my MEX-file looks like this:

#include "stdafx.h"
#include "mex.h"
#include "math.h"

int coord(int i, int j, int m)
{
return i * m + j;
}

// The gateway routine
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

// Create a pointer to the input image matrix
double *imageIn = mxGetPr(prhs[0]);

// Get the dimensions of the input image matrix
int m = mxGetM(prhs[0]);
int n = mxGetN(prhs[0]);

// Create the pointer to the output waveform image matrix
plhs[0] = mxCreateDoubleMatrix(255, n, mxREAL);
double *imageOut = mxGetPr(plhs[0]);

        // Nested loop
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
double doubleVal = imageIn[coord(i,j,m)];
int digitalVal = int((doubleVal*255.)+0.5);
imageOut[coord(digitalVal,j,m)] += doubleVal;
}
}
}
________________________________________________________________

Thanks a lot in advance!
Boris

Subject: Nested loop in a mex-file

From: Rune Allnor

Date: 24 Sep, 2009 15:41:02

Message: 2 of 5

On 24 Sep, 17:35, "Borys Golik" <boris.go...@gmx.de> wrote:
> Hi guys!
>
> I have a grayscale picture and I want to plot pixels intensity for each row like in a oscilloscope so that they are all ovarlapping.  I've got it running in Matlab, but I'd like to speed up the loop and so I decided to try to write a MEX-file. But something seems to be wrong in my nested loop and I don't know what it is.

...if *you* don't know what is wrong, how sould anybody else
have a clue? At least describe why you think there is a problem.

Apart from that, you are optimizing the wrong code if your
objective is to animate a figure. The window interaction and
on-screen graphics upates take orders of magnitude more time
than the updates of the data matrix.

Rune

Subject: Nested loop in a mex-file

From: Borys Golik

Date: 24 Sep, 2009 16:03:04

Message: 3 of 5

Ok, I'm able to compile and run the mex-file but the resulting image looks not the same I get from my matlab-code which is exactly what I expect. It doesn't make a lot of sense to try to describe how it looks, but it looks a kind of rotated clockwise by 90? having diagonal periodical structures. If you have a second, just copy and paste my matlab snippet to see what I mean. And if can compile mex-files you'll also be able to see what happens copying c++ code in a .cpp file.

Maybe you're right concerning the speed but I'd like to know what I did wrong in the mex code since it seems to be a pretty simple code.

Boris

> ...if *you* don't know what is wrong, how sould anybody else
> have a clue? At least describe why you think there is a problem.
>
> Apart from that, you are optimizing the wrong code if your
> objective is to animate a figure. The window interaction and
> on-screen graphics upates take orders of magnitude more time
> than the updates of the data matrix.
>
> Rune

Subject: Nested loop in a mex-file

From: Rune Allnor

Date: 24 Sep, 2009 16:43:49

Message: 4 of 5

On 24 Sep, 18:03, "Borys Golik" <boris.go...@gmx.de> wrote:
> Ok, I'm able to compile and run the mex-file but the resulting image looks not the same I get from my matlab-code which is exactly what I expect. It doesn't make a lot of sense to try to describe how it looks, but it looks a kind of rotated clockwise by 90?

Seems to be a memory managment problem, might be as simple as
that you got the dimensions tangled up. Work through the details
of how an MxNxC matrix is laid out in memory.

Rune

Subject: Nested loop in a mex-file

From: James Tursa

Date: 25 Sep, 2009 20:52:02

Message: 5 of 5

To OP:

First I need to chastise you for your nomenclature. In general, when a reviewer such as myself reads code that involves matrices and there are indexes i and j used, I expect i to be used for rows and j to be used for columns. You did the reverse. Second, when there is a function involved that takes a row and a column argument, it is expected that the row is listed first and the column second. You did the reverse. This makes it extremely annoying to read and debug your code. Every time I read a line I have to stop my brain from doing what it naturally wants to do with i and j and force it to think backwards. Same with the function calls. Please, in the future, use i for rows and j for columns and list function arguments in row,column order.

Now that my rant is done, back to the original problem ...

Your use of digitalVal for indexing does not match the m-file version, and your use of coord for imageOut does not use the correct number of rows for that matrix and misuses digitalVal in the call. Here is a mex routine that reproduces these lines of m-code:

m-code:
-----------------
[imHeight imWidth] = size(I);
dots = zeros(255, imWidth);
for i = 1:imWidth
    for j = 1:imHeight
        val = I(j,i);
     dots(val, i) = dots(val, i) + val;
    end
end

mex code:
----------------------
#include "stdafx.h"
#include "mex.h"
#include "math.h"

int coord(int i, int j, int m)
{
return i * m + j;
}

// The gateway routine
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

// Create a pointer to the input image matrix
double *imageIn = mxGetPr(prhs[0]);

// Get the dimensions of the input image matrix
int m = mxGetM(prhs[0]);
int n = mxGetN(prhs[0]);

// Create the pointer to the output waveform image matrix
plhs[0] = mxCreateDoubleMatrix(255, n, mxREAL);
double *imageOut = mxGetPr(plhs[0]);

        // Nested loop
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
double doubleVal = imageIn[coord(i,j,m)];
int digitalVal = ((int) doubleVal) - 1;
imageOut[coord(i,digitalVal,255)] += doubleVal;
}
}
}

Finally, I would like to point out when mex routines are useful for speed improvements and when they are not. If there is a lot of intermediate variable creation within your loop, then a mex routine can often avoid that overhead and give you a speed improvement. Or if there are a lot of array slices used in the loop (where MATLAB has to do a data copy to create the slice), then a mex routine can often access the slice directly without a data copy and run quite a bit faster. Those are the two main sources of speed improvements when converting m-code to C code. I didn't time the above mex code against the m-code, but it doesn't appear to have either of the two speedups that I mentioned to any great degree, so I would not necessarily expect it to run much faster than the m-code.

James Tursa

Tags for this Thread

Everyone's Tags:

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Tag Activity for This Thread
Tag Applied By Date/Time
mex Borys Golik 24 Sep, 2009 11:39:04
image processing Borys Golik 24 Sep, 2009 11:39:04
nested loop Borys Golik 24 Sep, 2009 11:39:04
rssFeed for this Thread

Contact us at files@mathworks.com