From: James Tursa on 5 Jul 2010 03:13 "James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <i0qhih$mb$1(a)fred.mathworks.com>... > "Aristeidis " <aris262(a)hotmail.com> wrote in message <i0qdqo$2no$1(a)fred.mathworks.com>... > > > > Please see below (both X and Y have been predefined outside the loops) and note that in X{i,j}{k,l} there are 2D matrices of equal dimenions, i.e. 4x4, 8x8 etc. > > > > for i = 1: size(X,1) > > for j = 1:size(X,2) > > for k = 1: size(X{i,j},1) > > for l = 1:size(X{i,j},2) > > Y{i,j}(k,l) = max(max(X{i,j}{k,l})); > > end > > end > > end > > end > > Also, what class are the individual X{i,j}{k,l} matrices? double? One of the int classes? > > James Tursa It wasn't difficult to do so I just coded it up for you, assuming double class matrices. If you have a different class the changes should be obvious. Caveat: This has virtually *no* argument checking. To make it robust you would have to add checks to make sure the input is a cell matrix, that the cells are themselves cell matrices, that the underlying matrices are the correct class, etc. etc. // maxmax.c #include "mex.h" void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { register mwSize i, j, k, mn, xy, kmax; mwSize m, n, x, y; mxArray *cell, *mx, *md; register double *pr, *prc; register double maxmax; m = mxGetM(prhs[0]); n = mxGetN(prhs[0]); plhs[0] = mxCreateCellMatrix(m, n); mn = m * n; for( i=0; i<mn; i++ ) { cell = mxGetCell(prhs[0], i); x = mxGetM(cell); y = mxGetN(cell); mx = mxCreateDoubleMatrix(x, y, mxREAL); pr = mxGetPr(mx); xy = x * y; for( j=0; j<xy; j++ ) { md = mxGetCell(cell, j); if( prc = mxGetPr(md) ) { maxmax = *prc; kmax = mxGetNumberOfElements(md); for( k=1; k<kmax; k++ ) { if( prc[k] > maxmax ) maxmax = prc[k]; } pr[j] = maxmax; } } mxSetCell(plhs[0], i, mx); } } You can mex it with this command: mex maxmax.c Using the following to build the original cell matrix just for testing purposes: % cellmake2.m X = cell(100,200); for k1=1:20000 X{k1} = cell(floor(rand*10)+1,floor(rand*10)+1); n = numel(X{k1}); for k2=1:n X{k1}{k2} = rand(floor(rand*10)+1,floor(rand*10)+1); end end I ran the following script cellmax.m based on your code % cellmax.m Y = cell(size(X)); for i = 1: size(X,1) for j = 1:size(X,2) Y{i,j} = zeros(size(X{i,j},1),size(X{i,j},2)); % added this pre-allocation for k = 1: size(X{i,j},1) for l = 1:size(X{i,j},2) Y{i,j}(k,l) = max(max(X{i,j}{k,l})); end end end end Then I ran the mex routine maxmax and compared the results: >> cellmake2 >> whos Name Size Bytes Class X 100x200 183922000 cell array >> tic;cellmax;toc Elapsed time is 6.956374 seconds. >> whos Name Size Bytes Class X 100x200 183922000 cell array Y 100x200 6042816 cell array >> tic;Z=maxmax(X);toc Elapsed time is 0.131055 seconds. >> whos Name Size Bytes Class X 100x200 183922000 cell array Y 100x200 6042816 cell array Z 100x200 6042816 cell array >> isequal(Y,Z) ans = 1 So you can see that approximately 98% of your original m-code was wasted overhead. That being said, there are probably some improvements you could make to your code with cellfun and linear indexing to speed things up quite a bit, but I doubt that whatever was done would match the mex routine in speed. Enjoy ... James Tursa
From: Aristeidis on 5 Jul 2010 06:56 > So you can see that approximately 98% of your original m-code was wasted overhead. That being said, there are probably some improvements you could make to your code with cellfun and linear indexing to speed things up quite a bit, but I doubt that whatever was done would match the mex routine in speed. > > Enjoy ... > > James Tursa I don't know what to say James... I couldn't hope for more help even if I wanted to. Thank you very much for all the help. I will go through and study your assessment and steps. I truly appreciate it and I hope this topic will be helpful to others. I think all of my questions have been answered in this thread. A massive thanks to everyone... Cheers!
From: Rune Allnor on 5 Jul 2010 07:16 On 5 Jul, 12:56, "Aristeidis " <aris...(a)hotmail.com> wrote: > > So you can see that approximately 98% of your original m-code was wasted overhead. That being said, there are probably some improvements you could make to your code with cellfun and linear indexing to speed things up quite a bit, but I doubt that whatever was done would match the mex routine in speed. > > > Enjoy ... > > > James Tursa > > I don't know what to say James... I couldn't hope for more help even if I wanted to. Of course you could. You asked the wrong question. James helped you speed up the wrong solution to whatever it is you attempt to do. > Thank you very much for all the help. I will go through and study your assessment and steps. I truly appreciate it and I hope this topic will be helpful to others. > > I think all of my questions have been answered in this thread. A massive thanks to everyone... Wait with the thanks till you have tested the idea. Don't be surprised if this cuts run-time with less than 50% of what you do now. Constructing the input cell array X will take at least as long (probably several times as long) as the time James' code saves. Do away with the cell array X in the first place. Once you find out how to do *that*, you can hope to see some *real* speeds improvements. Rune
From: Aristeidis on 5 Jul 2010 07:42 > Wait with the thanks till you have tested the idea. > > Don't be surprised if this cuts run-time with less than 50% > of what you do now. Constructing the input cell array X will > take at least as long (probably several times as long) as > the time James' code saves. > > Do away with the cell array X in the first place. Once you find > out how to do *that*, you can hope to see some *real* speeds > improvements. > > Rune Rune, I ve taken your comments on board. I ll have to research on that a little bit. Cell arrays are possibly not ideal as you say, but on the other hand having tried structures I wouldn't say these are ideal either. To my knowledge there isn't anything else in Matlab that can hold multiple matrices of values in such a structured way. I could be wrong? And of course, as I said earlier "i will study and go through" which means understand, read on and test, that is implicit. By the way, my thanks are not intended for an opinion/answer that works, it is my job to find the optimum solution as you correctly point out. My thanks are intended for the time it took everyone here to help. Also, I ve read other people's answers on different topics and answers there havent been as helpful as they have been here, I think.
From: Nicole on 5 Jul 2010 08:16
> Firstly, can anyone confirm that this is indeed the proper procedure to start mex files? > Secondly, I get an error from my VS2010 -> mexFunction.def : error LNK2001: unresolved external symbol mexFunction, as i follow thie above tutorial. My matlab version is 2007b. I would appreciate any help... http://www.mathworks.com/support/compilers/release2007b/ |