Help converting (remaining) MATLAB code to MEX? Removing NANs from matrix, and a sortrows equivalent?
Show older comments
Hi all,
I have a code which merges overlapping intervals that I am transcribing into Mex (for speed purposes).
Intervals are a 2 column matrix, with intervals(:,1) being start times, and intervals(:,2) end times.
The code sorts the intervals, then loops through them, and checks if they overlap with the previous one. It replaces the edges of overlapping intervals with NANs. After the code completes, NANs would then be removed from the matrices, keeping non-overlapping intervals.
Here is the MATLAB code:
function output=mergeIntervals(intervals)
intervals = sortrows(intervals); % This line is still missing from MEX code
for i = 2:size(intervals,1)
if intervals(i,1) <= intervals(i-1,2)
if intervals(i,2) < intervals(i-1,2)
intervals(i,2) = intervals(i-1,2);
end
intervals(i,1) = nan;
intervals(i-1,2) = nan;
end
end
output = reshape(intervals(~isnan(intervals(:))),[],2); % This line is still missing from MEX code
And the equivalent MEX code
// Start code
#include <mex.h>
#include <math.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// Declare variables
double *intervals;
int i, m;
// Allocate values
m = mxGetM(prhs[0]); // Number of rows
plhs[0] = mxCreateNumericMatrix(m, 2, mxDOUBLE_CLASS, mxREAL);
intervals = mxGetPr(plhs[0]);
intervals = mxGetPr(prhs[0]);
// The algorithm
for (i = 1; i < m; ++i)
{
if (intervals[i] <= intervals[i - 1 + m])
{
if (intervals[i + m] < intervals[i - 1 + m])
{
intervals[i + m] = intervals[i - 1 + m];
}
intervals[i] = NAN;
intervals[i - 1 + m] = NAN;
}
}
}
And here is the equivalent MATLAB code:
Now the idea is to remove NANs from the final matrix.
In Matlab notation, the line would be:
For large matrices, if I were to combine MATLAB sorting and nan removal with the MEX code, the MEX code is around ~20 to 30 times faster...
Is there a fast way to sort the rows within MEX code? What about removing NANs? Doing either one of them in MEX should make the code substantially faster...
Thanks
9 Comments
Jan
on 24 Sep 2018
What is "p1"? The same as "intervals"?
poultryNews
on 24 Sep 2018
By the way: You explained, what the algorithm does. But maybe there is a faster method, so better describe, what you want to achieve. Do I understand correctly:
You have a [Nx2] matrix, which contains interval and the value of the first element in each row is smaller (or smaller equal) than the element in the second column? Do the inputs contain NaN values? No you want to "join" all interval, which overlap. The output is a [M x 2] matrix without overlapping intervals.
How large are your inputs? If you call the function 1 million tiems with a 10x2 matrix the fastest solution will differ from a version handling 1e6 x 2 inputs.
poultryNews
on 26 Sep 2018
Edited: poultryNews
on 26 Sep 2018
Bruno Luong
on 26 Sep 2018
Edited: Bruno Luong
on 26 Sep 2018
Not sure how it compares to yours, but might be you should benchmark them before select one before mex conversion.
Bruno Luong
on 26 Sep 2018
Edited: Bruno Luong
on 26 Sep 2018
[0.5 3.1;
4.2 7.0;
7.3 10.5];
I think the interval [0.5,3.1] is incorrect, none of the original intervals do cover (2,2.5)
poultryNews
on 26 Sep 2018
poultryNews
on 27 Sep 2018
Bruno Luong
on 27 Sep 2018
Edited: Bruno Luong
on 27 Sep 2018
If you don't want to bother with sorting, code just the loop with C-mex and let MATLAB takes care of the rest, including sorting (MATLAB sorting is very good).
I usually use qsort when I do MEX programming with MSVC.
Otherwise you can just find the algorithm on the internet and code it yourself, it's not difficult, and I have done it in this FEX, but usually hard to beat factory MATLAB/MS sorting.
Answers (0)
Categories
Find more on Shifting and Sorting Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!