Mercurial > forge
changeset 5729:49cec4fd294b octave-forge
flag_rows done, single vector, and (u)int8/16 done;
author | schloegl |
---|---|
date | Mon, 08 Jun 2009 11:18:48 +0000 |
parents | e03f9a01e062 |
children | c45fb9ded279 |
files | extra/NaN/src/histo_mex.cpp |
diffstat | 1 files changed, 269 insertions(+), 220 deletions(-) [+] |
line wrap: on
line diff
--- a/extra/NaN/src/histo_mex.cpp Mon Jun 08 07:58:38 2009 +0000 +++ b/extra/NaN/src/histo_mex.cpp Mon Jun 08 11:18:48 2009 +0000 @@ -51,56 +51,116 @@ #endif #endif -inline int uint8cmp(const uint8_t *a, const uint8_t *b) { - return((int)*(uint8_t*)a - (int)*(uint8_t*)b); -} -inline int int8cmp(const int8_t *a, const int8_t *b) { - return((int)*(int8_t*)a - (int)*(int8_t*)b); -} -inline int uint16cmp(const void *a, const void *b) { - return((int)*(uint16_t*)a - (int)*(uint16_t*)b); -} -inline int int16cmp(const void *a, const void *b) { - return((int)*(int16_t*)a - (int)*(int16_t*)b); -} -inline int uint32cmp(const void *a, const void *b) { - return(memcmp(a,b,4)); -} -inline int int32cmp(const void *a, const void *b) { - return((int64_t)*(int32_t*)a - *(int32_t*)b); -} -inline int uint64cmp(const void *a, const void *b) { - return(memcmp(a,b,8)); -} -inline int int64cmp(const void *a, const void *b) { - return(*(int64_t*)a - *(int64_t*)b); -} +struct sort_t { + uint8_t *Table; + size_t Size; + size_t Stride; + size_t N; + mxClassID Type; +} Sort; + +//inline int compare(const sqize_t *a, const size_t *b) { +inline int compare(const void *a, const void *b) { + int z = 0; + size_t i = 0; +// mexPrintf("cmp: %u %u\n",*(size_t*)a,*(size_t*)b); +// mexPrintf("%i: %i %i %i %i %i %i \n",Sort.Type,mxINT32_CLASS,mxUINT32_CLASS,mxINT64_CLASS,mxUINT64_CLASS,mxSINGLE_CLASS,mxDOUBLE_CLASS); + while ((i<Sort.N) && !z) { -inline int float32cmp(const void *a, const void *b) { - return(memcmp(a,b,4)); -} -inline int float64cmp(const void *a, const void *b) { - return(memcmp(a,b,8)); -} -inline int float128cmp(const void *a, const void *b) { - return(memcmp(a,b,16)); + switch (Sort.Type) { + case mxCHAR_CLASS: + z = memcmp(Sort.Table+((*(size_t*)a + Sort.Stride*i)*Sort.Size),Sort.Table+((*(size_t*)b + Sort.Stride*i)*Sort.Size),Sort.Size); + break; + case mxINT32_CLASS: { + int32_t f1,f2; + f1 = ((int32_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((int32_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxUINT32_CLASS: { + uint32_t f1,f2; + f1 = ((uint32_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((uint32_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxINT64_CLASS: { + int64_t f1,f2; + f1 = ((int64_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((int64_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxUINT64_CLASS: { + uint64_t f1,f2; + f1 = ((uint64_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((uint64_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxSINGLE_CLASS: { + float f1,f2; + f1 = ((float*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((float*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxDOUBLE_CLASS: { + double f1,f2; + f1 = ((double*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((double*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxINT16_CLASS: { + int16_t f1,f2; + f1 = ((int16_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((int16_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxUINT16_CLASS: { + uint16_t f1,f2; + f1 = ((uint16_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((uint16_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxINT8_CLASS: { + int8_t f1,f2; + f1 = ((int8_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((int8_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + case mxUINT8_CLASS: { + uint8_t f1,f2; + f1 = ((uint8_t*)Sort.Table)[(*(size_t*)a + Sort.Stride*i)]; + f2 = ((uint8_t*)Sort.Table)[(*(size_t*)b + Sort.Stride*i)]; + if (f1<f2) z = -1; + else if (f1>f2) z = 1; + break; + } + } + i++; + } + return(z); } - -void histo(void *x, size_t sz, size_t stride, size_t n) -{ - if (stride==1) - qsort(x,n,sz,uint32cmp); - -} - void mexFunction(int POutputCount, mxArray* POutput[], int PInputCount, const mxArray *PInputs[]) { - - - const mwSize *SZ; char flag_rows = 0; char done = 0; @@ -143,194 +203,183 @@ mxArray *HIS = mxCreateStructMatrix(1, 1, 3, fnames); mxSetField(HIS,0,"datatype",mxCreateString("HISTOGRAM")); - if (!flag_rows || (SZ[1]==1)) - switch (mxGetClassID(PInputs[0])) { -/* - case mxCHAR_CLASS: { - mxArray *H = mxCreateNumericMatrix(256, SZ[1], mxUINT64_CLASS,mxREAL); - mxArray *X = mxCreateNumericMatrix(256, 1, mxINT8_CLASS,mxREAL); - mxSetField(HIS,0,"H",H); - mxSetField(HIS,0,"X",X); - - char *x; - x = (char*)mxGetData(X); - qsort(x,n,sz,strcpy); - break; + size_t *idx = NULL; + if (flag_rows) { +// if (SZ[1]==1) { + int (*compar)(const void*, const void*); + size_t n; + idx = (size_t*) mxMalloc(SZ[0]*sizeof(size_t)); + for (size_t n=0; n<SZ[0]; n++) { + idx[n]=n; } -*/ - case mxINT8_CLASS: { - mxArray *H = mxCreateNumericMatrix(256, SZ[1], mxUINT64_CLASS,mxREAL); - mxArray *X = mxCreateNumericMatrix(256, 1, mxINT8_CLASS,mxREAL); - mxSetField(HIS,0,"H",H); - mxSetField(HIS,0,"X",X); - - int8_t *x; - x = (int8_t*)mxGetData(X); - for (k=0; k<=255; k++) - x[k]=k-128; + Sort.Type = mxGetClassID(PInputs[0]); + Sort.Table = (uint8_t*) mxGetData(PInputs[0]); + switch (mxGetClassID(PInputs[0])) { + case mxINT8_CLASS: + case mxUINT8_CLASS: + Sort.Size = 1; + break; + case mxINT16_CLASS: + case mxUINT16_CLASS: + Sort.Size = 2; + break; + case mxINT32_CLASS: + case mxUINT32_CLASS: + case mxSINGLE_CLASS: + Sort.Size = 4; + break; + case mxINT64_CLASS: + case mxUINT64_CLASS: + case mxDOUBLE_CLASS: + Sort.Size = 8; + break; + default: + mexErrMsgTxt("unsupported input type"); + } + Sort.N = flag_rows ? SZ[1] : 1; - x = (int8_t*)mxGetData(PInputs[0]); - uint64_t *h = (uint64_t*)mxGetData(H); - for (k=0; k<SZ[0]*SZ[1]; k++) - h[x[k]+128+256*(k/SZ[0])]++; - - done = 1; - break; - } - case mxUINT8_CLASS: { - mxArray *H = mxCreateNumericMatrix(256, SZ[1], mxUINT64_CLASS,mxREAL); - mxArray *X = mxCreateNumericMatrix(256, 1, mxUINT8_CLASS,mxREAL); + qsort(idx,SZ[0],sizeof(*idx),compare); + n = SZ[0] ? 1 : 0; + for (size_t k=1; k<SZ[0]; k++) { + if (compare(idx+k-1,idx+k)) n++; + } + mxArray *H = mxCreateNumericMatrix(n, 1, mxUINT64_CLASS,mxREAL); + mxArray *X = mxCreateNumericMatrix(n, SZ[1], mxGetClassID(PInputs[0]),mxREAL); mxSetField(HIS,0,"H",H); mxSetField(HIS,0,"X",X); - + uint64_t *h = (uint64_t*)mxGetData(H); uint8_t *x = (uint8_t*)mxGetData(X); - for (k=0; k<255; k++) - x[k]=k; - - x = (uint8_t*)mxGetData(PInputs[0]); - uint64_t *h = (uint64_t*)mxGetData(H); - for (k=0; k<SZ[0]*SZ[1]; k++) - h[x[k]+256*(k/SZ[0])]++; - - done = 1; - break; - } - case mxINT16_CLASS: { - mxArray *H = mxCreateNumericMatrix(0x10000, SZ[1], mxUINT64_CLASS,mxREAL); - mxArray *X = mxCreateNumericMatrix(0x10000, 1, mxINT16_CLASS,mxREAL); - mxSetField(HIS,0,"H",H); - mxSetField(HIS,0,"X",X); - - uint64_t *h = (uint64_t*)mxGetData(H); - int16_t *x = (int16_t*)mxGetData(X); - for (k=0; k<0x10000; k++) - x[k]=k-0x8000; - - x = (int16_t*)mxGetData(PInputs[0]); - for (k=0; k<SZ[0]*SZ[1]; k++) - h[x[k]+0x8000+0x10000*(k/SZ[0])]++; - - done = 1; - break; + + for (j=0; j<SZ[1]; j++) { + memcpy(x+j*n*Sort.Size,Sort.Table+(idx[0]+j*Sort.Stride)*Sort.Size,Sort.Size); + } + h[0] = 1; + l = 0; + for (size_t k=1; k<SZ[0]; k++) { + if (compare(&idx[k-1], &idx[k])) { + l++; + for (j=0; j<SZ[1]; j++) { + memcpy(x + (l+j*n)*Sort.Size, Sort.Table+(idx[k] + j*Sort.Stride)*Sort.Size, Sort.Size); + } + } + h[l]++; + } + mxFree(idx); + done = 1; } - case mxUINT16_CLASS: { - mxArray *H = mxCreateNumericMatrix(0x10000, SZ[1], mxUINT64_CLASS,mxREAL); - mxArray *X = mxCreateNumericMatrix(0x10000, 1, mxINT16_CLASS,mxREAL); - mxSetField(HIS,0,"H",H); - mxSetField(HIS,0,"X",X); + else { + switch (mxGetClassID(PInputs[0])) { +/* + case mxCHAR_CLASS: { + mxArray *H = mxCreateNumericMatrix(256, SZ[1], mxUINT64_CLASS,mxREAL); + mxArray *X = mxCreateNumericMatrix(256, 1, mxINT8_CLASS,mxREAL); + mxSetField(HIS,0,"H",H); + mxSetField(HIS,0,"X",X); + + char *x; + x = (char*)mxGetData(X); + qsort(x,n,sz,strcpy); + break; + } +*/ + case mxINT8_CLASS: { + mxArray *H = mxCreateNumericMatrix(256, SZ[1], mxUINT64_CLASS,mxREAL); + mxArray *X = mxCreateNumericMatrix(256, 1, mxINT8_CLASS,mxREAL); + mxSetField(HIS,0,"H",H); + mxSetField(HIS,0,"X",X); + + int8_t *x; + x = (int8_t*)mxGetData(X); + for (k=0; k<=255; k++) + x[k]=k-128; + + x = (int8_t*)mxGetData(PInputs[0]); + uint64_t *h = (uint64_t*)mxGetData(H); + for (k=0; k<SZ[0]*SZ[1]; k++) + h[x[k]+128+256*(k/SZ[0])]++; + + done = 1; + break; + } + + case mxUINT8_CLASS: { + mxArray *H = mxCreateNumericMatrix(256, SZ[1], mxUINT64_CLASS,mxREAL); + mxArray *X = mxCreateNumericMatrix(256, 1, mxUINT8_CLASS,mxREAL); + mxSetField(HIS,0,"H",H); + mxSetField(HIS,0,"X",X); + + uint8_t *x = (uint8_t*)mxGetData(X); + for (k=0; k<255; k++) + x[k]=k; + + x = (uint8_t*)mxGetData(PInputs[0]); + uint64_t *h = (uint64_t*)mxGetData(H); + for (k=0; k<SZ[0]*SZ[1]; k++) + h[x[k]+256*(k/SZ[0])]++; + + done = 1; + break; + } - uint64_t *h = (uint64_t*)mxGetData(H); - int16_t *x = (int16_t*)mxGetData(X); - for (k=0; k<0x10000; k++) - x[k]=k-0x8000; + case mxINT16_CLASS: { + mxArray *H = mxCreateNumericMatrix(0x10000, SZ[1], mxUINT64_CLASS,mxREAL); + mxArray *X = mxCreateNumericMatrix(0x10000, 1, mxINT16_CLASS,mxREAL); + mxSetField(HIS,0,"H",H); + mxSetField(HIS,0,"X",X); + + uint64_t *h = (uint64_t*)mxGetData(H); + int16_t *x = (int16_t*)mxGetData(X); + for (k=0; k<0x10000; k++) + x[k]=k-0x8000; + + x = (int16_t*)mxGetData(PInputs[0]); + for (k=0; k<SZ[0]*SZ[1]; k++) + h[x[k]+0x8000+0x10000*(k/SZ[0])]++; + + done = 1; + break; + } - uint16_t *x16 = (uint16_t*)mxGetData(PInputs[0]); - for (k=0; k<SZ[0]*SZ[1]; k++) - h[x16[k]+0x10000*(k/SZ[0])]++; - done = 1; - break; + case mxUINT16_CLASS: { + mxArray *H = mxCreateNumericMatrix(0x10000, SZ[1], mxUINT64_CLASS,mxREAL); + mxArray *X = mxCreateNumericMatrix(0x10000, 1, mxINT16_CLASS,mxREAL); + mxSetField(HIS,0,"H",H); + mxSetField(HIS,0,"X",X); + + uint64_t *h = (uint64_t*)mxGetData(H); + int16_t *x = (int16_t*)mxGetData(X); + for (k=0; k<0x10000; k++) + x[k]=k-0x8000; + + uint16_t *x16 = (uint16_t*)mxGetData(PInputs[0]); + for (k=0; k<SZ[0]*SZ[1]; k++) + h[x16[k]+0x10000*(k/SZ[0])]++; + done = 1; + break; + } + + default: { + /* FIXME */ + mexErrMsgTxt("multicolumns with int32 or larger not supported!"); + + mxArray *H = mxCreateNumericMatrix(0x10000, SZ[1], mxUINT64_CLASS,mxREAL); + mxArray *X = mxCreateNumericMatrix(0x10000, SZ[1], mxGetClassID(PInputs[0]),mxREAL); + mxSetField(HIS,0,"H",H); + mxSetField(HIS,0,"X",X); + + uint64_t *h = (uint64_t*)mxGetData(H); + int16_t *x = (int16_t*)mxGetData(X); + + for (size_t n=0; n<SZ[1]; n++) { + } + } + } // end switch } - } // end switch - POutput[0] = HIS; - - if (done) return; - - /* FIXME */ - - if (!flag_rows) { - for (size_t n=0; n<SZ[1]; n++) { - - } - } - else + /******* output *******/ + if (done) POutput[0] = HIS; - - if (!done) - switch (mxGetClassID(PInputs[0])) { - case mxINT32_CLASS: { - int32_t *x = (int32_t*)mxGetData(PInputs[0]); - qsort(x,n,sz*4,int32cmp); - /* FIXME */ - break; - } - case mxUINT32_CLASS: { - uint32_t *x = (uint32_t*)mxGetData(PInputs[0]); - qsort(x,n,sz*4,uint32cmp); - /* FIXME */ - break; - } - case mxINT64_CLASS: { - uint64_t *x = (uint64_t*)mxGetData(PInputs[0]); - qsort(x,n,sz*8,int64cmp); - /* FIXME */ - break; - } - case mxUINT64_CLASS: { - uint64_t *x = (uint64_t*)mxGetData(PInputs[0]); - qsort(x,n,sz*8,uint64cmp); - /* FIXME */ - break; - } - case mxSINGLE_CLASS: { - mxArray *H = mxCreateNumericMatrix(0x10000, SZ[1], mxUINT64_CLASS,mxREAL); - mxArray *X = mxCreateNumericMatrix(0x10000, 1, mxSINGLE_CLASS,mxREAL); - mxSetField(HIS,0,"H",H); - mxSetField(HIS,0,"X",X); - - uint64_t *h = (uint64_t*)mxGetData(H); - float *x = (float*)mxGetData(X); - x = (float*)mxGetData(PInputs[0]); - - flag = 0; - for (k=0; (k<SZ[0]) && !flag; k++) { - if (x[k] == ceil(x[k])) - h[(size_t)x[k]+0x8000]++; - else - flag = 1; - } - if (!flag) { - for (k=0; k<0x10000; ) - x[k++]=k-0x8000; - } - else { - qsort(x,n,sz*4,float32cmp); - /* FIXME */ - } - break; - } - case mxDOUBLE_CLASS: { - mxArray *H = mxCreateNumericMatrix(0x18000, SZ[1], mxUINT64_CLASS,mxREAL); - mxArray *X = mxCreateNumericMatrix(0x18000, 1, mxDOUBLE_CLASS,mxREAL); - mxSetField(HIS,0,"H",H); - mxSetField(HIS,0,"X",X); - - uint64_t *h = (uint64_t*)mxGetData(H); - double *x = (double*)mxGetData(X); - x = (double*)mxGetData(PInputs[0]); - flag = 0; - for (k=0; (k<SZ[0]) && !flag; k++) { - if ((x[k] == ceil(x[k])) && (x[k]<0x10000) && (x[k]>-32769)) - h[(int)x[k]+0x8000]++; - else - flag = 1; - } - if (!flag) - for (k=0; k<0x18000; k++) - x[k++] = k-0x8000; - else { - qsort(x, n, sz*8, float64cmp); - - /* FIXME */ - } - break; - } - } // end switch - - - /******* output *******/ - POutput[0] = HIS; - + return; }