Mercurial > hg > camir-aes2014
diff toolboxes/FullBNT-1.0.7/KPMtools/rectintSparseLoopC.c @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/FullBNT-1.0.7/KPMtools/rectintSparseLoopC.c Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,147 @@ +/* This is based on +http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_external/ch04cr12.shtml + +See rectintSparse.m for the matlab version of this code. + +*/ + +#include <math.h> /* Needed for the ceil() prototype. */ +#include "mex.h" +#include <stdio.h> + +/* If you are using a compiler that equates NaN to be zero, you + * must compile this example using the flag -DNAN_EQUALS_ZERO. + * For example: + * + * mex -DNAN_EQUALS_ZERO fulltosparse.c + * + * This will correctly define the IsNonZero macro for your C + * compiler. + */ + +#if defined(NAN_EQUALS_ZERO) +#define IsNonZero(d) ((d) != 0.0 || mxIsNaN(d)) +#else +#define IsNonZero(d) ((d) != 0.0) +#endif + +#define MAX(x,y) ((x)>(y) ? (x) : (y)) +#define MIN(x,y) ((x)<(y) ? (x) : (y)) + +void mexFunction( + int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] + ) +{ + /* Declare variables. */ + int j,k,m,n,nzmax,*irs,*jcs, *irs2, *jcs2; + double *overlap, *overlap2, tmp, areaA, areaB; + double percent_sparse; + double *leftA, *rightA, *topA, *bottomA; + double *leftB, *rightB, *topB, *bottomB; + double *verbose; + + /* Get the size and pointers to input data. */ + m = MAX(mxGetM(prhs[0]), mxGetN(prhs[0])); + n = MAX(mxGetM(prhs[4]), mxGetN(prhs[4])); + /* printf("A=%d, B=%d\n", m, n); */ + + leftA = mxGetPr(prhs[0]); + rightA = mxGetPr(prhs[1]); + topA = mxGetPr(prhs[2]); + bottomA = mxGetPr(prhs[3]); + + leftB = mxGetPr(prhs[4]); + rightB = mxGetPr(prhs[5]); + topB = mxGetPr(prhs[6]); + bottomB = mxGetPr(prhs[7]); + + verbose = mxGetPr(prhs[8]); + + /* Allocate space for sparse matrix. + * NOTE: Assume at most 20% of the data is sparse. Use ceil + * to cause it to round up. + */ + + percent_sparse = 0.01; + nzmax = (int)ceil((double)m*(double)n*percent_sparse); + + plhs[0] = mxCreateSparse(m,n,nzmax,0); + overlap = mxGetPr(plhs[0]); + irs = mxGetIr(plhs[0]); + jcs = mxGetJc(plhs[0]); + + plhs[1] = mxCreateSparse(m,n,nzmax,0); + overlap2 = mxGetPr(plhs[1]); + irs2 = mxGetIr(plhs[1]); + jcs2 = mxGetJc(plhs[1]); + + + /* Assign nonzeros. */ + k = 0; + for (j = 0; (j < n); j++) { + int i; + jcs[j] = k; + jcs2[j] = k; + for (i = 0; (i < m); i++) { + tmp = (MAX(0, MIN(rightA[i], rightB[j]) - MAX(leftA[i], leftB[j]) )) * + (MAX(0, MIN(topA[i], topB[j]) - MAX(bottomA[i], bottomB[j]) )); + + if (*verbose) { + printf("j=%d,i=%d,tmp=%5.3f\n", j,i,tmp); + } + + if (IsNonZero(tmp)) { + + /* Check to see if non-zero element will fit in + * allocated output array. If not, increase + * percent_sparse by 20%, recalculate nzmax, and augment + * the sparse array. + */ + if (k >= nzmax) { + int oldnzmax = nzmax; + percent_sparse += 0.2; + nzmax = (int)ceil((double)m*(double)n*percent_sparse); + + /* Make sure nzmax increases atleast by 1. */ + if (oldnzmax == nzmax) + nzmax++; + printf("reallocating from %d to %d\n", oldnzmax, nzmax); + + mxSetNzmax(plhs[0], nzmax); + mxSetPr(plhs[0], mxRealloc(overlap, nzmax*sizeof(double))); + mxSetIr(plhs[0], mxRealloc(irs, nzmax*sizeof(int))); + overlap = mxGetPr(plhs[0]); + irs = mxGetIr(plhs[0]); + + mxSetNzmax(plhs[1], nzmax); + mxSetPr(plhs[1], mxRealloc(overlap2, nzmax*sizeof(double))); + mxSetIr(plhs[1], mxRealloc(irs2, nzmax*sizeof(int))); + overlap2 = mxGetPr(plhs[1]); + irs2 = mxGetIr(plhs[1]); + } + + overlap[k] = tmp; + irs[k] = i; + + areaA = (rightA[i]-leftA[i])*(topA[i]-bottomA[i]); + areaB = (rightB[j]-leftB[j])*(topB[j]-bottomB[j]); + overlap2[k] = MIN(tmp/areaA, tmp/areaB); + irs2[k] = i; + + k++; + } /* IsNonZero */ + } /* for i */ + } + jcs[n] = k; + jcs2[n] = k; + +} + + + + + + + +